【问题标题】:Late binding on CreateProcess with C# returns null value使用 C# 对 CreateProcess 进行后期绑定返回空值
【发布时间】:2015-08-26 18:34:19
【问题描述】:

我正在尝试对 kernel32.dll 中的 CreateProcess 函数使用后期绑定,但是,它返回的值与其他任何函数不同。

这是我用于后期绑定的代码

public abstract class LateBinding
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, BestFitMapping = false, SetLastError = true), SuppressUnmanagedCodeSecurity()]
    private static extern LBHandle LoadLibrary(string fileName);

    [DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity()]
    private static extern IntPtr GetProcAddress(LBHandle hModule, string procname);

    private Delegate Result = default(Delegate);

    public Delegate Call(string library, string method, Type type)
    {
        LBHandle Lib = LoadLibrary(library);
        if (!Lib.IsInvalid && !Lib.IsClosed)
        {
            Result = Marshal.GetDelegateForFunctionPointer(GetProcAddress(Lib, method), type);                
            Lib.Close();
        }
        return Result;
    }
}

[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
public sealed class LBHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool FreeLibrary(IntPtr hModule);

    private LBHandle() : base(true) { }

    protected override bool ReleaseHandle()
    {
        return FreeLibrary(handle);
    }
}

这就是我调用函数的方式

private delegate bool dCreateProcess(string applicationName, string commandLine, IntPtr processAttributes, IntPtr threadAttributes, bool inheritHandles, uint creationFlags, IntPtr environment, string currentDirectory, ref STARTUP_INFORMATION startupInfo, ref PROCESS_INFORMATION processInformation);
dCreateProcess CreateProcess = Call("kernel32.dll", "CreateProcess", typeof(dCreateProcess)) as dCreateProcess;

【问题讨论】:

  • LoadLibrary 返回一个 IntPtr ,它是模块的句柄,不确定您是如何将其解包到该类中的,或者它是否以这种方式工作。您是否尝试过查看运行后的最后一个错误是什么?您已将最后一个错误设置为 true,因此您应该能够检查它。
  • 看看这个:link

标签: c# createprocess late-binding kernel32 argumentnullexception


【解决方案1】:

kernel32 中没有名为CreateProcess 的函数。它有两个版本 CreateProcessA (ANSI) 和 CreateProcessW (Unicode)。您可以在按钮上看到 documentation for CreateProcess on MSDN

这不是 CreateProcess 独有的,几乎每个接受字符串的 Win32 API 函数都会有一个 A 和一个 W 版本。

以下是你想要的:

dCreateProcess CreateProcess = Call("kernel32.dll", "CreateProcessW", typeof(dCreateProcess)) as dCreateProcess;

另见What is the difference between CreateProcess and CreateProcessA?

【讨论】:

  • 在调用完函数之前,您也不应该调用FreeLibraryFreeLibrary 将从您的进程中卸载 DLL。您看不到 kernel32 的问题,因为它已经被加载,但是如果您在调用 FreeLibrary 之后调用用户 Dll 函数,您将崩溃。
  • 看来这一直是问题所在,感谢您向我澄清这一点。
【解决方案2】:

kernel32.dll 实际上并没有导出名称为 CreateProcess 的函数入口点 - 它是 CreateProcessA 或在您的情况下为 CreateProcessW 用于 unicode(宽)参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 2019-12-17
    • 2019-04-03
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多