2011-03-15 1 views
32

C#を使用してWindowsサービスからEXEプログラムを実行するにはどうすればよいですか?C#を使用してWindowsサービスからEXEプログラムを実行するにはどうすればよいですか?

これは私のコードです:私は、このサービスを実行すると

System.Diagnostics.Process.Start(@"E:\PROJECT XL\INI SQLLOADER\ConsoleApplication2\ConsoleApplication2\ConsoleApplication2\bin\Debug\ConsoleApplication2.exe"); 

、アプリケーションが起動されていません。
私のコードで何が問題になっていますか?

+1

私の知る限り、あなたは例外を取得している書かれたようなコードは何も問題はありませんか? –

+0

このプログラムを実行すると何が起こっているか教えてください。 – NT88

答えて

0

私はあなたが別の場所に.exeをコピーしていると思います。これは私が推測する問題かもしれません。 exeをコピーすると、その依存関係はコピーされません。任意の.NET exeファイルがそうで

アクセスできるように

だから、何であるかをあなたがすることができる、新しい場所にexeファイルをコピーしていない、GACにすべての依存DLLを置きます。環境変数を作成し、C#でexeを呼び出してください。パスは環境変数で定義されているので、exeはC#プログラムでアクセスできます。

アップデート:私は私のC#.NETの私はC#.NETコードから.exeファイルを実行しようとされた3.5のプロジェクトで同じ問題のいくつかの種類を持っていたし、そのexeファイルが別のプロジェクトが、何もなかった以前

私のexeアプリケーションで使用していたそれらのdllメソッドとexe(私は機能のためのいくつかのサポートdllを追加しました)。最後に、そのソリューションを同じソリューションの別のプロジェクトとして作成し、そのプロジェクトの出力をデプロイメントプロジェクトに追加して解決しました。このシナリオによると、私は答えました。もし彼が望むものでなければ、私は非常に残念です。

+1

あなたはEXEが別の場所にコピーされているという印象を与えますか? –

46

これは少なくともWindows Vista以降ではで動作しません。重要な問題は、標準のWindowsアプリケーションではなくWindowsサービス内からこれを実行しようとしていることです。表示されたコードは、Windowsフォーム、WPF、またはコンソールアプリケーションで完全に機能しますが、Windowsサービスではまったく機能しません。

Windowsサービスは、特定のユーザーのコンテキストで実行されていないため、追加のアプリケーションを開始できません。通常のWindowsアプリケーションと異なり、services are now run in an isolated sessionは、ユーザーまたはデスクトップとの対話が禁止されています。これにより、アプリケーションを実行する場所が決まりません。

詳しい情報は、これらの関連の質問に対する答えで提供されています:

あなたの問題を解決する最善のは、おそらく考え出してきたように今のところ、サービスの代わりに標準のWindowsアプリケーションを作成することです。これらは、特定のユーザーによって実行されるように設計されており、そのユーザーのデスクトップに関連付けられています。このようにして、既に示したコードを使用して、いつでも追加のアプリケーションを実行できます。

コンソールアプリケーションでインターフェイスや出力を必要としない別の方法として、ウィンドウを作成しないようにプロセスに指示することもできます。これにより、Windowsがプロセスの作成をブロックするのを防ぐことができます。これは、コンソールウィンドウの作成を要求しなくなるためです。関連するコードはthis answerにあります。

+3

EXEの名前に基づいて、私は彼がコンソールアプリケーションを開始しようとしていると推測して、それと対話するつもりはないと思うので、サービスから実行するのに問題はありません。 – Gabe

+0

@Gabe:コンソールアプリケーションはまだインターフェイスを表示します。デスクトップがなければ、そのインターフェイスはどこに表示されるべきですか? –

+0

あなたの答えをありがとうが、私がバットファイルを呼び出しても問題はありません。 – xoops

1

Windows XPでは、Windowsサービスから.exeを実行することができます。私は過去に自分でそれをやりました。

Windowsサービスのプロパティで[デスクトップとの対話を許可する]オプションを選択したことを確認する必要があります。これが行われないと、実行されません。

Windows 7またはVistaをチェックする必要があります。これらのバージョンではエラーが発生する可能性があるため、これらのバージョンには追加のセキュリティ権限が必要ですが、直接的または間接的に達成できると確信しています。 XPの場合、私は自分でそれをやったと確信しています。

+0

これは、exeが開かれるたびにwin 7を促します。 –

-9

System.Diagnostics.Process.Start( "Exe Name");

+0

それは働いていません.. –

2

まず、 システムアカウントで実行されるWindowsサービスを作成します。このサービスは、現在アクティブなユーザーのセッション内で 対話型プロセスを開始する責任があります。この 新しく作成されたプロセスには、UIが表示され、フル管理 の権限で実行されます。最初のユーザーがコンピュータにログオンすると、このサービスは となり、Session0で実行されます。ただし、 サービスが開始されるプロセスは、現在ログオンしているユーザー のデスクトップで実行されます。このサービスはLoaderServiceと呼ばれます。

次に、winlogon.exeプロセスは、ユーザーログイン とログアウト手順を管理します。 コンピュータにログオンするすべてのユーザーは、固有のセッションIDと、セッションに関連付けられた対応する winlogon.exeプロセスを持つことがわかります。今度は上記の について説明しました.LoaderServiceはシステムアカウントで実行されます。また、 は、コンピュータ上の各winlogon.exeプロセスが、システムアカウント で実行されていることを確認しました。システムアカウントは LoaderServiceとwinlogon.exeプロセスの両方の所有者であるため、LoaderService はwinlogon.exeプロセスのアクセストークン(およびセッションID)をコピーしてからのWin32 API関数CreateProcessAsUserを呼び出して は、ログオンしているユーザーの現在アクティブなセッションに処理します。 コピーされた winlogon.exeプロセスのアクセストークン内にあるセッションIDが0より大きいため、そのトークンを使用して対話型 プロセスを起動できます。

これを試してみてください。 Subverting Vista UAC in Both 32 and 64 bit Architectures

3

私はこの記事を試しましたCode Project、それは私のためにうまくいきます。 私もコードを使用しました。記事はスクリーンショットの説明に優れています。

私は、このシナリオに

を必要な説明を追加していあなたは自分のコンピュータを起動してログオンしようとしていています。ログオンすると、システムによって一意のセッションIDが割り当てられます。 Windows Vistaでは、コンピュータに最初にログオンするユーザーに、OSによってセッションID 1が割り当てられます。次にログオンするユーザーには、セッションID 2が割り当てられます。タスクマネージャの[ユーザー]タブから、ログオンしている各ユーザーに割り当てられているセッションIDを表示できます。 enter image description here

ただし、WindowsサービスはセッションIDが0になっています。このセッションは他のセッションから隔離されています。これは、最終的にWindowsサービスが1または2のようなユーザーセッションで実行されているアプリケーションを呼び出すのを防ぎます。

Windowsサービスからアプリケーションを呼び出すには、winlogon.exeからコントロールをコピーする必要があります下のスクリーンショット。 enter image description here

重要なコード

// obtain the process id of the winlogon process that 
// is running within the currently active session 
Process[] processes = Process.GetProcessesByName("winlogon"); 
foreach (Process p in processes) 
{ 
    if ((uint)p.SessionId == dwSessionId) 
    { 
     winlogonPid = (uint)p.Id; 
    } 
} 

// obtain a handle to the winlogon process 
hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid); 

// obtain a handle to the access token of the winlogon process 
if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken)) 
{ 
    CloseHandle(hProcess); 
    return false; 
} 

// Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser 
// I would prefer to not have to use a security attribute variable and to just 
// simply pass null and inherit (by default) the security attributes 
// of the existing token. However, in C# structures are value types and therefore 
// cannot be assigned the null value. 
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); 
sa.Length = Marshal.SizeOf(sa); 

// copy the access token of the winlogon process; 
// the newly created token will be a primary token 
if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, 
    (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, 
    (int)TOKEN_TYPE.TokenPrimary, ref hUserTokenDup)) 
    { 
     CloseHandle(hProcess); 
     CloseHandle(hPToken); 
     return false; 
    } 

STARTUPINFO si = new STARTUPINFO(); 
si.cb = (int)Marshal.SizeOf(si); 

// interactive window station parameter; basically this indicates 
// that the process created can display a GUI on the desktop 
si.lpDesktop = @"winsta0\default"; 

// flags that specify the priority and creation method of the process 
int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; 

// create a new process in the current User's logon session 
bool result = CreateProcessAsUser(hUserTokenDup, // client's access token 
          null,    // file to execute 
          applicationName, // command line 
          ref sa,   // pointer to process SECURITY_ATTRIBUTES 
          ref sa,   // pointer to thread SECURITY_ATTRIBUTES 
          false,   // handles are not inheritable 
          dwCreationFlags, // creation flags 
          IntPtr.Zero,  // pointer to new environment block 
          null,    // name of current directory 
          ref si,   // pointer to STARTUPINFO structure 
          out procInfo  // receives information about new process 
          ); 
+0

私のために働いた。私はWindowsサービス経由でスキャンを要求している間にスキャナからエラーを表示することができました。ありがとうございました –

+0

場合は、ソリューションの+1。 – Vijayaraghavan

+0

私はすでに回答を+1しました –

関連する問題