从 Visual Studio 运行时,STARTUPINFO.wShowWindow 为 0 [英] STARTUPINFO.wShowWindow is 0 when running from Visual Studio

查看:22
本文介绍了从 Visual Studio 运行时,STARTUPINFO.wShowWindow 为 0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在调试名为 Notepad2 的开源记事本替代品(更具体地说,是最近的一个名为

根据 STARTUPINFO MSDN 条目,如果 dwFlags 中有 STARTF_USESHOWWINDOWwShowWindow 的值应该与 nCmdShow 的值匹配.但是,在这两种情况下(从 VS 和 cmd 启动),dwFlags 的值都是 0.

那么,这是 VS 的问题还是我的理解有误?

解决方案

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

有一个极小的案例可以证明这是故意的,盲目遵循 nCmdShow 建议是不可取的.它是一种恶意软件攻击媒介,允许它在用户不注意的情况下启动程序.许多程序故意忽略 SW_HIDE,这不是一件很直观的事情,而且很容易被忽略.您需要一个半满的玻璃杯才能做出这种解释,但是 WinMain() 的 nCmdShow 参数是通常使用的并且是正确的.

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

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

I stumbled upon an issue while debugging a feature in an open-source Notepad replacement called Notepad2 (more specifically, a more recent fork called Notepad2-mod).

It has a flag /u that causes the app to restart itself under Administrative privileges (using runas verb with ShellExecute). The code looks like this (snipped for brevity):

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);

For some reason, if I launched this from Visual Studio (with or without a debugger attached), the elevated child process' main window would just not show! It would appear in Process Explorer, but had no visible windows.

Upon investigation, I realized that the nCmdShow passed to the child process' WinMain was 0 (which corresponds to SW_HIDE) when started from Visual Studio! This value was subsequently passed to ShowWindow, and that's why it didn't show.

When trying to launch this from a cmd shell, everything worked fine.

Upon further investigation, it turned out that the value of si.wShowWindow, obtained by a call to GetStartupInfo was 0 when running in VS, but was 1 when started from a cmd:

According to STARTUPINFO MSDN entry, the value for wShowWindow should match the value of nCmdShow if dwFlags has STARTF_USESHOWWINDOW in it. However, in both cases (launching from VS and cmd), the value for dwFlags was 0.

So, is this an issue with VS or am I just holding it wrong?

解决方案

I'll write this one up, it is a pretty awesome bug. It is specific to the VS2015 debugging engine, it is quite notorious for having rather a lot of bugs. Something you can see for yourself by disabling it. Tools > Options > Debugging > General > tick the "Use Native Compatibility Mode" option. That forces an older debugging engine to be used, you now consistently get STARTUPINFO.nCmdShow == SW_SHOWNORMAL.

There is a wee corner-case to reason that this was intentional, blindly following the nCmdShow advice is not advisable. It is a malware attack vector, allowing it to start a program without the user noticing. Many programs intentionally ignore SW_HIDE, not a very intuitive thing to do and very easy to overlook. You need a glass that's well over half-full to make that interpretation however, the nCmdShow argument to WinMain() is what is normally used and it is correct.

Which is also the workaround that you can use. Of course in this specific case you should never rely on the startup value and pass SW_SHOWNORMAL or SW_SHOWMAXIMIZED depending on the current state of Notepad++'s main window.

So I vote bug, use connect.microsoft.com to report it. Put a link to the feedback article in a comment and we'll vote for it.

这篇关于从 Visual Studio 运行时,STARTUPINFO.wShowWindow 为 0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆