microsoft / vswhere

Locate Visual Studio 2017 and newer installations
MIT License
921 stars 97 forks source link

vswhere returns nothing when run from Cygwin SSH terminal #236

Closed vinaydhegde closed 2 years ago

vinaydhegde commented 3 years ago

I have installed vs2019 professional (internal version 16.9.6) with vs installer 2.9.x. If I run ./vswhere.exe -version '[16.0,17.0)' from SSH terminal, it is returning nothing. It just prints, Visual Studio Locator version 2.7.1+180c706d56 [query version 2.7.3111.17308]
Copyright (C) Microsoft Corporation. All rights reserved.

Whereas, on CMD terminal (on the host) vswhere is working. It is also working in direct Cygwin terminal (locally). Not sure, what is the issue when run from SSH terminal.

Please note: In VS 2019 internal version 16.0 with vs installer 2.0.3287, I am not facing any issue (i.e. vswhere is working even in SSH terminal).

I also tried -products *, -products Microsoft.VisualStudio.Product.BuildTools, -prerelease, -all command line options. None of them are working from SSH terminal.

Output from command window (not SSH terminal) where it successfully runs, C:\Program Files (x86)\Microsoft Visual Studio>cd Installer

C:\Program Files (x86)\Microsoft Visual Studio\Installer>vswhere.exe -version [16.0,17.0) Visual Studio Locator version 2.7.1+180c706d56 [query version 2.7.3111.17308] Copyright (C) Microsoft Corporation. All rights reserved.

instanceId: 748e645e installDate: 5/29/2021 6:25:26 AM installationName: VisualStudio/16.9.6+31313.79 installationPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional installationVersion: 16.9.31313.79 productId: Microsoft.VisualStudio.Product.Professional productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\devenv.exe state: 4294967295 isComplete: 1 isLaunchable: 1 isPrerelease: 0 isRebootRequired: 0 displayName: Visual Studio Professional 2019 description: Professional IDE best suited to small teams channelId: VisualStudio.16.Release channelUri: https://aka.ms/vs/16/release/channel enginePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service installChannelUri: C:\temp\ansible_workdir\Desktop_development_with_C++_Ansible\ChannelManifest.json layoutPath: C:\temp\ansible_workdir\Desktop_development_with_C++_Ansible releaseNotes: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-v16.9#16.9.6 thirdPartyNotices: https://go.microsoft.com/fwlink/?LinkId=660909 updateDate: 2021-05-29T11:25:26.1294549Z catalog_buildBranch: d16.9 catalog_buildVersion: 16.9.31313.79 catalog_id: VisualStudio/16.9.6+31313.79 catalog_localBuild: build-lab catalog_manifestName: VisualStudio catalog_manifestType: installer catalog_productDisplayVersion: 16.9.6 catalog_productLine: Dev16 catalog_productLineVersion: 2019 catalog_productMilestone: RTW catalog_productMilestoneIsPreRelease: False catalog_productName: Visual Studio catalog_productPatchVersion: 6 catalog_productPreReleaseMilestoneSuffix: 1.0 catalog_productSemanticVersion: 16.9.6+31313.79 catalog_requiredEngineVersion: 2.9.3365.38425 properties_campaignId: properties_channelManifestId: VisualStudio.16.Release/16.9.6+31313.79 properties_nickname: properties_setupEngineFilePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\setup.exe

heaths commented 3 years ago

I'm confused. You said it works on in cmd on the host, but not via ssh - which implies you're remoted into another machine. Is that the case? vswhere shouldn't be affected by the shell you use, but definitely by the machine on which you run it. It has to have VS installed. vswhere uses no remoting APIs. It's a simple console app with very few imports.

vinaydhegde commented 3 years ago

Thanks for the response. I'll try to clarify. Let's say, machine-X has VS installed. From machine-Y, I am SSHing in to machine-X & then trying to run vswhere command there. In this case vswhere is NOT working. Where as, If I connect to machine-X via remote desktop & run vswhere in CMD window, it is working. Please let me know if you need any more info/clarification. (This issue is observed in version 16.9.6 or in the current latest)

Few details about SSH: We use Cygwin provided SSH(not openSSH) on Windows. i.e. Machine-X is configured with Cygwin + SSH service (sshd by cygwin). Machine-Y (can be a Windows Host or Linux) will be able to SSH to machine-X as a ssh service is running on machine-X.

Note: As I have already mentioned, when using VS2019 version 16.0, vswhere is working for all the use cases mentioned above, including SSH terminal.

heaths commented 3 years ago

It would be helpful if you'd create a dump of vswhere when it starts within the cygwin-compiled shell. I suspect it's redirecting APIs. You can use gflags or other methods to record a dump.

Can you also try OpenSSH on Windows and see if this repros?

vinaydhegde commented 3 years ago

Can you please guide me on how to record a dump using gflags. As I understand, gflags.exe comes with Win10 SDK. So I changed/updated installed Win10 SDK to include 'Debugging Tools for Windows' & after that, I could locate gflags.exe at: 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64' I am not sure how to run this. I tried the below command. gflags.exe /i 'vswhere.exe' + ux But don't know whether it is the right command or where it will dump the records.

heaths commented 3 years ago

If you already have the debugger tools installed, it's probably faster just to use cdb.

<path>\cdb.exe "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"
# once that's running, inside cdb:
.sympath srv*https://msdl.microsoft.com/download/symbols
.reload
g
.dump /ma c:\vswhere.pdb
qq

Then attach c:\vswhere.pdb to this issue. Hopefully that contains enough. I suspect cygwin is hooking some APIs preventing either vswhere from loading the COM server that reads the info, or the COM server from actually finding and reading the necessary info.

vinaydhegde commented 3 years ago

Thanks for the details. PFA vswhere pdb file. (Renamed as .txt, as github was not allowing to upload pdb) vswhere.txt

heaths commented 3 years ago

The dump is from a breakpoint and the COM server isn't even loaded yet. Did you run through to the end? If an exception occurred while in the debugger, that is also necessary to know. But use g to run till the end. See here for an example of what that looks like.

I really don't know what can be done about this. vswhere just uses standard COM APIs to load a COM server DLL registered in %ProgramData%. The COM server DLL looks for specific files also under %ProgramData%. If cygwin is hooking any system calls or overriding Windows-specified environment variables that may be used in well-known folder look ups, this would account for the issue.

FWIW, this is working correctly for me over OpenSSH on Windows, as I'd expect since it's just opening a remote terminal connection with cmd as my current login shell.

vinaydhegde commented 3 years ago

Thanks for the quick response. I'll re-run cdb & share the pdb file again tomorrow ( I do not have the exact environment to reproduce the issue now). It may not be a Cygwin issue. Because, as I mentioned already it works with version 16.0.

vinaydhegde commented 3 years ago

One more thing to mention, If I install 16.0 & then upgrade it to 16.9.6 or the latest version, vswhere still works (on SSH/cygwin terminal). May be this gives some clue on what's happening. To summarise:

heaths commented 3 years ago

The information is parsed in the same way. Have you tried it without parameters? Something in cygwin could be messing up parsing in the -version parameter.

vswhere is just a COM client. The COM server installed with VS, which I also wrote, does the heavy lifting. Upgrading shouldn't have any effect other than installing a new COM server and new vswhere version, though the vswhere version shouldn't really matter since it is just a COM client designed to work with even the first version of the COM server we shipped for VS 15.0.

Run vswhere without any parameters. IF that doesn't yield anything, run it with -prerelease -all. -prerelease will make sure it's covering any case if you used a non-release channel, and -all will query a product in any state. For example, if a reboot is pending, vswhere won't show the instance by default because the instance isn't stable - a reboot is required to avoid torn state.

heaths commented 2 years ago

Closing without author response. If the requested information is provided, we can reopen the investigation.

Loffe commented 2 years ago

I had a similar issue: running vswhere.exe on Jenkins always resulted in empty output.

This was due to the environment variable ProgramData missing. (Jenkins removes system environment variables unless we explicitly whitelisted them). Re-adding ProgramData solved the issue šŸ˜„ šŸ‘

It would have been nice with an error message, or non-zero exit code if vswhere could not run properly.

heaths commented 2 years ago

That would be a breaking change. This was designed such that any error from the COM APIs (it's the underlying COM server that needs %ProgramData%) would be treated as "no valid instances found". Though, we might entertain a PR that adds, say, a -error switch to enabled error exit codes from any (or at least most) terminal errors.

Note that the absence of environment variables can and will affect build environments as well. Any build output that attempts to look up locations like MSBuild extensions where %ProgramFiles(x86)% and/or %ProgramFiles% is used to find them will fail to enumerate such extensions, unless MSBuild internally is using CSIDLs or KNOWNFOLDERIDs that otherwise populate environment variables.