251 lines
7.7 KiB
C#
251 lines
7.7 KiB
C#
|
// Copyright 2017 - Refael Ackermann
|
||
|
// Distributed under MIT style license
|
||
|
// See accompanying file LICENSE at https://github.com/node4good/windows-autoconf
|
||
|
|
||
|
// Usage:
|
||
|
// powershell -ExecutionPolicy Unrestricted -Command "Add-Type -Path Find-VisualStudio.cs; [VisualStudioConfiguration.Main]::PrintJson()"
|
||
|
// This script needs to be compatible with PowerShell v2 to run on Windows 2008R2 and Windows 7.
|
||
|
|
||
|
using System;
|
||
|
using System.Text;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using System.Collections.Generic;
|
||
|
|
||
|
namespace VisualStudioConfiguration
|
||
|
{
|
||
|
[Flags]
|
||
|
public enum InstanceState : uint
|
||
|
{
|
||
|
None = 0,
|
||
|
Local = 1,
|
||
|
Registered = 2,
|
||
|
NoRebootRequired = 4,
|
||
|
NoErrors = 8,
|
||
|
Complete = 4294967295,
|
||
|
}
|
||
|
|
||
|
[Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")]
|
||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||
|
[ComImport]
|
||
|
public interface IEnumSetupInstances
|
||
|
{
|
||
|
|
||
|
void Next([MarshalAs(UnmanagedType.U4), In] int celt,
|
||
|
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt,
|
||
|
[MarshalAs(UnmanagedType.U4)] out int pceltFetched);
|
||
|
|
||
|
void Skip([MarshalAs(UnmanagedType.U4), In] int celt);
|
||
|
|
||
|
void Reset();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.Interface)]
|
||
|
IEnumSetupInstances Clone();
|
||
|
}
|
||
|
|
||
|
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
|
||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||
|
[ComImport]
|
||
|
public interface ISetupConfiguration
|
||
|
{
|
||
|
}
|
||
|
|
||
|
[Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")]
|
||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||
|
[ComImport]
|
||
|
public interface ISetupConfiguration2 : ISetupConfiguration
|
||
|
{
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.Interface)]
|
||
|
IEnumSetupInstances EnumInstances();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.Interface)]
|
||
|
ISetupInstance GetInstanceForCurrentProcess();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.Interface)]
|
||
|
ISetupInstance GetInstanceForPath([MarshalAs(UnmanagedType.LPWStr), In] string path);
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.Interface)]
|
||
|
IEnumSetupInstances EnumAllInstances();
|
||
|
}
|
||
|
|
||
|
[Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")]
|
||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||
|
[ComImport]
|
||
|
public interface ISetupInstance
|
||
|
{
|
||
|
}
|
||
|
|
||
|
[Guid("89143C9A-05AF-49B0-B717-72E218A2185C")]
|
||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||
|
[ComImport]
|
||
|
public interface ISetupInstance2 : ISetupInstance
|
||
|
{
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetInstanceId();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.Struct)]
|
||
|
System.Runtime.InteropServices.ComTypes.FILETIME GetInstallDate();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetInstallationName();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetInstallationPath();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetInstallationVersion();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetDisplayName([MarshalAs(UnmanagedType.U4), In] int lcid);
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetDescription([MarshalAs(UnmanagedType.U4), In] int lcid);
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string ResolvePath([MarshalAs(UnmanagedType.LPWStr), In] string pwszRelativePath);
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.U4)]
|
||
|
InstanceState GetState();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
|
||
|
ISetupPackageReference[] GetPackages();
|
||
|
|
||
|
ISetupPackageReference GetProduct();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetProductPath();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||
|
bool IsLaunchable();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||
|
bool IsComplete();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
|
||
|
ISetupPropertyStore GetProperties();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetEnginePath();
|
||
|
}
|
||
|
|
||
|
[Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")]
|
||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||
|
[ComImport]
|
||
|
public interface ISetupPackageReference
|
||
|
{
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetId();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetVersion();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetChip();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetLanguage();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetBranch();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetType();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||
|
string GetUniqueId();
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||
|
bool GetIsExtension();
|
||
|
}
|
||
|
|
||
|
[Guid("c601c175-a3be-44bc-91f6-4568d230fc83")]
|
||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||
|
[ComImport]
|
||
|
public interface ISetupPropertyStore
|
||
|
{
|
||
|
|
||
|
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
|
||
|
string[] GetNames();
|
||
|
|
||
|
object GetValue([MarshalAs(UnmanagedType.LPWStr), In] string pwszName);
|
||
|
}
|
||
|
|
||
|
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
|
||
|
[CoClass(typeof(SetupConfigurationClass))]
|
||
|
[ComImport]
|
||
|
public interface SetupConfiguration : ISetupConfiguration2, ISetupConfiguration
|
||
|
{
|
||
|
}
|
||
|
|
||
|
[Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")]
|
||
|
[ClassInterface(ClassInterfaceType.None)]
|
||
|
[ComImport]
|
||
|
public class SetupConfigurationClass
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public static class Main
|
||
|
{
|
||
|
public static void PrintJson()
|
||
|
{
|
||
|
ISetupConfiguration query = new SetupConfiguration();
|
||
|
ISetupConfiguration2 query2 = (ISetupConfiguration2)query;
|
||
|
IEnumSetupInstances e = query2.EnumAllInstances();
|
||
|
|
||
|
int pceltFetched;
|
||
|
ISetupInstance2[] rgelt = new ISetupInstance2[1];
|
||
|
List<string> instances = new List<string>();
|
||
|
while (true)
|
||
|
{
|
||
|
e.Next(1, rgelt, out pceltFetched);
|
||
|
if (pceltFetched <= 0)
|
||
|
{
|
||
|
Console.WriteLine(String.Format("[{0}]", string.Join(",", instances.ToArray())));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
try
|
||
|
{
|
||
|
instances.Add(InstanceJson(rgelt[0]));
|
||
|
}
|
||
|
catch (COMException)
|
||
|
{
|
||
|
// Ignore instances that can't be queried.
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static string JsonString(string s)
|
||
|
{
|
||
|
return "\"" + s.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"";
|
||
|
}
|
||
|
|
||
|
private static string InstanceJson(ISetupInstance2 setupInstance2)
|
||
|
{
|
||
|
// Visual Studio component directory:
|
||
|
// https://docs.microsoft.com/en-us/visualstudio/install/workload-and-component-ids
|
||
|
|
||
|
StringBuilder json = new StringBuilder();
|
||
|
json.Append("{");
|
||
|
|
||
|
string path = JsonString(setupInstance2.GetInstallationPath());
|
||
|
json.Append(String.Format("\"path\":{0},", path));
|
||
|
|
||
|
string version = JsonString(setupInstance2.GetInstallationVersion());
|
||
|
json.Append(String.Format("\"version\":{0},", version));
|
||
|
|
||
|
List<string> packages = new List<string>();
|
||
|
foreach (ISetupPackageReference package in setupInstance2.GetPackages())
|
||
|
{
|
||
|
string id = JsonString(package.GetId());
|
||
|
packages.Add(id);
|
||
|
}
|
||
|
json.Append(String.Format("\"packages\":[{0}]", string.Join(",", packages.ToArray())));
|
||
|
|
||
|
json.Append("}");
|
||
|
return json.ToString();
|
||
|
}
|
||
|
}
|
||
|
}
|