如何在SetCompatibleTextRenderingDefault抛出InvalidOperationException时找出IWin32Window已创建的内容?

时间:2017-05-05 08:40:59

标签: c# winforms

在重大重构之后,我运行我的WinForms应用程序,它立即在Application.SetCompatibleTextRenderingDefault(false)崩溃。一般来说,我理解是什么原因导致的:IWin32Window已经创建。

我的问题是,对于我的生活,我无法弄清楚这样的对象(或对象?)是如何被实例化的。 “在哪里”它被实例化后来成为一个希望更容易的后续问题:)抛出的行实际上是我的代码的第二行:如果我进入我的应用程序(使用F10而不是F5启动,要清楚),它会通过通常Application.EnableVisualStyles()没有问题,然后在第二行停止。

有没有办法“检查”创建的窗口?我正在寻找任何解决方案,代码行,调试器功能,外部程序,任何东西。谢谢。

请注意对我来说很明显我在重构过程中一定搞砸了。我无法编译三天,所以我最有可能自己创建了这个bug。我问是否有办法自信地找到有问题的IWin32Window对象。

更新

我在Program.Main()的最开头添加了以下代码:

        var thisProcess = System.Diagnostics.Process.GetCurrentProcess();
        if (thisProcess != null)
        {
            var mainWindow = thisProcess.MainWindowHandle;
        }

好吧,mainWindow是(指针)为零。

1 个答案:

答案 0 :(得分:4)

在运行Main()方法之前,您必须查找运行的代码。对于这样的代码没有很多候选者,只有Program类的静态构造函数(aka type initializer)才有资格。你知道你是否写了一个,并且可以设置一个断点,不太明显的情况是Program类中带有字段初始值设定项的static变量。 CLR实际上不支持,C#编译器通过创建静态构造函数本身并移动字段初始化程序的代码来解决它。

如果知道它是由字段初始化程序引起的,那么您可以考虑在相关框架方法上设置断点。这需要对内部如何工作有一些了解,并没有简单的快捷方式。好吧,除了问SO:)

首先使用工具>选项>调试>一般和解开"只是我的代码"。这不是你的代码。接下来使用Debug>新断点>功能断点>键入" System.Windows.Forms.NativeWindow.AddWindowToTable"。这是存储对任何已创建窗口的引用的内部方法,确保.NET类包装器对象不会过早收集垃圾。

按F5键,“调用堆栈”窗口指向恶意者。