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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With