C# 仅在IDE之外的发布模式下与x64.NET 4.0应用程序崩溃

C# 仅在IDE之外的发布模式下与x64.NET 4.0应用程序崩溃,c#,.net,visual-studio-2010,pinvoke,windows-7-x64,C#,.net,Visual Studio 2010,Pinvoke,Windows 7 X64,所以,我的小测试应用程序遇到了一个非常奇怪的问题。说到问题,我的意思是它崩溃了。。。很难。没有抛出异常(至少,没有我能捕捉到的),只是“废话废话已停止响应…”消息。仅当我在发布模式下以x64运行应用程序时,在IDE外部,应用程序才会崩溃。如果我在x86模式下运行它,或者如果我在x64的IDE中运行它,或者我在x64中作为DEBUG单独运行它,那么它可以正常工作 我已经把范围缩小到了我的p/Message通话。所以,我需要聪明的头脑来看看我写的那些废话,告诉我我做得对不对。因为,说真的,我快要失去

所以,我的小测试应用程序遇到了一个非常奇怪的问题。说到问题,我的意思是它崩溃了。。。很难。没有抛出异常(至少,没有我能捕捉到的),只是“废话废话已停止响应…”消息。仅当我在发布模式下以x64运行应用程序时,在IDE外部,应用程序才会崩溃。如果我在x86模式下运行它,或者如果我在x64的IDE中运行它,或者我在x64中作为DEBUG单独运行它,那么它可以正常工作

我已经把范围缩小到了我的p/Message通话。所以,我需要聪明的头脑来看看我写的那些废话,告诉我我做得对不对。因为,说真的,我快要失去理智了。我在两台电脑上试过,它们都表现出相同的行为。我有点担心这可能是一个.NET4.0错误

无论如何,这是我的p/invoke代码。如果您看到任何奇怪或愚蠢的事情,请告诉我:

以下是呼叫Peek的消息:

private static bool PeekMessage()
{
        MSG message = new MSG();                // Message to retrieve.

        return Win32API.PeekMessage(ref message, IntPtr.Zero, 0, 0, PeekMessageFlags.NoRemove);
}
下面是一条消息(注意:suppress security属性位于类定义上,因此正在应用它):

这是消息:

[StructLayout(LayoutKind.Sequential)]
internal struct MSG
{
        /// <summary>Window handle.</summary>
        public IntPtr hwnd;
        /// <summary>Message to process.</summary>
        public uint Message;
        /// <summary>Window message parameter 1.</summary>
        public uint wParam;
        /// <summary>Window message parameter 2.</summary>
        public uint lParam;
        /// <summary>Time message was sent?</summary>
        public uint time;
        /// <summary>Mouse pointer position.</summary>
        public Point pt;
}
所以,如果你觉得有什么不对劲,请告诉我。我不希望这不是我的错


如果不够详细,很抱歉,如果您需要更多信息,请留下说明。

MSG的
lParam
wParam
字段的大小错误。您应该使用
IntPtr
而不是
uint
/
int

如果你看一下,你会发现:

  • LPARAM
    是一个
    LONG_PTR
    ,即32位平台上的32位大小和64位平台上的64位大小
  • PARAM
    是一个
    UINT\u PTR
    ,在32位平台上也是32位大小,在64位平台上是64位大小

相反地,
int
uint
类型的大小都是32位,无论平台是什么,这意味着在64位平台上,您的
MSG
结构的64位太小,这将导致某种内存损坏。

即使是最轻微的错误参数,尤其是字符串,我也有类似的问题(Unicode与Ansi等)为
PeekMessage
列出不同的签名。我建议您尝试其他签名,直到找到一个有效的签名为止。作为随机提示,如果调试此签名时遇到问题,则会导致异常。假设您可以在生成程序后加载程序,则可以运行它。然后,通常visual studio会附加到进程,您应该是即使在发布模式下,只要PDB与它在一起,你也可以调试它。然后,你可以在任何抛出的异常上打开break(CTRL+ALT+E)你可能会得到更多的信息。是的,我考虑过这样做,但它马上就例外了,所以没有时间附加。我现在意识到我可以在
peek消息之前添加
睡眠
延迟,但现在是午夜,我几乎无法形成连贯的句子,所以我没有想到这一点是的,我是在Uwe Keim建议我访问pinvoke.net后看到这个的。我昨天晚上就这么做了。我把它改成了
IntPtr
,效果很好。谢谢你们两位。
[StructLayout(LayoutKind.Sequential)]
internal struct MSG
{
        /// <summary>Window handle.</summary>
        public IntPtr hwnd;
        /// <summary>Message to process.</summary>
        public uint Message;
        /// <summary>Window message parameter 1.</summary>
        public uint wParam;
        /// <summary>Window message parameter 2.</summary>
        public uint lParam;
        /// <summary>Time message was sent?</summary>
        public uint time;
        /// <summary>Mouse pointer position.</summary>
        public Point pt;
}
internal enum PeekMessageFlags
{
        /// <summary>Keep message on the message queue.</summary>
        NoRemove = 0,
        /// <summary>Remove message from the queue.</summary>
        Remove = 1,
        /// <summary>Do not yield execution to waiting threads.</summary>
        NoYield = 2
}
Faulting application name: Tester_Graphics.exe, version: 1.0.0.0, time stamp: 0x4ec0ba85
Faulting module name: unknown, version: 0.0.0.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x00000000000001cb
Faulting process id: 0x1260
Faulting application start time: 0x01cca299e2c21a77
Faulting application path: D:\Code\Current\Gorgon\Branches\2.x\Dorian\Examples\Tester_Graphics\bin\Release\Tester_Graphics.exe
Faulting module path: unknown
Report Id: 20ac891f-0e8d-11e1-a5d7-bcaec5753ddd