究竟是怎么WinMain()
称呼的?我记得专业黑客使用的一个函数,它以(某物)开头,看起来像__startupWinMain()
.
问题是,我有一个 Win32 EXE(用 编译/SUBSYSTEM:WINDOWS
)但从命令行获取参数。如果命令行不正确,该过程应将帮助消息打印到控制台。
如何FreeConsole()
使用链接器选项从 exe 手动释放(或)/SUBSYSTEM:WINDOWS
?
作为程序的第一步,检查参数。如果他们没问题,请照常继续。
否则调用AttachConsole
通过ATTACH_PARENT_PROCESS
。如果成功,那么您可以将错误打印到标准输出并退出。如果没有,那么您必须在消息框中显示错误。
也许您应该考虑让程序在命令行不正确时弹出一个消息框。像这样的东西:
MessageBox( NULL, "(description of command line error)",
"MyProg - Command Line Error",
MB_OK|MB_ICONEXCLAMATION );
这将在显示屏中央打开一个消息框,并在实际终止程序之前等待用户确认。
另一方面,您可以将程序构建为控制台应用程序并用于printf()
写入控制台。控制台程序可能仍会创建窗口,但控制台本身会挂起,除非您弄清楚如何从中分离(然后,当然,您将不再能够使用printf()
.)
WinMain() 实际上是如何调用的?
如果您在调试器中单步执行程序的第一行,然后查看堆栈,您可以看到 WinMain 是如何被调用的。典型构建的实际启动函数是从运行时库中提取的函数。对我来说,它是_WinMainCRTStartup
.,但我想它可能会根据您构建的编译器、链接器和库的版本而有所不同。运行时库中的启动函数进行一些初始化,然后调用 WinMain。
使用dumpbin /headers
(或其他可以检查 PE 二进制文件的程序),您可以确认哪个函数是可执行文件的“入口点”。除非你做了一些改变它,你可能会看到_WinMainCRTStartup
,这与堆栈跟踪告诉我们的一致。
那应该回答你的问题,但它不能解决你的问题。看起来其他一些人已经发布了很好的解决方案。
编译器如何知道调用 wWinMain 而不是标准的 main 函数?实际发生的是 Microsoft C 运行时库 (CRT) 提供调用 WinMain 或 wWinMain 的 main 实现。注意 CRT 在 main 中做了一些额外的工作。例如,在 wWinMain 之前调用任何静态初始化程序。尽管您可以告诉链接器使用不同的入口点函数,但如果您链接到 CRT,请使用默认值。否则,将跳过 CRT 初始化代码,导致无法预料的结果。(例如,全局对象将无法正确初始化。)