Marshal.GetLastWin32Error() 没有 return 错误

Marshal.GetLastWin32Error() does not return the error

看不懂哪里错了

我正在尝试调用 CreateProcess,但未成功。

这是调用 CreateProcess winapi 函数的代码:

$param = [CodeDom.Compiler.CompilerParameters]::new()
$param.CompilerOptions = "/unsafe"
Add-Type -CompilerParameters $param -TypeDefinition '
using System.Runtime.InteropServices;
using System;

public class Win32{
    [StructLayout(LayoutKind.Sequential)]
    public struct PROCESS_INFORMATION{
        public IntPtr hProcess;
        public IntPtr hThread;
        public int dwProcessId;
        public int dwThreadId;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_ATTRIBUTES{
        public int ln;
        public unsafe byte* lpSecurityDescriptor;
        public int bInheritHandle;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct STARTUPINFO{
        public Int32 cb;
        public string lpReserved;
        public string lpDesktop;
        public string lpTitle;
        public Int32 dwX;
        public Int32 dwY;
        public Int32 dwXSize;
        public Int32 dwYSize;
        public Int32 dwXCountChars;
        public Int32 dwYCountChars;
        public Int32 dwFillAttribute;
        public Int32 dwFlags;
        public Int16 wShowWindow;
        public Int16 cbReserved2;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;
    }

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern bool CreateProcess(
        string lpApplicationName,
        string lpCommandLine,
        ref SECURITY_ATTRIBUTES lpProcessAttributes,
        ref SECURITY_ATTRIBUTES lpThreadAttributes,
        bool bInheritHandles,
        uint dwCreationFlags,
        IntPtr lpEnvironment,
        string lpCurrentDirectory,
        ref STARTUPINFO lpStartupInfo,
        ref PROCESS_INFORMATION lpProcessInformation
    );
}'

$path = "C:\Windows\System32\notepad.exe" 
$lpCurrentDirectory = ""
$CommandLine = ""
$lpEnvironment  = [IntPtr]::Zero
$PRIORITY_CLASS = [UInt32]0x0020
$sInfo    = [win32+STARTUPINFO]::new()
$pInfo    = [win32+PROCESS_INFORMATION]::new()
$pSec     = [win32+SECURITY_ATTRIBUTES]::new()
$tSec     = [win32+SECURITY_ATTRIBUTES]::new()
$sInfo.cb = [Runtime.InteropServices.Marshal]::SizeOf($sInfo)
$pSec.ln  = [Runtime.InteropServices.Marshal]::SizeOf($pSec)
$tSec.ln  = [Runtime.InteropServices.Marshal]::SizeOf($tSec)

$result = [Win32]::CreateProcess(
    $path,
    $CommandLine,
    [ref]$pSec,
    [ref]$tSec,
    $false,
    $PRIORITY_CLASS,
    $lpEnvironment,
    $lpCurrentDirectory,
    [ref]$sInfo,
    [ref]$pInfo
)

if(!$result){
    "Error"
}

$errorCode = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
if($errorCode -eq 0){
    "The operation completed successfully"
}
else{
    "Error code: $errorCode"
}

输出:

Error

The operation completed successfully

为什么记事本没有启动?

GetLastWin32Error() returns 0,我不知道我的错误在哪里。

你得到了错误的错误,因为这个代码

if(!$result){
    "Error"
}

在调用 CreateProcessGetLastWin32Error 之间覆盖错误。删除此代码,您将获得相关的错误代码 123 (ERROR_INVALID_NAME)

GetLastWin32Error 必须始终在您想要获得 return 错误的调用之后立即使用。