Windows Vista:无法加载 DLL“x.dll”:对内存位置的访问无效。 (DllNotFound异常)
今天下午我在客户的机器上进行了测试,该机器装有 Windows Vista(他在家,但我在商业版上进行测试,结果相同)。
我们使用 .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
我不知道是什么导致了问题,因为我完全控制了该文件夹。 该项目是 ac#.net Windows 窗体应用程序,除了对外部库的调用之外,一切正常。
我这样声明它:(注意:它不是 COM 库,并且不需要注册)。
[DllImport("HardwareID.dll")]
public static extern String GetHardwareID(bool HDD,
bool NIC, bool CPU, bool BIOS, string sRegistrationCode);
然后调用代码非常简单:
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*");
}
当您创建示例应用程序时,它可以工作,但在我的项目中却不能。 XP下工作正常。 关于我应该在 Vista 中做什么才能使其工作有什么想法吗? 正如我所说,该文件夹及其子文件夹对“所有人”具有完全控制权。
更新:我没有安装 Vista SP 1。
更新2:我已经安装了Vista SP1,现在,在禁用UAC的情况下,甚至连简单的示例都不起作用! :( 该死的维斯塔。
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).
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:
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.
I am declaring it like this: (note: it's not a COM library and it doesn't need to be registered).
[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".
UPDATE: I do not have Vista SP 1 installed.
UPDATE 2: I have installed Vista SP1 and now, with UAC disabled, not even the simple sample works!!! :( Damn Vista.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
DllNotFoundException 的名称让您感到困惑 - 这不是查找或加载 DLL 文件的问题,问题是加载 DLL 时,它会执行非法内存访问,从而导致加载过程失败。
就像这里的另一张海报一样,我认为这是一个 DEP 问题,并且您的 UAC 等更改最终允许您为此应用程序禁用 DEP。
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.
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.
@马丁
您没有收到 UAC 提示的原因是 UAC 只能更改进程启动的方式,一旦进程运行,它必须保持在相同的高度级别。 如果出现以下情况,则会出现 UAC 提示:
前两个选项是 UAC 之前的“旧”应用程序的解决方法,对于新应用程序执行此操作的正确方法是 嵌入清单资源,请求您需要的权限。
某些程序(例如Process Explorer)似乎会提升正在运行的进程(在这种情况下,当您在文件菜单中选择“显示所有进程的详细信息”时),但他们真正做的是启动一个新实例,并且是该新实例被提升 - 而不是最初运行的实例。 如果只有应用程序的某些部分需要提升(例如特殊的“管理选项”对话框),这是推荐的方法。
@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:
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 resource asking for the privileges that you need.
Some program, such as Process Explorer appear 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).
您部署代码的机器是64位机器吗? 您还可能遇到 DEP 问题。
编辑
我提到了 64 位,因为在低级别,从 32 位到 64 位的结构无法得到正确处理。 由于计算机不是 64 位,因此下一步很可能禁用 DEP。 Vista 确实比 XP SP2 更安全。
嗯,我还了解到人们在将计算机更新到 Vista SP1 后遇到此错误。 这些 Vista 安装有 SP1 吗?
太好了,我本来想建议的,但我想你可能已经尝试过了。
Is the machine you have the code deployed on a 64-bit machine? You could also be running into a DEP issue.
Edit
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.
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?
Great, I was actually going to suggest that, but I figured you probably tried it already.
您是否向供应商提出过支持请求? 也许 MacBook Pro 硬件存在某些问题,导致该产品无法正常工作。
Have you made a support request to the vendor? Perhaps there's something about the MacBook Pro hardware that prevents the product from working.
鉴于异常是 DllNotFoundException,您可能需要在安装之前尝试使用 Dependency Walker 检查 HardwareID.dll Vista 安装上的任何开发工具都可以查看是否确实缺少依赖项。
Given that the exception is a DllNotFoundException, you might want to try checking the HardwareID.dll with Dependency Walker BEFORE installing any dev tools on the Vista install to see if there is in fact a dependency missing.
从命令提示符到您可以执行:
如果您看到诸如“Mandatory Label\High Mandatory Level”之类的行,则该文件夹只能由高完整性进程访问。 如果没有这样的行,那么只要没有其他 ACL 拒绝访问(例如基于用户),中等完整性进程就可以访问它。
编辑:忘记提及您可以使用 /setintegritylevel 开关来实际更改访问对象所需的完整性级别。
From a command prompt to you can execute:
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).
EDIT: Forgot to mention you can use the /setintegritylevel switch to actually change the required integrity level for accessing the object.