• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 - Refael Ackermann
2 // Distributed under MIT style license
3 // See accompanying file LICENSE at https://github.com/node4good/windows-autoconf
4 
5 // Usage:
6 // powershell -ExecutionPolicy Unrestricted -Command "Add-Type -Path Find-VisualStudio.cs; [VisualStudioConfiguration.Main]::PrintJson()"
7 // This script needs to be compatible with PowerShell v2 to run on Windows 2008R2 and Windows 7.
8 
9 using System;
10 using System.Text;
11 using System.Runtime.InteropServices;
12 using System.Collections.Generic;
13 
14 namespace VisualStudioConfiguration
15 {
16     [Flags]
17     public enum InstanceState : uint
18     {
19         None = 0,
20         Local = 1,
21         Registered = 2,
22         NoRebootRequired = 4,
23         NoErrors = 8,
24         Complete = 4294967295,
25     }
26 
27     [Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")]
28     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
29     [ComImport]
30     public interface IEnumSetupInstances
31     {
32 
Next([MarshalAs(UnmanagedType.U4), In] int celt, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt, [MarshalAs(UnmanagedType.U4)] out int pceltFetched)33         void Next([MarshalAs(UnmanagedType.U4), In] int celt,
34             [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt,
35             [MarshalAs(UnmanagedType.U4)] out int pceltFetched);
36 
Skip([MarshalAs(UnmanagedType.U4), In] int celt)37         void Skip([MarshalAs(UnmanagedType.U4), In] int celt);
38 
Reset()39         void Reset();
40 
41         [return: MarshalAs(UnmanagedType.Interface)]
Clone()42         IEnumSetupInstances Clone();
43     }
44 
45     [Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
46     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
47     [ComImport]
48     public interface ISetupConfiguration
49     {
50     }
51 
52     [Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")]
53     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
54     [ComImport]
55     public interface ISetupConfiguration2 : ISetupConfiguration
56     {
57 
58         [return: MarshalAs(UnmanagedType.Interface)]
EnumInstances()59         IEnumSetupInstances EnumInstances();
60 
61         [return: MarshalAs(UnmanagedType.Interface)]
GetInstanceForCurrentProcess()62         ISetupInstance GetInstanceForCurrentProcess();
63 
64         [return: MarshalAs(UnmanagedType.Interface)]
GetInstanceForPath([MarshalAs(UnmanagedType.LPWStr), In] string path)65         ISetupInstance GetInstanceForPath([MarshalAs(UnmanagedType.LPWStr), In] string path);
66 
67         [return: MarshalAs(UnmanagedType.Interface)]
EnumAllInstances()68         IEnumSetupInstances EnumAllInstances();
69     }
70 
71     [Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")]
72     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
73     [ComImport]
74     public interface ISetupInstance
75     {
76     }
77 
78     [Guid("89143C9A-05AF-49B0-B717-72E218A2185C")]
79     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
80     [ComImport]
81     public interface ISetupInstance2 : ISetupInstance
82     {
83         [return: MarshalAs(UnmanagedType.BStr)]
GetInstanceId()84         string GetInstanceId();
85 
86         [return: MarshalAs(UnmanagedType.Struct)]
GetInstallDate()87         System.Runtime.InteropServices.ComTypes.FILETIME GetInstallDate();
88 
89         [return: MarshalAs(UnmanagedType.BStr)]
GetInstallationName()90         string GetInstallationName();
91 
92         [return: MarshalAs(UnmanagedType.BStr)]
GetInstallationPath()93         string GetInstallationPath();
94 
95         [return: MarshalAs(UnmanagedType.BStr)]
GetInstallationVersion()96         string GetInstallationVersion();
97 
98         [return: MarshalAs(UnmanagedType.BStr)]
GetDisplayName([MarshalAs(UnmanagedType.U4), In] int lcid)99         string GetDisplayName([MarshalAs(UnmanagedType.U4), In] int lcid);
100 
101         [return: MarshalAs(UnmanagedType.BStr)]
GetDescription([MarshalAs(UnmanagedType.U4), In] int lcid)102         string GetDescription([MarshalAs(UnmanagedType.U4), In] int lcid);
103 
104         [return: MarshalAs(UnmanagedType.BStr)]
ResolvePath([MarshalAs(UnmanagedType.LPWStr), In] string pwszRelativePath)105         string ResolvePath([MarshalAs(UnmanagedType.LPWStr), In] string pwszRelativePath);
106 
107         [return: MarshalAs(UnmanagedType.U4)]
GetState()108         InstanceState GetState();
109 
110         [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
GetPackages()111         ISetupPackageReference[] GetPackages();
112 
GetProduct()113         ISetupPackageReference GetProduct();
114 
115         [return: MarshalAs(UnmanagedType.BStr)]
GetProductPath()116         string GetProductPath();
117 
118         [return: MarshalAs(UnmanagedType.VariantBool)]
IsLaunchable()119         bool IsLaunchable();
120 
121         [return: MarshalAs(UnmanagedType.VariantBool)]
IsComplete()122         bool IsComplete();
123 
124         [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
GetProperties()125         ISetupPropertyStore GetProperties();
126 
127         [return: MarshalAs(UnmanagedType.BStr)]
GetEnginePath()128         string GetEnginePath();
129     }
130 
131     [Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")]
132     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
133     [ComImport]
134     public interface ISetupPackageReference
135     {
136 
137         [return: MarshalAs(UnmanagedType.BStr)]
GetId()138         string GetId();
139 
140         [return: MarshalAs(UnmanagedType.BStr)]
GetVersion()141         string GetVersion();
142 
143         [return: MarshalAs(UnmanagedType.BStr)]
GetChip()144         string GetChip();
145 
146         [return: MarshalAs(UnmanagedType.BStr)]
GetLanguage()147         string GetLanguage();
148 
149         [return: MarshalAs(UnmanagedType.BStr)]
GetBranch()150         string GetBranch();
151 
152         [return: MarshalAs(UnmanagedType.BStr)]
GetType()153         string GetType();
154 
155         [return: MarshalAs(UnmanagedType.BStr)]
GetUniqueId()156         string GetUniqueId();
157 
158         [return: MarshalAs(UnmanagedType.VariantBool)]
GetIsExtension()159         bool GetIsExtension();
160     }
161 
162     [Guid("c601c175-a3be-44bc-91f6-4568d230fc83")]
163     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
164     [ComImport]
165     public interface ISetupPropertyStore
166     {
167 
168         [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
GetNames()169         string[] GetNames();
170 
GetValue([MarshalAs(UnmanagedType.LPWStr), In] string pwszName)171         object GetValue([MarshalAs(UnmanagedType.LPWStr), In] string pwszName);
172     }
173 
174     [Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
175     [CoClass(typeof(SetupConfigurationClass))]
176     [ComImport]
177     public interface SetupConfiguration : ISetupConfiguration2, ISetupConfiguration
178     {
179     }
180 
181     [Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")]
182     [ClassInterface(ClassInterfaceType.None)]
183     [ComImport]
184     public class SetupConfigurationClass
185     {
186     }
187 
188     public static class Main
189     {
PrintJson()190         public static void PrintJson()
191         {
192             ISetupConfiguration query = new SetupConfiguration();
193             ISetupConfiguration2 query2 = (ISetupConfiguration2)query;
194             IEnumSetupInstances e = query2.EnumAllInstances();
195 
196             int pceltFetched;
197             ISetupInstance2[] rgelt = new ISetupInstance2[1];
198             List<string> instances = new List<string>();
199             while (true)
200             {
201                 e.Next(1, rgelt, out pceltFetched);
202                 if (pceltFetched <= 0)
203                 {
204                     Console.WriteLine(String.Format("[{0}]", string.Join(",", instances.ToArray())));
205                     return;
206                 }
207 
208                 try
209                 {
210                     instances.Add(InstanceJson(rgelt[0]));
211                 }
212                 catch (COMException)
213                 {
214                     // Ignore instances that can't be queried.
215                 }
216             }
217         }
218 
JsonString(string s)219         private static string JsonString(string s)
220         {
221             return "\"" + s.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"";
222         }
223 
InstanceJson(ISetupInstance2 setupInstance2)224         private static string InstanceJson(ISetupInstance2 setupInstance2)
225         {
226             // Visual Studio component directory:
227             // https://docs.microsoft.com/en-us/visualstudio/install/workload-and-component-ids
228 
229             StringBuilder json = new StringBuilder();
230             json.Append("{");
231 
232             string path = JsonString(setupInstance2.GetInstallationPath());
233             json.Append(String.Format("\"path\":{0},", path));
234 
235             string version = JsonString(setupInstance2.GetInstallationVersion());
236             json.Append(String.Format("\"version\":{0},", version));
237 
238             List<string> packages = new List<string>();
239             foreach (ISetupPackageReference package in setupInstance2.GetPackages())
240             {
241                 string id = JsonString(package.GetId());
242                 packages.Add(id);
243             }
244             json.Append(String.Format("\"packages\":[{0}]", string.Join(",", packages.ToArray())));
245 
246             json.Append("}");
247             return json.ToString();
248         }
249     }
250 }
251