在 VB.Net 中使用 GetModuleFileNameExW

Using GetModuleFileNameExW in VB.Net

我有以下 C++ 代码:

    DWORD _intLen;
    LPWSTR lpFilename = new wchar_t[200];
    DWORD nSize = 200;
    //get process file path
    _intLen = GetModuleFileNameEx(1000, NULL, lpFilename, nSize);

现在我想在 VB.Net 中使用它:

  Public Declare Function GetModuleFileNameExW Lib "PSAPI.DLL" (ByVal hProcess As Integer, ByVal hModule As Integer, ByRef lpFilename As String, ByVal nSize As Integer) As Integer


    Dim _intLen As Integer
    Dim lpFilename As String
    Dim nSize As Integer
    nSize = 200
    lpFilename = Space(400)

    'get process file path
    _intLen = GetModuleFileNameExW(1000, nothing, lpFilename, nSize)

这会导致以下错误:

有什么想法吗?

补充说明:我已经用字符串生成器测试了代码:

Public Declare Function GetModuleFileNameExW Lib "PSAPI.DLL" (ByVal hProcess As Integer, ByVal hModule As Integer, ByRef lpFilename As StringBuilder, ByVal nSize As Integer) As Integer

        Dim _intLen As Integer
        Dim lpFilename As StringBuilder
        Dim nSize As Integer
        nSize = 200

        lpFilename = New StringBuilder()
        'also tried this
        'lpFilename.append(space(nSize))
        'and this
        'lpFilename = New StringBuilder(nSize)

        _intLen = GetModuleFileNameExW(1000, 0, lpFilename, nSize)

您的 p/invoke 声明(我们看不到)是错误的。您需要将文件名声明为 StringBuilder。那是因为数据从被调用者流向调用者。它是一个输出参数。

来自 pinvoke.net 的 p/invoke 声明是准确的,可以使用:

<DllImport("psapi.dll")> _
Public Shared Function GetModuleFileNameEx(ByVal hProcess As IntPtr, ByVal hModule As IntPtr, <Out()> ByVal lpBaseName As StringBuilder, <[In]()> <MarshalAs(UnmanagedType.U4)> ByVal nSize As Integer) As UInteger
End Function

虽然这是一个毫无意义的练习。托管 Process class 已经满足您的需求。获取表示外部进程的 Process 对象。 MainModule属性获取进程的主模块。然后用FileName属性获取文件名。