Process.StartTime访问被拒绝
我的代码需要确定特定进程已经运行了多长时间。但是它继续失败,并在Process.StartTime
请求上显示拒绝访问错误消息。这是一个使用用户凭据运行的进程(即,不是高特权进程)。显然有一个安全设置或者一个策略设置,或者我需要修改以解决此问题的方法,因为我不相信StartTime属性位于Framework中,以至于它可能在100%的时间内失败。
Google搜索表明,我可以通过将运行查询代码的凭据的用户添加到"性能日志用户"组中来解决此问题。但是,此机器上不存在这样的用户组。
解决方案
回答
基础代码需要能够调用OpenProcess,为此我们可能需要SeDebugPrivilege。
我们正在以与我们自己的进程不同的用户身份运行时,正在执行StartTime请求的进程吗?
回答
好吧,抱歉,这没有用...我不是ASP.NET模拟的专家,我倾向于使用应用程序池,我认为我们不能在W2K上使用过吗?相同的查询,然后以各种用户身份运行该查询?
我不愿意在此处发布大量MS框架代码,但是我们可以使用Reflector或者以下代码:http://www.codeplex.com/NetMassDownloader获取框架相关位的源代码,以便我们可以尝试实现各种位以查看失败之处。
我们可以在不被拒绝访问的情况下获取有关该过程的任何其他信息吗?
回答
我可以枚举该过程(即GetProcessById函数起作用),并且我们还有其他代码可以获取EXE名称和其他信息。
我将尝试测试应用程序。如果无法在短时间内使Cimplementation正常工作,我还将尝试使用WMI获取此信息(这不是关键功能,因此我无法花几天时间)。
回答
.Net 1.1的过程使用性能计数器来获取信息。它们被禁用,或者用户没有管理权限。确保已启用性能计数器,并且用户是管理员,应使代码正常工作。
实际上,"性能计数器用户组"应该足够了。该组默认情况下不存在。因此,我们应该自己创建它。
.Net 2.0的过程不依赖于性能计数器。
参见http://weblogs.asp.net/nunitaddin/archive/2004/11/21/267559.aspx
回答
我读过与我们过去说过的类似的话,拉斯。不幸的是,我在有关机器上的工作受到了一定的限制(换句话说,我不能随意创建用户组:这是一台服务器,而不仅仅是随机的PC)。
感谢回答,威尔和拉斯。不幸的是,他们没有解决我的问题。
最终的解决方案是使用WMI:
using System.Management; String queryString = "select CreationDate from Win32_Process where ProcessId='" + ProcessId + "'"; SelectQuery query = new SelectQuery(queryString); ManagementScope scope = new System.Management.ManagementScope(@"\.\root\CIMV2"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); ManagementObjectCollection processes = searcher.Get(); //... snip ... logic to figure out which of the processes in the collection is the right one goes here DateTime startTime = ManagementDateTimeConverter.ToDateTime(processes[0]["CreationDate"].ToString()); TimeSpan uptime = DateTime.Now.Subtract(startTime);
其中一部分是从Code Project中删除的:
http://www.codeproject.com/KB/system/win32processusingwmi.aspx
还有"嘿,脚本专家!":
http://www.microsoft.com/technet/scriptcenter/resources/qanda/jul05/hey0720.mspx