3

環境 - C#、.net 4.0、VS 2010

こんにちは、Windows 用の単純なシェルの代替品を作成しました。ユーザーがログインすると、シェルが自動的に起動されます。ユーザーがシェルを終了すると、通常の Windows の「explorer.exe」が起動します。

ここで、ユーザーが終了するとき (およびこれを適切にサポートするために)、現在ログインしているユーザーに対して "explorer.exe" が実行されているかどうかを確認できる必要があります。これにより、コードが不必要に再起動して「Windows Explorer」アプリケーション ウィンドウが表示されるのを防ぐことができます。

プロセスが実行されているかどうかを確認する方法の無数の例を見てきました...しかし、現在ログインしているユーザーに対して実行されているかどうかを確認する例はありません。

以下のコードは、「explorer.exe」が既に実行されているかどうかを確認し、実行されていない場合は起動します。しかし、必要がないのに、このコードがテストで陽性になる場合があります。

たとえば、ユーザーの簡易切り替えを使用している場合...別のユーザーがマシンにログインしているため、プロセスの一覧に「explorer.exe」が表示されます。ただし、「explorer.exe」の実行中は、現在ログインしているユーザーに対しては実行されません! そのため、シェルが終了すると、コードのテストは肯定的になり、「explorer.exe」は起動されません。ユーザーには黒い画面が残り、シェルはありません!

では、以下のコードを変更して、現在ログインしているユーザーに対して「explorer.exe」が実行されているかどうかをテストするにはどうすればよいでしょうか?

Process[] Processes = Process.GetProcessesByName("explorer");
if (Processes.Length == 0)
{
   string ExplorerShell = string.Format("{0}\\{1}", Environment.GetEnvironmentVariable("WINDIR"), "explorer.exe");
   System.Diagnostics.Process prcExplorerShell = new System.Diagnostics.Process();
   prcExplorerShell.StartInfo.FileName = ExplorerShell;
   prcExplorerShell.StartInfo.UseShellExecute = true;
   prcExplorerShell.Start();
}
4

1 に答える 1

3

プロセスからSessionIDを取得してから、Processesにクエリを実行し、同じSessionIDを持つExplorerインスタンスを取得できます。たとえば、プログラムの名前が「NewShell」であるとします。

  Process myProc = Process.GetProcesses().FirstOrDefault(pp => pp.ProcessName.StartsWith("NewShell"));
  Process myExplorer = Process.GetProcesses().FirstOrDefault(pp => pp.ProcessName == "explorer" && pp.SessionId == myProc.SessionId);

  if (myExplorer == null)
    StartExplorer()

ところで。ProcessName.StartsWith("NewShell")代わりにを使用するとProcessName == "NewShell"、VSデバッガーでも機能します(vshostをexeに追加します)

于 2012-05-19T16:33:18.057 に答える