如何从用户进程等待系统进程?

时间:2014-10-15 09:39:19

标签: c# .net windows service ipc

我有.net Windows服务作为本地系统运行。我有另一个.net进程需要等待服务终止。该进程不知道服务名称,因此无法查询服务控制管理器。它确实知道服务进程Id。我可以修改Windows服务和其他进程的源。

当我这样做时:

process = Process.GetProcessById(processId);
process.WaitForExit();

来自另一个过程,我得到了:

System.ComponentModel.Win32Exception: Access is denied

Stack trace: 
  at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
  at System.Diagnostics.Process.WaitForExit(Int32 milliseconds)

GetProcessHandle调用OpenProcess。显然,目标进程应该允许SYNCHRONIZE bit以上工作,理论上可以通过SetSecurityInfo从Windows服务设置。然而,似乎没有一种简单的方法可以在.NET中执行此操作,而不是调用几个pinvoke来提升,启用权限并最终更改安全性。

我是否忽略了从用户进程等待另一个(系统)进程的简单方法?

2 个答案:

答案 0 :(得分:0)

尝试使用相同的用户帐户启动服务和程序,或使用内置管理员帐户运行程序(Windows Vista及之后)。

如果仍然抛出异常,请尝试设置计算机的DEP(数据执行保护)设置。

<强>更新 也许你可以使用这个愚蠢的代码..获取服务名称很麻烦,因为它可能与Process.Name不同。

static ServiceController GetServiceControllerByPId(int processId)
{

    string serviceName = "";

    string qry = "SELECT NAME FROM WIN32_SERVICE WHERE PROCESSID = " + processId.ToString();
    System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher(qry);
    System.Management.ManagementObjectCollection mngntObjs = searcher.Get();

    foreach (System.Management.ManagementObject mngntObj in mngntObjs)
    {
        serviceName = (string)mngntObj["NAME"];
    }
    if (serviceName == "")
    {
        return null;
    }

    return System.ServiceProcess.ServiceController.GetServices().FirstOrDefault(x => x.ServiceName == serviceName);
}

调用此函数,并监视ServiceController.Status

答案 1 :(得分:0)

如果您知道服务进程ID,为什么不能获取服务名称并从流程检查服务状态如下?

Process process = Process.GetProcessById(1);
ServiceController windowsService = ServiceController.GetServices().FirstOrDefault(x => x.ServiceName == process.ProcessName);

//Wait until the windows service stops running
while (windowsService.Status == ServiceControllerStatus.Running)
{
   Thread.Sleep(1000);
}