3

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

您好,我已经为 Windows 编写了一个简单的 shell 替换。当用户登录时,shell 会自动启动。当用户退出我的 shell 时,会启动普通的 Windows“explorer.exe”。

现在,当用户退出(并正确支持这一点)时,我需要能够检查当前登录用户是否正在运行“explorer.exe”。这可以防止代码不必要地再次启动它,从而导致“Windows 资源管理器”应用程序窗口。

我已经看到了无数关于如何检查和查看进程是否正在运行的示例......但没有看到它是否正在为当前登录的用户运行。

下面的代码将检查“explorer.exe”是否已经在运行,如果没有,将启动它。但是在某些情况下,此代码在不需要时会测试为阳性!

例如,当使用快速用户切换时......另一个用户登录到机器,结果,“explorer.exe”显示在进程列表中。但是,当“explorer.exe”正在运行时,它并没有为当前登录的用户运行!因此,当我的 shell 退出时,代码测试为正,并且“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"then 它也将在 VS 调试器下工作(它将 vshost 添加到 exe)

于 2012-05-19T16:33:18.057 回答