.net 是否从x86应用程序获取x64 process mainmodule位置?

.net 是否从x86应用程序获取x64 process mainmodule位置?,.net,vb.net,winforms,process,.net,Vb.net,Winforms,Process,我正在尝试获取操作系统上正在运行的进程的所有文件路径,这些文件路径是从Process.getprocesss()方法获取的,它在x64.NET应用程序下工作得非常好,但如果我尝试从x86.NET应用程序中迭代进程列表,情况会发生变化,因为Process.MainModule.FileName属性抛出Win32异常(以我的本地语言)比如说:一个32位进程无法访问64位进程模块,好吧,我理解这个问题,但我如何解决它呢 引发此异常的代码示例(在x86.NET解决方案下,而不是AnyCPU下): 我看到

我正在尝试获取操作系统上正在运行的进程的所有文件路径,这些文件路径是从
Process.getprocesss()
方法获取的,它在x64.NET应用程序下工作得非常好,但如果我尝试从x86.NET应用程序中迭代进程列表,情况会发生变化,因为
Process.MainModule.FileName
属性抛出Win32异常(以我的本地语言)比如说:
一个32位进程无法访问64位进程模块
,好吧,我理解这个问题,但我如何解决它呢

引发此异常的代码示例(在x86.NET解决方案下,而不是AnyCPU下):


我看到了一种使用WMI查询获取64位进程文件路径的替代方法,但这种方法似乎不是更有效的方法,我正在寻找更好的方法,如果可能的话,可以通过.NET framework类库而不干扰WMI接口。

事实上,您无法做到这一点

原因是: 注意:32位进程无法访问64位进程的模块。如果您试图从32位进程获取有关64位进程的信息,您将获得Win32异常

而且,正如您所看到的,每当“32位进程试图访问64位进程的模块”时,Process.MainModule属性就会抛出Win32异常

声明您应该“捕获异常并继续”

似乎通过Process.main模块可以直接访问该模块,因此32位程序集将无法访问64位模块。 更好的解释


确保您确实需要32位版本的应用程序(如果您没有引用任何32位DLL,那么您应该将程序集编译为“任何CPU”,这将避免问题)。

为每个进程查询WMI将非常缓慢。您应该做的是返回所有类,然后按进程id进行“托管比较”。在下面的示例中,我读取每个类的所有属性,并将每个类映射到其相应的
进程。执行时间:
165.53毫秒
。注意,这包括
Process.getprocesss()
。不,我没有超级计算机

(注意:您需要添加对的引用)

测试

Dim watch As New Stopwatch()

watch.[Start]()

Dim result As New Dictionary(Of Process, Win32Process)
Dim processes As Win32Process() = Win32Process.GetProcesses()

Process.GetProcesses().AsParallel().ForAll(
    Sub(p As Process)
        SyncLock result
            result.Add(p, (From item In processes.AsEnumerable() Where (item.ProcessId.HasValue AndAlso (CUInt(p.Id) = item.ProcessId.Value)) Select item).FirstOrDefault())
        End SyncLock
    End Sub)

watch.[Stop]()

Debug.WriteLine("Time: {0} ms, Win32ProcessCount={1}, ProcessCount={1}", watch.Elapsed.TotalMilliseconds, processes.Length, result.Count)
Debug.WriteLine("**************")
Debug.WriteLine(String.Join(Environment.NewLine, (From pair As KeyValuePair(Of Process, Win32Process) In result Select String.Format("Id={0}, Matched={1}", pair.Key.Id.ToString("X8"), (Not pair.Value Is Nothing)))))
结果

Dim watch As New Stopwatch()

watch.[Start]()

Dim result As New Dictionary(Of Process, Win32Process)
Dim processes As Win32Process() = Win32Process.GetProcesses()

Process.GetProcesses().AsParallel().ForAll(
    Sub(p As Process)
        SyncLock result
            result.Add(p, (From item In processes.AsEnumerable() Where (item.ProcessId.HasValue AndAlso (CUInt(p.Id) = item.ProcessId.Value)) Select item).FirstOrDefault())
        End SyncLock
    End Sub)

watch.[Stop]()

Debug.WriteLine("Time: {0} ms, Win32ProcessCount={1}, ProcessCount={1}", watch.Elapsed.TotalMilliseconds, processes.Length, result.Count)
Debug.WriteLine("**************")
Debug.WriteLine(String.Join(Environment.NewLine, (From pair As KeyValuePair(Of Process, Win32Process) In result Select String.Format("Id={0}, Matched={1}", pair.Key.Id.ToString("X8"), (Not pair.Value Is Nothing)))))
时间:165.53毫秒,Win32ProcessCount=96,ProcessCount=96
*******************Id=00001B1C,Matched=True
Id=000019FC,Matched=True
Id=000006EC,Matched=True
Id=000007B0,Matched=True
Id=00001CC0,Matched=True
Id=000014,Matched=True
Id=00000AC0,Matched=True
Id=0000078C,Matched=True
,Matched=True
Id=00000B7C,Matched=True
Id=00000304,Matched=True
Id=0000079C,Matched=True
Id=00000238,Matched=True
Id=00000F80,Matched=True
Id=00000170,Matched=True
Id=00000234,Matched=True
Id=00001634,Matched=True
Id=00000230,Matched=True
Id=1b000094,Matched=True
Id=00000540,Matched=True
Id=00001254,Matched=True
Id=00001A04,Matched=True
Id=000002EC,Matched=True
Id=00000474,Matched=True
Id=00000910,Matched=True
Id=000004F0,Matched=True
Id=00000114,Matched=True
,Matched=True
Id=0000144C,Matched=True
Id=0000133C,Matched=True
Id=00001384,Matched=True
Id=000007F8,Matched=True
Id=000012BC,Matched=True
Id=00000D58,Matched=True
Id=00000B08,Matched=True
Id=00001F08,Matched=True
Id=00000,匹配=True
Id=00001750,匹配=True
Id=000008B0,匹配=True
Id=0000199C,匹配=True
Id=000001C0,匹配=True
Id=00000970,匹配=True
Id=00000720,匹配=True
Id=0000136C,匹配=True
Id=000001B8,匹配=True
Id=000001B4,匹配=True
Id=000012A0,匹配=True
,Matched=True
Id=0000093C,Matched=True
Id=00001890,Matched=True
Id=000012D0,Matched=True
Id=000003F8,Matched=True
Id=00000330,Matched=True
Id=00000 AE0,Matched=True
Id=000002B4,Matched=True
Id=00000C64,Matched=True
Id=00000574,Matched=True
Id=000001fd4,Matched=True
Id=000018BC,Matched=True
Id=00001A44,Matched=True
Id=00000B94,Matched=True
Id=00000630,Matched=True
Id=000003E0,Matched=True
Id=0000102C,Matched=True
Id=000005C0,Matched=True
Id=00000000,Matched=True
Id=000009D0,Matched=True
,Matched=True
Id=00000218,Matched=True
Id=00000A88,Matched=True
Id=00000B70,Matched=True
Id=000002D4,Matched=True
Id=00000398,Matched=True
Id=0000020C,Matched=True
Id=0000082C,Matched=True
Id=000001298,Matched=True
Id=000009B0,Matched=True
,Matched=True
Id=00000F40,Matched=True
Id=00000758,Matched=True
Id=00001128,Matched=True
Id=000005C8,Matched=True
Id=00001900,Matched=True
Id=00001148,Matched=True
Id=0000120C,Matched=True
Id=0000120C,Matched=True
Id=00000CA8,Matched=True


您能提供重新创建异常的示例代码吗?只需使用WMI,它就可以正常工作。为什么这看起来不是一个有效的方法?获取进程可执行路径的API不在.NET的
进程中。您可以通过使用P/Invoke来解决问题,但这肯定比使用WMI更糟糕。哦,由于悬赏,您无法解决这个问题,但它是重复的-
使用WMI,它工作正常。为什么这看起来不是一种有效的方法?
老实说,您是否执行了一个简单的性能测试
Public Class Win32Process

    Public Property Caption() As String
    Public Property CommandLine() As String
    Public Property CreationClassName() As String
    Public Property CreationDate() As DateTime?
    Public Property CSCreationClassName() As String
    Public Property CSName() As String
    Public Property Description() As String
    Public Property ExecutablePath() As String
    Public Property ExecutionState() As UInt16?
    Public Property Handle() As String
    Public Property HandleCount() As UInt32?
    Public Property InstallDate() As DateTime?
    Public Property KernelModeTime() As UInt64?
    Public Property MaximumWorkingSetSize() As UInt32?
    Public Property MinimumWorkingSetSize() As UInt32?
    Public Property Name() As String
    Public Property OSCreationClassName() As String
    Public Property OSName() As String
    Public Property OtherOperationCount() As UInt64?
    Public Property OtherTransferCount() As UInt64?
    Public Property PageFaults() As UInt32?
    Public Property PageFileUsage() As UInt32?
    Public Property ParentProcessId() As UInt32?
    Public Property PeakPageFileUsage() As UInt32?
    Public Property PeakVirtualSize() As UInt64?
    Public Property PeakWorkingSetSize() As UInt32?
    Public Property Priority() As UInt32?
    Public Property PrivatePageCount() As UInt64?
    Public Property ProcessId() As UInt32?
    Public Property QuotaNonPagedPoolUsage() As UInt32?
    Public Property QuotaPagedPoolUsage() As UInt32?
    Public Property QuotaPeakNonPagedPoolUsage() As UInt32?
    Public Property QuotaPeakPagedPoolUsage() As UInt32?
    Public Property ReadOperationCount() As UInt64?
    Public Property ReadTransferCount() As UInt64?
    Public Property SessionId() As UInt32?
    Public Property Status() As String
    Public Property TerminationDate() As DateTime?
    Public Property ThreadCount() As UInt32?
    Public Property UserModeTime() As UInt64?
    Public Property VirtualSize() As UInt64?
    Public Property WindowsVersion() As String
    Public Property WorkingSetSize() As UInt64?
    Public Property WriteOperationCount() As UInt64?
    Public Property WriteTransferCount() As UInt64?

    Public Shared Function GetProcesses() As Win32Process()
        Using searcher As New ManagementObjectSearcher("select * from Win32_Process")
            Return (
                From
                    item As ManagementObject
                In
                    searcher.[Get]().Cast(Of ManagementObject)()
                Select New Win32Process() With {
                    .Caption = CType(item.Properties("Caption").Value, String),
                    .CommandLine = CType(item.Properties("CommandLine").Value, String),
                    .CreationClassName = CType(item.Properties("CreationClassName").Value, String),
                    .CreationDate = ManagementUtils.ToDateTime(item.Properties("CreationDate").Value),
                    .CSCreationClassName = CType(item.Properties("CSCreationClassName").Value, String),
                    .CSName = CType(item.Properties("CSName").Value, String),
                    .Description = CType(item.Properties("Description").Value, String),
                    .ExecutablePath = CType(item.Properties("ExecutablePath").Value, String),
                    .ExecutionState = CType(item.Properties("ExecutionState").Value, UInt16?),
                    .Handle = CType(item.Properties("Handle").Value, String),
                    .HandleCount = CType(item.Properties("HandleCount").Value, UInt32?),
                    .InstallDate = ManagementUtils.ToDateTime(item.Properties("InstallDate").Value),
                    .KernelModeTime = CType(item.Properties("KernelModeTime").Value, UInt64?),
                    .MaximumWorkingSetSize = CType(item.Properties("MaximumWorkingSetSize").Value, UInt32?),
                    .MinimumWorkingSetSize = CType(item.Properties("MinimumWorkingSetSize").Value, UInt32?),
                    .Name = CType(item.Properties("Name").Value, String),
                    .OSCreationClassName = CType(item.Properties("OSCreationClassName").Value, String),
                    .OSName = CType(item.Properties("OSName").Value, String),
                    .OtherOperationCount = CType(item.Properties("OtherOperationCount").Value, UInt64?),
                    .OtherTransferCount = CType(item.Properties("OtherTransferCount").Value, UInt64?),
                    .PageFaults = CType(item.Properties("PageFaults").Value, UInt32?),
                    .PageFileUsage = CType(item.Properties("PageFileUsage").Value, UInt32?),
                    .ParentProcessId = CType(item.Properties("ParentProcessId").Value, UInt32?),
                    .PeakPageFileUsage = CType(item.Properties("PeakPageFileUsage").Value, UInt32?),
                    .PeakVirtualSize = CType(item.Properties("PeakVirtualSize").Value, UInt64?),
                    .PeakWorkingSetSize = CType(item.Properties("PeakWorkingSetSize").Value, UInt32?),
                    .Priority = CType(item.Properties("Priority").Value, UInt32?),
                    .PrivatePageCount = CType(item.Properties("PrivatePageCount").Value, UInt64?),
                    .ProcessId = CType(item.Properties("ProcessId").Value, UInt32?),
                    .QuotaNonPagedPoolUsage = CType(item.Properties("QuotaNonPagedPoolUsage").Value, UInt32?),
                    .QuotaPagedPoolUsage = CType(item.Properties("QuotaPagedPoolUsage").Value, UInt32?),
                    .QuotaPeakNonPagedPoolUsage = CType(item.Properties("QuotaPeakNonPagedPoolUsage").Value, UInt32?),
                    .QuotaPeakPagedPoolUsage = CType(item.Properties("QuotaPeakPagedPoolUsage").Value, UInt32?),
                    .ReadOperationCount = CType(item.Properties("ReadOperationCount").Value, UInt64?),
                    .ReadTransferCount = CType(item.Properties("ReadTransferCount").Value, UInt64?),
                    .SessionId = CType(item.Properties("SessionId").Value, UInt32?),
                    .Status = CType(item.Properties("Status").Value, String),
                    .TerminationDate = ManagementUtils.ToDateTime(item.Properties("TerminationDate").Value),
                    .ThreadCount = CType(item.Properties("ThreadCount").Value, UInt32?),
                    .UserModeTime = CType(item.Properties("UserModeTime").Value, UInt64?),
                    .VirtualSize = CType(item.Properties("VirtualSize").Value, UInt64?),
                    .WindowsVersion = CType(item.Properties("WindowsVersion").Value, String),
                    .WorkingSetSize = CType(item.Properties("WorkingSetSize").Value, UInt64?),
                    .WriteOperationCount = CType(item.Properties("WriteOperationCount").Value, UInt64?),
                    .WriteTransferCount = CType(item.Properties("WriteTransferCount").Value, UInt64?)
                }
            ).ToArray()
        End Using
    End Function

End Class

Friend Class ManagementUtils

    Friend Shared Function ToDateTime(value As Object) As DateTime?
        If (value Is Nothing) Then
            Return CType(Nothing, DateTime?)
        End If
        Return ManagementDateTimeConverter.ToDateTime(CType(value, String))
    End Function

End Class
Dim watch As New Stopwatch()

watch.[Start]()

Dim result As New Dictionary(Of Process, Win32Process)
Dim processes As Win32Process() = Win32Process.GetProcesses()

Process.GetProcesses().AsParallel().ForAll(
    Sub(p As Process)
        SyncLock result
            result.Add(p, (From item In processes.AsEnumerable() Where (item.ProcessId.HasValue AndAlso (CUInt(p.Id) = item.ProcessId.Value)) Select item).FirstOrDefault())
        End SyncLock
    End Sub)

watch.[Stop]()

Debug.WriteLine("Time: {0} ms, Win32ProcessCount={1}, ProcessCount={1}", watch.Elapsed.TotalMilliseconds, processes.Length, result.Count)
Debug.WriteLine("**************")
Debug.WriteLine(String.Join(Environment.NewLine, (From pair As KeyValuePair(Of Process, Win32Process) In result Select String.Format("Id={0}, Matched={1}", pair.Key.Id.ToString("X8"), (Not pair.Value Is Nothing)))))