C# 当SetCompatibleTextRenderingDefault引发InvalidOperationException时,如何找出已创建的IWIN32窗口?
主要重构之后,我运行WinForms应用程序,它立即在C# 当SetCompatibleTextRenderingDefault引发InvalidOperationException时,如何找出已创建的IWIN32窗口?,c#,winforms,C#,Winforms,主要重构之后,我运行WinForms应用程序,它立即在应用程序上崩溃。SetCompatibleTextRenderingDefault(false)。一般来说,我理解这是什么原因:已经创建了一个iwin32窗口 我的问题是,在我的一生中,我无法弄清楚这样一个对象(或多个对象?)被实例化了。“Where”被实例化是一个希望更简单的问题:)抛出的行实际上是我代码的第二行:如果我进入我的应用程序(明确地说,是用F10而不是F5启动),它会顺利通过通常的应用程序。EnableVisualStyles(
应用程序上崩溃。SetCompatibleTextRenderingDefault(false)
。一般来说,我理解这是什么原因:已经创建了一个iwin32窗口
我的问题是,在我的一生中,我无法弄清楚这样一个对象(或多个对象?)被实例化了。“Where”被实例化是一个希望更简单的问题:)抛出的行实际上是我代码的第二行:如果我进入我的应用程序(明确地说,是用F10而不是F5启动),它会顺利通过通常的应用程序。EnableVisualStyles()
,然后它会在第二行停止
有没有办法“检查”创建的窗口?我正在寻找任何解决方案,代码行,调试器功能,外部程序,任何东西。多谢各位
请注意,对我来说很明显,我一定是在重构过程中搞砸了什么。我有三天无法编译,所以很可能是我自己造成了这个bug。我在问是否有办法自信地找到有问题的IWin32Window
对象
更新
我在Program.Main()
的开头添加了以下代码:
嗯,mainWindow
是(指向)零的指针 您必须查找在Main()方法运行之前运行的代码。这类代码的候选代码不多,只有程序类的静态构造函数(aka type initializer)符合条件。如果您已经编写了一个,并且可以在上面设置断点,那么不太明显的情况是程序类中带有字段初始值设定项的static
变量。CLR实际上并不支持C#编译器,它通过创建静态构造函数本身并移动字段初始值设定项的代码来解决这个问题
如果知道它是由字段初始化器引起的,那么你可以考虑在相关的框架方法上设置断点。这确实需要对其内部工作方式有所了解,而且没有简单的捷径。好吧,除了问苏:)
首先使用工具>选项>调试>常规并取消选中“仅我的代码”。这不是你的代码。接下来使用调试>新建断点>函数断点>键入“System.Windows.Forms.NativeWindow.AddWindowToTable”。这是存储对任何已创建窗口的引用的内部方法,确保.NET类包装器对象不会过早地被垃圾收集
按F5,调用堆栈窗口指向作恶者。您可能可以使用SetWinEventHook
方法收听EVENT\u OBJECT\u CREATE
事件。您还可以处理Windows UI自动化事件。看一看,没有很多方法会弄错。除了一个。我的水晶球告诉我,您使用字段初始值设定项向程序类添加了一个static
变量。类似于publicstaticform1mainwindow=newform1()首先执行的代码>,当您执行单个步骤时,调试器不会显示它。“别那样做!”汉斯帕桑哈,我希望如此!:)我在大多数窗体的构造函数中都设置了断点,但仍然没有成功。我只有两个静态变量(我知道,我不应该这样做,但我没有编写遗留代码,重构仍在待办事项中),显然没有一个能实例化任何表单。@RezaAghaei谢谢你的指针-我要试试。使用调试>新断点>函数断点>键入System.Windows.Forms.NativeWindow.AddWindowToTable。使用工具>选项>调试禁用“仅我的代码”选项,以便断点可以工作。
var thisProcess = System.Diagnostics.Process.GetCurrentProcess();
if (thisProcess != null)
{
var mainWindow = thisProcess.MainWindowHandle;
}