一个Win32控制台应用程序能否检测是否是从资源管理器中运行的?

22 浏览
0 Comments

一个Win32控制台应用程序能否检测是否是从资源管理器中运行的?

我需要创建一个控制台应用程序,它需要一些参数。如果缺少或错误,我会打印出一个错误信息。

现在的问题是:如果有人通过双击资源管理器启动程序,控制台窗口会立即消失。(但从资源管理器启动的应用程序并不完全无用,您可以将文件拖放到其中并且它会工作)

我可以一直等待按键,但如果用户是从命令行启动它,我不想要那样。

有没有办法区分这些情况?

0
0 Comments

问题的出现原因是作者想要在Win32控制台应用程序中判断程序是从资源管理器运行还是从命令行运行。解决方法是使用GetConsoleTitle函数和AttachConsole函数来判断。

GetConsoleTitle函数用于获取控制台窗口的标题。如果函数返回0且GetLastError函数返回ERROR_SUCCESS,则说明程序是从控制台运行的;否则,说明程序是从GUI环境运行的。

AttachConsole函数用于将进程连接到指定的控制台进程。如果函数返回0,则说明程序是从GUI环境运行的;否则,说明程序是从控制台运行的,并且通过AttachConsole函数可以获取到已存在的控制台的句柄。

如果在GUI环境中需要在后续的操作中打印信息到控制台窗口,可以在需要的时候调用AllocConsole函数来创建一个新的控制台窗口。

反馈中提到,作者在使用MinGW/MSYS编译的命令行应用程序中,以上两种方法都无法区分是从资源管理器拖动文件到应用程序中运行,还是在bash shell中执行应用程序。

0
0 Comments

这篇文章将讨论一个问题:如何让Win32控制台应用程序检测它是否是从资源管理器中运行的。下面是一种解决方案以及出现该问题的原因。

在寻找解决方案时,作者发现了一个更好的方法,即使用GetConsoleProcessList函数来获取当前控制台附加的进程计数。如果该进程是唯一附加的进程,则在该进程退出时,控制台也会关闭。作者在https://devblogs.microsoft.com/oldnewthing/20160125-00/?p=92922中找到了这个解决方案。

然而,该解决方案存在一个错误(至少在Windows 10中存在),因为文档禁止使用null调用该函数。

作者给出了自己的解决方案:

DWORD procId;
DWORD count = GetConsoleProcessList(&procId, 1);
if (count < 2) ...

通过使用以上代码,作者可以检测到控制台是否有其他进程附加。如果计数小于2,则表示该进程是唯一附加的进程,从而可以进行相应的处理。

0