現在ログに記録されているユーザーのセッションIDを取得するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/3197138

質問

Windowsサービス内からプロセスを実行しています

ProcessStartInfo processStartInfo = new ....
Process.Start(processStartInfo);

問題は、ローカルシステムアカウントの下でサービスを実行した場合、それは大丈夫ですが、プログラムのウィンドウは表示されません。ユーザー資格情報をサービスプロパティに配置しようとしましたが、「デスクトップとの対話を許可する」チェックボックスが無効になりました。

アプリをサービスから呼び出すアプリを実際に実行する必要があり、アプリのウィンドウを実際に確認する必要があります。

お願い助けて。

upd。さて、過負荷のバージョンのprocess.startユーザー名、パスワード、ドメインを使用するものを使用します。プログラムをデスクトップに引き込みます。しかし、今では1つの資格情報の下でアプリを起動しますが、異なるユーザーのデスクトップでそれを示しています。どうして?

Upd2:アイデアがあります! Sysinternals Suiteのpsexec.exeを使用できます。しかし、問題は、「管理者として」静かにそのことを始める必要があることです。そして、私は方法がわかりません。私は、あなたがすでに管理者の権利を持っているとしても、「管理者として実行する」と手動で言う必要があることを意味し、UACを確認する必要があります。 UACのものをもたらさずに、どれほど静かに何かを走らせるかわかりません。

Upd3:親愛なる主。私はそのことを持っています!ついに。

Ok。最初は、問題は確かにセッション0分離のものでした。そのため、サービスから開始できるミドルアプリを構築する必要があり、そのアプリはRPCを介してアプリケーションを起動してデスクトップに持ち込むと仮定します。ミドルレイヤーアプリを構築する代わりに、PSEXECツールを使用することにしました(とにかく、RPCを通じて必要な方法で正確に機能します)。そして、私がローカルシステムアカウントの下でそのツールを使用しようとしたとき、それは何らかの理由で機能しませんでした。そして、私は気づきました - その理由は、MSがすべてのPSTOOLに入れたEula Popupダイアログであり、ボタンをクリックしてローカルシステムアカウントの下でダイアログを確認することは不可能でした。したがって、解決策は、レジストリHKU.DEFAULT SOFTWARE SysInternals PSEXECでキーを作成することです。

hooray、今はうまくいきます!しかし!次に、プログラムを現在ログに記録しているユーザーの画面に持ち込む必要があります。そのためには、セッションIDが必要になります!

質問は、現在ログに記録されているユーザーのセッションIDを取得するにはどうすればよいですか?そして、まだ誰も記録していない場合はどうなりますか?それはどのようなセッションIDになりますか?

Upd4:それだけです!私はそれを手に入れました!

dllimport( "kernel32.dll"、entrypoint = "wtsgetactiveconsolessessionid")] wubl static extern int wtsgetactiveconsolessessionid();

君たちありがとう!

役に立ちましたか?

解決

1つの解決策は、3番目のプロセスを仲介者として機能させ、RPC/名前パイプを介してアプリを起動するように指示することです。

プロセス:

  • Windowsサービス
  • 仲介アプリケーション
  • 実行するアプリ

Shimは、通信エンドポイント(パイプ、WCFエンドポイントという名前)を作成し、その上に耳を傾けます。先に進むためにメッセージが表示されると、実行するアプリが起動します。

次に、Windowsサービスがアプリを起動したい場合、エンドポイント(Pipe、WCF Endpointという名前)を見つけて開き、アプリを起動するためにメッセージを送信します。その後、仲介アプリケーションはプロセスの立ち上げ事業を処理し、Windowsサービスが持っている制限はありません。

この仲介プロセスをログオンから開始すると、あなたは良いことです。

これは、デスクトップと対話するテストを実行する必要がある場合、Microsoftテストエージェント/コントローラーがどのように機能するかに似ています。

他のヒント

wtsgetactiveconsolessessionId(ターミナルサービスAPIから)を使用して、アクティブコンソールセッションIDを取得できます。 Winxp/win2k3以降にのみ使用できますが、Win2K以前のセッションIDのハードコード0ができるため、問題ありません。これがピンボークの署名です:

[DllImport("Kernel32.dll", SetLastError = true)]
[return:MarshalAs(UnmanagedType.U4)]
public static extern int WTSGetActiveConsoleSessionId ( );

ユーザーセッションでプロセスを開始する限り、私が与えた答えを参照できます ここ. 。基本的に4つのAPIを呼び出すことが含まれます。 wtsgetConsolessessionId、wtsqueryusertoken、duplicatetokenex、createprocessasuser、そしてwinxp/win2k3以上を実行している任意のマシンで動作します。

これは中間プロセスなしで実行できますが、500行以上のコードを行う必要があります。基本的に、ユーザーにログインした現在のプロセスとして2番目のプロセスを起動する必要があります。 Vista/7の場合、このユーザーは独自のWinlogonプロセスを持ち、XPの場合、エクスプローラープロセスがあります。プライマリトークン、環境ブロック、セキュリティ属性、およびその実行プロセスのスレッドセキュリティ属性を取得する必要があります。そのすべての情報を使用してWindows API関数CreateProcessasuserを呼び出し、正しいウィンドウステーションを選択してください(通常は "winsta0 default ")。これはすべて実行可能ですが、2番目のプロセスとIPCの他の提案でより良い時期があるかもしれません。

WindowsXPより新しいものでこれを試している場合、これは機能しません。これは、セッション0分離と呼ばれるVista / Windows 7で導入された新機能のためです。 http://msdn.microsoft.com/en-us/library/bb756986.aspx ユーザーのデスクトップに表示されるサービスによって起動されたアプリを入手することはできません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top