从Visual Studio运行时STARTUPINFO.wShowWindow为0

Iga*_*nik 9 windows winapi visual-studio-2015

我在一个名为Notepad2的开源记事本替换中调试一个功能时遇到了一个问题(更具体地说,是一个名为Notepad2-mod的更新的分支).

它有一个标志/u,使应用程序在管理权限下重新启动(使用runas带有ShellExecute的动词).代码看起来像这样(为简洁起见):

STARTUPINFO si;
SHELLEXECUTEINFO sei;

si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);

ZeroMemory(&sei,sizeof(SHELLEXECUTEINFO));
sei.cbSize = sizeof(SHELLEXECUTEINFO);
...
sei.lpVerb = L"runas";
sei.lpFile = lpArg1;
sei.lpParameters = lpArg2;
sei.nShow = si.wShowWindow;

ShellExecuteEx(&sei);
Run Code Online (Sandbox Code Playgroud)

出于某种原因,如果我从Visual Studio启动它(无论是否附加调试器),提升的子进程'主窗口就不会显示!它将出现在Process Explorer中,但没有可见的窗口.

通过调查,我意识到从Visual Studio启动时nCmdShow传递给子进程' WinMain为0(对应于SW_HIDE)!随后将该值传递给了ShowWindow,这就是它没有显示的原因.

当尝试从cmd shell启动它时,一切正常.

经过进一步调查,结果发现,在VS中运行时si.wShowWindow,通过调用获得的值为GetStartupInfo0,但从cmd启动时为1:

从cmd发射

STARTUPINFO MSDN条目,该值wShowWindow应该匹配的值nCmdShow,如果dwFlagsSTARTF_USESHOWWINDOW在里面.但是,在两种情况下(从VS和cmd启动),值为dwFlags0.

那么,这是VS的一个问题还是我只是把它弄错了?

Han*_*ant 8

我会写这个,这是一个非常棒的bug.它特定于VS2015调试引擎,因为它有很多错误而臭名昭着.通过禁用它可以为自己看到的东西.工具>选项>调试>常规>勾选"使用本机兼容模式"选项.这会强制使用较旧的调试引擎,现在您始终获得STARTUPINFO.nCmdShow == SW_SHOWNORMAL.

有一个小问题,因为这是故意的,盲目地遵循nCmdShow建议是不可取的.它是一种恶意软件攻击媒介,允许它在用户不注意的情况下启动程序.许多程序故意忽略SW_HIDE,这不是一个非常直观的事情,很容易被忽视.你需要一个超过半满的玻璃才能做出这种解释,但WinMain()的nCmdShow参数是通常使用的,它是正确的.

这也是您可以使用的解决方法.当然,在这种特定情况下,您不应该依赖启动值并传递SW_SHOWNORMAL或SW_SHOWMAXIMIZED,具体取决于Notepad ++主窗口的当前状态.

所以我投票错误,使用connect.microsoft.com报告它.在评论中添加反馈文章的链接,我们将投票给它.