33

Win 7/UACは私を夢中にさせています。

C ++アプリケーション内から、Windows 7で昇格が必要な実行可能ファイルを実行する必要があります。これを実行し、完了するのを待ってから続行します。これを行う最も簡単な方法は何ですか?

私は通常、を介してこの種のことをCreateProcess()行いますが、昇格を必要とする実行可能ファイルでは失敗します。

cmd.exe /c ...を使用して実行してみCreateProcessましたが、これは機能しますが、醜いcmdターミナルウィンドウがポップアップします。

昇格できるように読んでいShellExecute()ますが、を使用しているときにexeが終了するのを待つのは簡単ではないようShellExecute()です。仕事のような単純なものはありsystem()ますか?

他のアイデアは大歓迎です!

4

3 に答える 3

47

ShellExecuteExではなく、を使用してくださいShellExecute。この関数は、作成されたプロセスのハンドルを提供します。これを使用してWaitForSingleObject、そのハンドルを呼び出して、そのプロセスが終了するまでブロックできます。CloseHandle最後に、プロセス ハンドルを呼び出して閉じるだけです。

サンプル コード (わかりやすく簡潔にするために、ほとんどのエラー チェックは省略されています):

SHELLEXECUTEINFO shExInfo = {0};
shExInfo.cbSize = sizeof(shExInfo);
shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shExInfo.hwnd = 0;
shExInfo.lpVerb = _T("runas");                // Operation to perform
shExInfo.lpFile = _T("C:\\MyApp.exe");       // Application to start    
shExInfo.lpParameters = "";                  // Additional parameters
shExInfo.lpDirectory = 0;
shExInfo.nShow = SW_SHOW;
shExInfo.hInstApp = 0;  

if (ShellExecuteEx(&shExInfo))
{
    WaitForSingleObject(shExInfo.hProcess, INFINITE);
    CloseHandle(shExInfo.hProcess);
}

に「runas」動詞を指定するとlpVerb、起動しようとしているアプリケーションが UAC によって昇格されます。これは、アプリケーションのマニフェストでアクセス許可レベルを「requireAdministrator」に設定することと同じです。管理者と制限付きユーザーの両方に UAC 昇格が必要です。

ただし、絶対に必要な場合を除き、必要な実行レベルを指定する、起動するアプリケーションにマニフェストを追加する「標準」の方法を優先する必要があることに注意してください。この方法を使用する場合は、単純に「open」を として渡しますlpVerb。サンプル マニフェストを以下に示します。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <dependency>
                <dependentAssembly>
                        <assemblyIdentity
                                type="win32"
                                name="Microsoft.Windows.Common-Controls"
                                version="6.0.0.0"
                                processorArchitecture="X86"
                                publicKeyToken="6595b64144ccf1df"
                                language="*"
                        />
                </dependentAssembly>
        </dependency>
        <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
                <security>
                        <requestedPrivileges>
                                <requestedExecutionLevel 
                                       level="requireAdministrator" 
                                       uiAccess="false"/>
                        </requestedPrivileges>
                </security>
        </trustInfo>
</assembly>

最後に、UAC の昇格を必要とするプロセスの実行をトリガーするアプリケーション内の要素が、それに応じてマークされていることを確認してください。ユーザー インターフェイスでこれをモデル化するのはあなたの仕事です。Windows はそれを処理しません。これは、エントリ ポイントに盾のアイコンを表示することによって行われます。例えば:

        ボタンに表示される UAC シールド                                     メニュー項目に表示される UAC シールド

于 2011-02-04T00:59:35.623 に答える
0

昇格された特権で実行するには、これを起動するプロセスが特権を昇格している必要があります。これには通常、安全なサービスまたはプロセスを起動するために既に実行されているものが必要です。これは Vista からの変更です。プロセスを起動し、起動プロセスから継承された適切なレベルの特権で起動できる権限を (ACL トークンを介して) 持つことに関係しています。マイクロソフトは、昇格されたすべての機能のニーズを処理する昇格されたプロセスを作成し、残りを最小特権のユーザー空間に残すように人々に強く求めてきました。Vista がアルファ版だったときから、これを断続的に行ってきました。面倒ですが、セキュリティ上の理由から Microsoft が推奨する方法です。

ちなみに、Program Files ディレクトリなどの安全な場所からアプリを起動している場合、ShellExec 呼び出しは機能しません。数年前にサービス モデルに移行する前に試してみました。

したがって、プロセスを起動して UAC をバイパスするには、継承するセキュリティ特権を既に持っているプロセスから起動するしかありません。

于 2011-08-07T18:52:27.450 に答える
0

できることは、子プロセス「stdin」のパイプを作成し (入力をそのプロセスにリダイレクトするかのように)、パイプが壊れるのを待つことです。

プロセスはリダイレクトされた入力を実際には受信しないことに注意してください。

たとえば、昇格していないコマンドプロンプトから実行しようとした場合

echo help | diskpart

標高が表示され、コマンド ウィンドウは別のウィンドウを閉じるまで待機します。

于 2011-02-04T00:28:46.423 に答える