C# Windows Vista:无法加载 DLL“x.dll”:对内存位置的访问无效。(DllNotFoundException)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 08:19:11  来源:igfitidea点击:

Windows Vista: Unable to load DLL 'x.dll': Invalid access to memory location. (DllNotFoundException)

提问by Martin Marconcini

I was testing on a customer's box this afternoon which has Windows Vista (He had home, but I am testing on a Business Edition with same results).

我今天下午在一个装有 Windows Vista 的客户盒子上进行测试(他有家,但我在商业版上进行测试,结果相同)。

We make use of a .DLL that gets the Hardware ID of the computer. It's usage is very simple and the sample program I have created works. The Dll is This from AzSdk. In fact, this works perfectly under Windows XP. However, for some strange reason, inside our project (way bigger), we get this exception:

我们使用一个 .DLL 来获取计算机的硬件 ID。它的用法非常简单,我创建的示例程序可以运行。这个 Dll 是来自 AzSdk 的。事实上,这在 Windows XP 下非常有效。然而,出于一些奇怪的原因,在我们的项目中(更大的),我们得到了这个异常:

Exception Type:        System.DllNotFoundException
Exception Message:     Unable to load DLL 'HardwareID.dll': Invalid access to memory location. (Exception from HRESULT: 0x800703E6)
Exception Target Site: GetHardwareID

I don't know what can be causing the problem, since I have full control over the folder. The project is a c#.net Windows Forms application and everything works fine, except the call for the external library.

我不知道是什么导致了问题,因为我可以完全控制文件夹。该项目是 ac#.net Windows 窗体应用程序,一切正常,除了对外部库的调用。

I am declaring it like this: (note: it's nota COM library and it doesn't need to be registered).

我是这样声明的:(注意:它不是COM 库,不需要注册)。

[DllImport("HardwareID.dll")]
public static extern String GetHardwareID(bool HDD,
   bool NIC, bool CPU, bool BIOS, string sRegistrationCode);

And then the calling code is quite simple:

然后调用代码非常简单:

private void button1_Click(object sender, EventArgs e)
{
    textBox1.Text = GetHardwareID(cb_HDD.Checked, 
                                  cb_NIC.Checked, 
                                  cb_CPU.Checked, 
                                  cb_BIOS.Checked, 
                                 "*Registration Code*");
}

When you create a sample application, it works, but inside my projectit doesn't. Under XP works fine. Any ideas about what should I do in Vista to make this work? As I've said, the folder and its sub-folders have Full Control for "Everybody".

当您创建示例应用程序时,它可以工作,但在我的项目中却没有。在 XP 下工作正常。关于在 Vista 中我应该怎么做才能使这项工作有任何想法?正如我所说,该文件夹及其子文件夹对“所有人”具有完全控制权。

UPDATE:I do not have Vista SP 1 installed.

更新:我没有安装 Vista SP 1。

UPDATE 2:I have installed Vista SP1 and now, with UAC disabled, not even the simple sample works!!! :( Damn Vista.

更新 2:我已经安装了 Vista SP1,现在,在禁用 UAC 的情况下,即使是简单的示例也无法运行!!!:(该死的Vista。

采纳答案by Wilka

@Martín

@马丁

The reason you were not getting the UAC prompt is because UAC can only change how a process is started, once the process is running it must stay at the same elevation level. The UAC will prompt will happen if:

您没有收到 UAC 提示的原因是因为 UAC 只能更改进程的启动方式,一旦进程运行,它必须保持在相同的高度级别。如果出现以下情况,UAC 将提示将发生:

  • Vista thinks it's an installer (lots of rules here, the simplest one is if it's called "setup.exe"),
  • If it's flagged as "Run as Administrator" (you can edit this by changing the properties of the shortcut or the exe), or
  • If the exe contains a manifest requesting admin privileges.
  • Vista 认为它是一个安装程序(这里有很多规则,最简单的是如果它被称为“setup.exe”),
  • 如果它被标记为“以管理员身份运行”(您可以通过更改快捷方式或 exe 的属性来编辑它),或者
  • 如果 exe 包含请求管理员权限的清单。

The first two options are workarounds for 'legacy' applications that were around before UAC, the correct way to do it for new applications is to embed a manifest resourceasking for the privileges that you need.

前两个选项是针对在 UAC 之前存在的“遗留”应用程序的解决方法,为新应用程序执行此操作的正确方法是嵌入清单资源,要求您获得所需的权限。

Some program, such as Process Explorerappear to elevate a running process (when you choose "Show details for all process" in the file menu in this case) but what they really do is start a new instance, and it's that new instance that gets elevated - not the one that was originally running. This is the recommend way of doing it if only some parts of your application need elevation (e.g. a special 'admin options' dialog).

某些程序,例如Process Explorer似乎提升了正在运行的进程(在这种情况下,当您在文件菜单中选择“显示所有进程的详细信息”时),但它们真正做的是启动一个新实例,并且是该新实例获得提升 - 不是最初运行的那个。如果只有应用程序的某些部分需要提升(例如特殊的“管理选项”对话框),这是推荐的方法。

回答by Dale Ragan

Is the machine you have the code deployed on a 64-bit machine? You could also be running into a DEPissue.

您将代码部署在 64 位机器上的机器吗?您也可能遇到DEP问题。

Edit

编辑

This is a 1st gen Macbook Pro with a 1st gen Core Duo 2 Intel processor. Far from 64 bits.

这是第一代 Macbook Pro,配备第一代 Core Duo 2 Intel 处理器。远非 64 位。

I mentioned 64 bit, because at low levels structs from 32 bit to 64 bit do not get properly handled. Since the machines aren't 64bit, then more than likely disabling DEP would be a good logical next step. Vista did get more secure than XP SP2.

我提到了 64 位,因为在低级别从 32 位到 64 位的结构没有得到正确处理。由于机器不是 64 位,因此很有可能禁用 DEP 将是一个很好的合乎逻辑的下一步。Vista 确实比 XP SP2 更安全。

Well, I've just turned DEP globally off to no avail. Same error.

好吧,我刚刚在全球范围内关闭了 DEP,但无济于事。同样的错误。

Well, I also read that people were getting this error after updating a machine to Vista SP1. Do these Vista installs have SP1 on them?

好吧,我还读到人们在将机器更新到 Vista SP1 后收到此错误。这些 Vista 安装是否带有 SP1?

Turns out to be something completely different. Just for the sake of testing, I've disabled de UAC (note: I was not getting any prompt).

原来是完全不同的东西。只是为了测试,我禁用了 de UAC(注意:我没有收到任何提示)。

Great, I was actually going to suggest that, but I figured you probably tried it already.

太好了,我实际上打算建议这样做,但我想你可能已经尝试过了。

回答by Curt Hagenlocher

Have you made a support request to the vendor? Perhaps there's something about the MacBook Pro hardware that prevents the product from working.

您是否向供应商提出了支持请求?或许 MacBook Pro 硬件的某些方面阻止了该产品的工作。

回答by imaginaryboy

Given that the exception is a DllNotFoundException, you might want to try checking the HardwareID.dll with Dependency WalkerBEFORE installing any dev tools on the Vista install to see if there is in fact a dependency missing.

鉴于异常是 DllNotFoundException,您可能想在 Vista 安装上安装任何开发工具之前尝试使用Dependency Walker检查 HardwareID.dll,以查看是否确实缺少依赖项。

回答by Will Dean

Unable to load DLL 'HardwareID.dll': Invalid access to memory location. (Exception from HRESULT: 0x800703E6)

无法加载 DLL 'HardwareID.dll':对内存位置的访问无效。(来自 HRESULT 的异常:0x800703E6)

The name of DllNotFoundException is confusing you - this isn't a problem with finding or loading the DLL file, the problem is that when the DLL is loaded, it does an illegal memory access which causes the loading process to fail.

DllNotFoundException 的名称让您感到困惑 - 这不是查找或加载 DLL 文件的问题,问题在于加载 DLL 时,它进行了非法内存访问,导致加载过程失败。

Like another poster here, I think this is a DEP problem, and that your UAC, etc, changes have finally allowed you to disable DEP for this application.

就像这里的另一张海报一样,我认为这是一个 DEP 问题,并且您的 UAC 等更改最终允许您为此应用程序禁用 DEP。

回答by imaginaryboy

In addition to allowing full control to "Everyone" does the location also allow processes with a medium integrity level to write?

How do I check that ? I am new to Vista, I don't like it too much, it's too slow inside a VM for daily work and for VStudio usage inside a Virtual Machine, it doesn't bring anything new.

除了允许完全控制“每个人”之外,该位置还允许具有中等完整性级别的进程写入吗?

我如何检查?我是 Vista 的新手,我不太喜欢它,它在 VM 中对于日常工作和虚拟机中的 VStudio 使用来说太慢了,它没有带来任何新的东西。

From a command prompt to you can execute:

从命令提示符可以执行:

icacls C:\Folder

If you see a line such as "Mandatory Label\High Mandatory Level" then the folder is only accessible to a high integrity process. If there is no such line then medium integrity processes can access it provided there are no other ACLs denying access (based on user for example).

如果您看到诸如“Mandatory Label\High Mandatory Level”之类的行,则该文件夹只能由高完整性进程访问。如果没有这样的行,那么只要没有其他 ACL 拒绝访问(例如基于用户),中等完整性进程就可以访问它。

EDIT: Forgot to mention you can use the /setintegritylevel switch to actually change the required integrity level for accessing the object.

编辑:忘记提及您可以使用 /setintegritylevel 开关来实际更改访问对象所需的完整性级别。