gpt4 book ai didi

c# - FreeLibrary 在使用 GetModuleFileName(x64 平台)后抛出 AccessViolationException?

转载 作者:太空宇宙 更新时间:2023-11-03 13:01:26 26 4
gpt4 key购买 nike

我完全不知道这是怎么发生的。我正在尝试使用 GetModuleFileName 获取可执行文件(cmd.exe)的实际全名。调试显示 GetModuleFileName 输出了正确的路径,但就在调用 FreeLibrary 时,它抛出了异常 AccessViolationException:

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

代码如下:

[DllImport("kernel32")]
public static extern IntPtr LoadLibrary(string path);
[DllImport("kernel32")]
public static extern int FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll", SetLastError = true)]
[PreserveSig]
public static extern uint GetModuleFileName([In] IntPtr hModule,[Out] StringBuilder lpFilename,[In] [MarshalAs(UnmanagedType.U4)] int nSize);

var hm = LoadLibrary("cmd.exe");
if (hm != IntPtr.Zero) {
var s = new StringBuilder();
GetModuleFileName(hm, s, 255);//at here s contains the correct path
FreeLibrary(hm);//the exception throws at here.
}

通过一些试验,我认识到它只发生在 x64(或 AnyCPU)平台上。如果可执行文件(找到它的全名)是一个 32 位文件,平台应该是 x86 然后它工作正常(虽然我的 Windows 是 64 位但是代码在试图找到 "cmd.exe 时也可以工作" 与 x86 目标平台)。但是,如果可执行文件是 64 位的,平台应该是 x64,但代码将无法运行并抛出我提到的异常。

问题是构建的 x86 平台适用于 32 位文件,但构建的 x64 平台不适用于 64 位文件。所以很奇怪。至少构建的 x86 没有错误(因为它按预期工作),而构建的 x64 看起来像错误。

我想知道这是否是预期行为?您肯定可以使用提供的代码以及我所描述的内容轻松地重现该问题。

谢谢!

最佳答案

您没有在字符串生成器对象中分配空间。因此错误。在调用函数之前设置容量。

var sb = new StringBuilder(260);

然后将sb.Capacity传递给GetModuleFileName

您还应该检查错误。不要忽略返回值。

您不应该使用 LoadLibrary 将可执行文件加载到您的进程中,而只能使用 DLL。只有当可执行文件是您的进程的可执行文件时,才将 LoadLibrary 与可执行文件一起使用才有意义,尽管这毫无意义。

可执行文件不是使用 DLL 搜索顺序定位的。可执行文件的搜索过程取决于它们的启动方式。使用 CreateProcessShellExecuteEx。查阅那里的文档。

关于c# - FreeLibrary 在使用 GetModuleFileName(x64 平台)后抛出 AccessViolationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32154168/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com