2

GUIアプリケーションを起動する役割を持つ.NET Windowsサービスを作成しています(ソースは利用できません)。操作はファイア アンド フォーゲットであり、初期コマンド ライン パラメータ以外の通信はありません。

サービスは、特定の Windows アカウントとして実行する必要があります。

問題: サービスが起動するアプリがデスクトップに表示されません。インタラクティブなアプリであるため、そうする必要があります。解決策は何ですか?

注: これはシステムの仕様と設計です。サービス/アプリの通信とセキュリティに関する一般的な懸念は、この特定のケースには当てはまりません。

編集: ローカル システム アカウントとしてログインした場合、GUI 要素は正しく表示されますが、GUI アプリはネットワーク ドライブにアクセスする必要があるため (UNC マッピングを認識できません)、指定されたユーザー アカウントとして実行する必要があります。 「インタラクティブな要素を表示する」設定がないもの。

edit2: OS は Windows 2003 Server で、アップグレードの予定はありません。

4

5 に答える 5

4

残念ながら、これは Vista 以来、より問題になっています... 理由の詳細については、このブログ投稿に投稿されています。

その投稿には、いくつかの潜在的な回避策への参照が含まれています。 これは、MSDN のスレッドで、プロセス全体と、直面する可能性のある潜在的な問題の一部を詳しく説明しています。

ただし、(ユーザーがログインしたときに) ユーザーモード アプリケーションをスタートアップ アプリとして実行するように切り替え、サービスへのすべての通信をそのアプリケーションで処理できるかどうかを確認することを強くお勧めします。特にビスタ、ターミナル サービス、およびその他の状況下では、はるかに信頼性が高くなります。

于 2009-04-30T16:09:26.873 に答える
0

これは、タスク管理サービスでこれを行うために過去に使用したコードであり、対話型セッションで何かを実行する必要がある場合がありました。wibble.exe をアプリに置き換えます。Server 2003 (つまり、NT5) で問題なく動作するはずです。NT6 でインタラクティブ モードを実行しようとはしませんでした (手間がかかりすぎました)。アプリをサービス セッションで実行したままにして、パイプ経由で対話する独自のデバッグ ユーティリティを作成しました。

STARTUPINFO  sui ;
PROCESS_INFORMATION pi;

ZeroMemory (&sui, sizeof(STARTUPINFO));
sui.cb = sizeof (STARTUPINFO);
sui.wShowWindow = pTask->GetWinStartState();
sui.dwFlags     = STARTF_USESHOWWINDOW;
ZeroMemory (&pi,sizeof(pi));

if (InteractiveMode)
{
   HANDLE  hToken = NULL;
   DWORD dwSessionId = GetCurrentUserSession();

   if (dwSessionId != (DWORD)-1)
   {
      if (WTSQueryUserToken (dwSessionId, &hToken))
      {
         sui.lpDesktop = TEXT("winsta0\\default");
         LPVOID  pEnv = NULL;
         dwCreateFlags |= CREATE_NEW_CONSOLE;
         HMODULE hModu = LoadLibrary(TEXT("Userenv.dll"));

         if (hModu)
         {
            if (CreateEnvironmentBlock (&pEnv, hToken, FALSE))
            {
               dwCreateFlags |= CREATE_UNICODE_ENVIRONMENT;    
            }
            else
            {
               pEnv = NULL;
            }
         }

         bCreatedOk = CreateProcessAsUser (hToken,
                                           NULL,
                                           TEXT("wibble.exe"),
                                           NULL,
                                           NULL,
                                           FALSE,
                                           dwCreateFlags,
                                           pEnv,
                                           NULL,
                                           &sui,
                                           &pi);
      }
      else
      {
         // error case
      }
   }
   else
   {
      // remote session? error case.
   }
}

あなたの「指定されたユーザー アカウント」は、ここではコンソール セッションである必要があると思います。そのアカウントがまだログインしていない状態で指定されたアカウントで実行する必要がある場合は、レジストリ ハイブの読み込みなど、まったく新しい世界にいることになります。

于 2016-09-27T14:02:15.273 に答える
0

ターミナル サーバーの役割が有効になっている場合、アプリケーション/サービスは動作すると思いますか? そうであれば、「アプリケーションを起動するサービス」モデルではなく、「サービスをポーリングするアプリケーション」モデルを実行する必要があります。

この理由は、いつでも複数のユーザーがマシンに接続している可能性があり、どれが「コンソール」にあるかを知る方法がないためです。実際、コンソールには誰もいない可能性があります。

于 2009-05-01T05:59:11.590 に答える
0

これは暗闇の中での刺し傷ですが、うまくいけば、解決策への何らかの道筋をたどることができます.

セキュリティは問題ではありませんが、問題になる可能性があります。サービスは、現在ログインしているユーザーとは異なる資格情報セットでアプリを起動しています。ユーザーのマシンへのリモート デスクトップのようなもので、ユーザーが見るアプリを起動します。

テストとして、サービスの資格情報を現在ログインしているユーザーに変更して、何が起こるかを確認してください。

ユーザーがログインしていなくてもサービスが実行されるため、アプリを起動するとどうなりますか? ビジネス ルールまたは機能によって、それが起こらないようになっている可能性がありますが、Windows が何かを行って、それが機能しないようにしている可能性があります。

于 2009-04-30T16:06:30.937 に答える
0

Sysinternals/Microsoft から無料の自動ログオン ユーティリティ http://technet.microsoft.com/en-us/sysinternals/bb963905.aspx を使用アプリケーションを自動ログオン ユーザー プロファイルのスタートアップに配置できます。その後、スクリーンサーバーを数分で起動するように設定し、「再開時にログオン画面を表示する」チェックボックスをオンにします。

于 2009-04-30T18:56:03.680 に答える