C# 如何从用户进程等待系统进程?
我有一个.net Windows服务作为本地系统运行。我有另一个.net进程需要等待服务终止。该进程不知道服务名称,因此无法查询服务控制管理器。它确实知道服务进程Id。我可以修改windows服务和其他进程的源 当我这样做时: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
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吗?