Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从用户进程等待系统进程?_C#_.net_Windows_Service_Ipc - Fatal编程技术网

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

C# 如何从用户进程等待系统进程?,c#,.net,windows,service,ipc,C#,.net,Windows,Service,Ipc,我有一个.net Windows服务作为本地系统运行。我有另一个.net进程需要等待服务终止。该进程不知道服务名称,因此无法查询服务控制管理器。它确实知道服务进程Id。我可以修改windows服务和其他进程的源 当我这样做时: process = Process.GetProcessById(processId); process.WaitForExit(); 从另一个过程中,我得到: System.ComponentModel.Win32Exception: Access is denied

我有一个.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调用。显然,目标进程应该允许上述工作,理论上可以通过Windows服务设置。然而,除了调用几个Pinvoke来提升、启用特权并最终更改安全性之外,在.NET中似乎没有一种简单的方法来实现这一点


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

尝试使用相同的用户帐户启动服务和程序,或使用内置管理员帐户运行程序(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

如果您知道服务进程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);
}

您的进程是32位的,服务是64位的吗?IIRC 32位进程可以查询64位进程的内容有一些限制。@SriramSakthivel都是在目标设置为“Any”的情况下编译的,目标设置为行抛出
Win32Exception
。它是
GetProcessById
WaitForExit
?WaitForExit。在.net内部,它调用GetProcessHandle并将同步访问掩码传递给它。这将导致我们看到的“访问被拒绝”。另一件事是您可以尝试订阅Process.Exited事件。。不幸的是,这不是一个选择。服务需要作为本地系统运行,进程需要在当前用户帐户下运行。但是感谢您的建议。服务名称可能与流程名称不同。您可以P/调用QueryServiceStatusEx来获取每个服务的流程ID吗?