解決策は、ニーズによって異なり、非常に複雑になる可能性があります (Windows Vista のおかげです)。これはおそらくあなたのニーズを超えているでしょうが、これは検索でこのページを見つけた他の人を助けるでしょう.
- GUI でプロセスを実行する必要がなく、昇格も必要ない場合
- 実行したいユーザーがすでにセッションにログインしている場合
- GUI でプロセスを実行する必要があり、ユーザーがログインしている場合とログインしていない場合があります。
- 昇格を使用してプロセスを実行する必要がある場合
1 について:
Windows Vista には、セッション 0 分離と呼ばれるものが存在します。すべてのサービスはセッション 0 として実行され、セッション 0 で GUI を使用することは想定されていません。最初にログオンしたユーザーはセッション 1 にログインします。Windows の以前のバージョン (Vista より前) では、最初にログオンしたユーザーもセッション 1 で完全に実行されました。セッション 0。
同じセッションで、異なるユーザー名を使用していくつかの異なるプロセスを実行できます。セッション 0 の分離に関する優れたドキュメントは、こちら にあります。
オプション 1) を扱っているため、GUI は必要ありません。したがって、セッション 0 でプロセスを開始できます。
次のような呼び出しシーケンスが必要になります: LogonUser、ExpandEnvironmentStringsForUser、GetLogonSID、LoadUserProfile、CreateEnvironmentBlock、CreateProcessAsUser。
このサンプル コードは、任意の検索エンジンまたはGoogle コード検索で見つけることができます。
2 について: プロセスを実行するユーザーが既にログインしている場合は、WTSEnumerateSessions と WTSQuerySessionInformation を使用してセッション ID を取得し、次に WTSQueryUserToken を使用してユーザー トークンを取得します。そこから、CreateProcessAsUser Win32 API でユーザー トークンを使用できます。
ユーザーとしてログインする必要も、ユーザーのユーザー名/パスワードを知る必要もないため、これは優れた方法です。これは、ローカル システム アカウントとして実行しているサービスを介してのみ可能だと思います。
WTSGetActiveConsoleSessionId を介して現在のセッションを取得できます。
3 について:
#1 と同じ手順に従いますが、さらに STARTUPINFO の lpDesktop フィールドを使用します。これを winsta0\Default に設定します。また、OpenDesktop Win32 API の使用を試みる必要があります。これが失敗した場合は、CreateDesktop を実行できます。ステーション ハンドルとデスクトップ ハンドルを使用する前に、SE_WINDOW_OBJECT と GROUP_SECURITY_INFORMATION | を使用してそれぞれに SetSecurityInfo を使用する必要があります。DACL_SECURITY_INFORMATION。
問題のユーザーが後でログインしようとすると、実行中のプロセスが実際に表示されます。
4 について:
これも実行できますが、昇格したプロセスを既に実行している必要があります。ローカル システム アカウントとして実行されているサービスは、管理者特権で実行されます。また、開始したい Authenticode 署名付きプロセスを使用することによってのみ、それを機能させることができました。開始するプロセスには、requestedExecutionLevel level="requireAdministrator" で関連付けられたマニフェスト ファイルも必要です。
その他の注意事項:
- SetTokenInformation と TokenSessionId を介してトークンのセッションを設定できます
- すでに実行中のプロセスのセッション ID は変更できません。
- Vista が考慮されていなければ、このプロセス全体は大幅に単純化されます。