Delphi 程序 & Windows 64 位兼容性问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4885540/
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
Delphi program & Windows 64-bit compatibility issue
提问by Irwan
I have some customers/candidate who complained that my program doesn't work on their Windows 7 64 bit version (confirmed with screenshots). The errors were strange, for example:
我有一些客户/候选人抱怨我的程序在他们的 Windows 7 64 位版本上不起作用(通过屏幕截图确认)。错误很奇怪,例如:
in the trial version i am getting a error message whenever i click on \"mark\" \"delete\" \"help\".
error msg is: Access violation at address 0046C978 in module \'ideduper.exe.\' read of address 00000004
windows 7 ultimate 64bit. i7 920 @2.67GHz 9gb or ram
在试用版中,每当我点击\"标记\"\"删除\"\"帮助\"时,我都会收到一条错误消息。
错误消息是:在模块 \'ideduper.exe.\' 读取地址 00000004 中地址 0046C978 处的访问冲突
Windows 7 终极版 64 位。i7 920 @2.67GHz 9gb 或内存
'Mark', 'delete' and 'help' are just standard TToolButton on TToolbar.
“标记”、“删除”和“帮助”只是 TToolbar 上的标准 TToolButton。
The other example is failing to get a thumbnail from IExtractImage.
另一个示例无法从 IExtractImage 获取缩略图。
I have told them to try Compatibility mode but still doesn't work.
我已经告诉他们尝试兼容模式,但仍然不起作用。
The problem is when I tested it on Windows 7 HP 64-bit on my computer (which I've done it before released it actually) it just works fine! So I don't know what causing it
问题是当我在我的计算机上的 Windows 7 HP 64 位上测试它时(我在实际发布之前已经完成了它)它运行良好!所以我不知道是什么原因造成的
Do you have any advice ?Are different Windows package (home basic,premium,ultimate,etc) treating 32 bit prog differently ?Are the newer version of Delphis (I use 2006) more compatible with 64 bit Windows ? Do I need to wait until 64 bit compiler out?
你有什么建议吗?不同的 Windows 包(家庭基本版、高级版、终极版等)对 32 位程序的处理方式不同吗?新版本的 Delphis(我使用 2006)是否与 64 位 Windows 更兼容?我需要等到 64 位编译器出来吗?
Thanks in advance
提前致谢
回答by Kaitnieks
Your best bet in my opinion is to add MadExcept or EurekaLog or something similar to your application and give it to the customer to try again. MadExcept will generate log with stack trace, which will give you a clearer view of what is happening there.
在我看来,您最好的选择是添加 MadExcept 或 EurekaLog 或类似于您的应用程序的内容,并将其提供给客户再试一次。MadExcept 将生成带有堆栈跟踪的日志,这将使您更清楚地了解那里发生的事情。
To answer 2nd part of the question, 32bit Delphi programs work fine on 64bit Windows 7. I think it's more likely you have some memory management problems and the customer just happens to stumble upon them while you don't. Use FastMM4 to track those down.
为了回答问题的第二部分,32 位 Delphi 程序在 64 位 Windows 7 上运行良好。我认为您更有可能遇到一些内存管理问题,而客户只是碰巧偶然发现了它们,而您没有。使用 FastMM4 来追踪这些。
回答by Kaitnieks
Your applications is trying to access an invalid pointer. Changing environment may surface issues that are hidden in others. Check your application, and use FastMM + JCL+JCVL/MadExcept/EurekaLog to get a detailed trace of the issue. Some Windows APIs may have some stricter call requisites under 7 and/or 64 bit, but we would have to know what your app actually cals.
您的应用程序正在尝试访问无效的指针。不断变化的环境可能会暴露隐藏在其他环境中的问题。检查您的应用程序,并使用 FastMM + JCL+JCVL/MadExcept/EurekaLog 获取问题的详细跟踪。一些 Windows API 在 7 位和/或 64 位下可能有一些更严格的调用要求,但我们必须知道你的应用程序实际调用什么。
回答by Warren P
A free alternative to MadExcept is JCL Debug stuff. However it is less thorough and doesn't include the cool dialog box to send the stack trace to you via email, or as a file you can attach and manually email.
MadExcept 的免费替代品是 JCL 调试工具。然而,它不太彻底,并且不包括通过电子邮件将堆栈跟踪发送给您的酷对话框,或者作为您可以附加和手动通过电子邮件发送的文件。
MadExcept is worth the money, and it is free for non-commercial use. You could try it first on your own PC, observe its functionality, and be sure it functions the way you want, and then buy it.
MadExcept 物有所值,并且可以免费用于非商业用途。您可以先在您自己的 PC 上试用它,观察它的功能,并确保它按您想要的方式运行,然后再购买。
If buying Delphi is worth it (and it is!) then buying mad Except is a no brainer. But if you insist on rolling your own, JCLDebug (part of jedi code library) is also pretty nice.
如果购买 Delphi 是值得的(而且确实值得!),那么购买 mad except 是没有道理的。但是如果你坚持自己滚动,JCLDebug(绝地代码库的一部分)也很不错。
回答by Mike Versteeg
Give them a stripped down version of your app and see when the problem goes away. I am betting it is your code as I never had any problems with my (hundreds of) W7/64 clients.
给他们一个精简版的应用程序,看看问题何时消失。我敢打赌这是您的代码,因为我的(数百个)W7/64 客户端从未遇到任何问题。
回答by Ken White
I'd be willing to bet it's an issue in your code. The reason it's failing on your customer's machine and not yours is that your machine probably has the default Data Execution Protection (DEP) enabled (which is turned on only for essential Windows programs and services), while your customer's computer is actually using DEP as intended (turned on for all programs and services).
我愿意打赌这是您代码中的一个问题。它在您客户的机器上而不是您的机器上失败的原因是您的机器可能启用了默认的数据执行保护 (DEP)(仅为必要的 Windows 程序和服务启用),而您的客户的计算机实际上正在按预期使用 DEP (为所有程序和服务打开)。
The default setting (which is compatible with older versions of Windows, like 95/98/ME), allows software to execute code from what should be data segments. The more strict setting won't allow this, and raises a system-level exception instead.
默认设置(与旧版本的 Windows,如 95/98/ME 兼容),允许软件从应该是数据段的地方执行代码。更严格的设置不允许这样做,而是引发系统级异常。
You can check the settings between the two by looking at System Properties. I'm not at a Win7 machine right now, but on WinXP you get there by right-clicking on My Computer, choosing Properties, clicking on Performance Options, and then selecting the "Data Execution Prevention" tab. Find it on Vista/Win7 by using the Help; search for Data Execution Protection.
您可以通过查看系统属性来检查两者之间的设置。我现在不在 Win7 机器上,但在 WinXP 上,您可以通过右键单击我的电脑,选择属性,单击性能选项,然后选择“数据执行保护”选项卡来到达那里。使用帮助在 Vista/Win7 上找到它;搜索数据执行保护。
The solution, as previous answers have told you, is to install MadExcept or EurekaLog. You can also get a free version as part of JEDI, in JCLDebug IIRC. I haven't used it, so I can't vouch for it personally. I've heard it's pretty good, though.
正如之前的答案告诉您的,解决方案是安装 MadExcept 或 EurekaLog。您还可以在 JCLDebug IIRC 中获得作为JEDI一部分的免费版本。我没有用过,所以我不能亲自担保。不过听说还不错
If you don't want to go that route, set a breakpoint somewhere in the startup portion of your app (make sure to build with debugging info turned on). Run your app until the breakpoint is hit, and then use the IDE's Search->Goto Address (which is disabled until the breakpoint is hit). Enter the address from the exception dialog (not the one that's almost all zeros, but the 0046C978 address, prefixed with $ to indicate it's in hex) as in $0046C978. You'll probably end up in the CPU window looking at assembly code, but you can usually pick out a line of Delphi code of some sort that can sometimes give you a place to start looking.
如果您不想走那条路,请在应用程序的启动部分的某处设置一个断点(确保在打开调试信息的情况下进行构建)。运行您的应用程序直到遇到断点,然后使用 IDE 的 Search->Goto Address(在遇到断点之前禁用该地址)。从异常对话框中输入地址(不是几乎全为零的地址,而是 0046C978 地址,以 $ 为前缀表示它是十六进制的),如 $0046C978。您可能最终会在 CPU 窗口中查看汇编代码,但您通常可以挑选出一行某种类型的 Delphi 代码,有时可以为您提供一个开始查看的位置。
回答by LightBulb
In addition to all previous suggestions, I'll add the difference in accessing Registry under WOW64 compared to Win32. If your application is accessing Registry to read or write some settings, you should be aware of this. First, take a look at thisand thispage in the MSDN. On thispage you will find 2 flags that determine the access you get to Registry from 32- or 64-bit application. KEY_WOW64_64KEY
is the one that you should use.
除了之前的所有建议,我将添加与 Win32 相比在 WOW64 下访问注册表的差异。如果您的应用程序正在访问 Registry 以读取或写入某些设置,您应该注意这一点。首先,看看MSDN 中的这个和这个页面。在此页面上,您将找到 2 个标志,用于确定您从 32 位或 64 位应用程序访问 Registry 的权限。KEY_WOW64_64KEY
是您应该使用的那个。
In any case, I agree with others about using madExcept (or any other similar tool) to be able to find the exact cause of your problems.
无论如何,我同意其他人关于使用 madExcept(或任何其他类似工具)能够找到问题的确切原因。