Closed kdschlosser closed 2 years ago
The article doesn't say that vswhere can be accessed through COM, but does discuss the COM APIs that are available for both native code (or through whatever FFI you use) or .NET (as RCWs). See https://docs.microsoft.com/dotnet/api/microsoft.visualstudio.setup.configuration for API documentation. Packages are available here:
But what's wrong with using the process submodule? vswhere handles a lot of conditions you'd have to otherwise. Yes, there's an overhead for starting a new process, but it's very fast with relatively little overhead (working set is very small) and already done for you. Think of an EXE as just another API. If you think about a typical shell script, it calls into EXEs no differently. It's up to you, but weighing the cost of starting a new process that already does what you need vs. setting up a build environment both for maintenance and CIs all while having to rewrite the detection code atop the APIs that vswhere already does really makes starting a new process look more attractive.
As for parsing, just use -format json -utf8
to emit proper JSON you can parse easily enough. For example, here's a simple script I threw together to get the path to the latest release installed:
import json
import subprocess
proc = subprocess.run(['vswhere', '-latest', '-format', 'json', '-utf8'], capture_output=True, text=True)
instances = json.loads(proc.stdout)
installationPath = instances[0]['installationPath']
Does that answer your question?
I know how to use the subprocess module but it has been stated that the output from vswhere can change and should not be used as an API. I can't remember where I saw that but I am likely to believe it.
I really do not like using the subprocess module to call an external program. It has always seemed kind of "hackish" to me.
But at any rate. This is what I have so far. This is a running example. This uses COM interfaces to collect the information.
the comtypes library is needed to run this script.
Here is a more completed version
I know how to use the subprocess module but it has been stated that the output from vswhere can change and should not be used as an API. I can't remember where I saw that but I am likely to believe it.
As the author of the COM APIs and vswhere, that is not true. We've added properties, but backward compatibility has been paramount, which is why, for example, I had to add a -utf8
parameter to output proper JSON when it was discovered there were scenarios (depending on the current locale set for the console host) where JSON wasn't compatible with UTF8 as spec'd. I didn't break compatibility then, as much as a I wanted to, because it's been paramount.
You're free to use COM if you want, but any scenarios that vswhere already support are up to you. You're free to examine the vswhere source, of course; however, the output of vswhere should always be backward compatible and to date has been. I have integration tests that help make sure of that.
Since you've got something working for your requirements, I'm closing this issue out.
Well it could be a problem and that problem would be a lack of documentation
https://devblogs.microsoft.com/setup/new-vswhere-with-more-properties/
In that blog it states that vswhere is able to be accessed using COM interfaces but there is no information about the API or where the documentation for the API is.
Can this be done.?
I am writing a Python script that will compile C libraries and C extensions and it will do it properly. Python's distutils package is really horrible at setting up a proper windows build environment and I wouldn't have expected them to really excel in this area because most of the developers for Python are nix type users so they don't have a really great working knowledge of Windows. Any time a user asks to have some portion of Python improved or to report a bug that relates to Windows it pretty much falls on def ears.
I have written the script and it does work with Python 2.7, 3.6+ x86 and x64. It is able to detect all Visual Studio versions from 9.0 (2008) to 15 (2019) and Windows SDK's from 6.0 to the most recent version. It is able to detect C++/ VS Build Tools and also C++ for Python 2.7.
It sets up an identical build environment to what Visual Studio does and it does it without using the vcvars*.bat files at all. I would like to eliminate using the python subprocess module to tun an executable and then parsing the output. I would prefer to keep it all within my script so to speak. I have written many python bindings for Windows COM interfaces so it is not foreign to me. I would prefer to now have to go hunting for GUID's and property keys.
I have used a COM object viewer and com up empty handed and I find these COM objects VisualStudio.DTE and VisualStudio.Solution using powershell but they do not look promising.
Any information on the COM API for vswhere would be really appreciated.