| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 | // Copyright 2017 - Refael Ackermann// Distributed under MIT style license// See accompanying file LICENSE at https://github.com/node4good/windows-autoconf// Usage:// powershell -ExecutionPolicy Unrestricted -Version "2.0" -Command "&{Add-Type -Path Find-VS2017.cs; [VisualStudioConfiguration.Main]::Query()}"using System;using System.Text;using System.Runtime.InteropServices;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 Query()        {            ISetupConfiguration query = new SetupConfiguration();            ISetupConfiguration2 query2 = (ISetupConfiguration2)query;            IEnumSetupInstances e = query2.EnumAllInstances();            int pceltFetched;            ISetupInstance2[] rgelt = new ISetupInstance2[1];            StringBuilder log = new StringBuilder();            while (true)            {                e.Next(1, rgelt, out pceltFetched);                if (pceltFetched <= 0)                {                    Console.WriteLine(String.Format("{{\"log\":\"{0}\"}}", log.ToString()));                    return;                }                if (CheckInstance(rgelt[0], ref log))                    return;            }        }        private static bool CheckInstance(ISetupInstance2 setupInstance2, ref StringBuilder log)        {            // Visual Studio Community 2017 component directory:            // https://www.visualstudio.com/en-us/productinfo/vs2017-install-product-Community.workloads            string path = setupInstance2.GetInstallationPath().Replace("\\", "\\\\");            log.Append(String.Format("Found installation at: {0}\\n", path));            bool hasMSBuild = false;            bool hasVCTools = false;            uint Win10SDKVer = 0;            bool hasWin8SDK = false;            foreach (ISetupPackageReference package in setupInstance2.GetPackages())            {                const string Win10SDKPrefix = "Microsoft.VisualStudio.Component.Windows10SDK.";                string id = package.GetId();                if (id == "Microsoft.VisualStudio.VC.MSBuild.Base")                    hasMSBuild = true;                else if (id == "Microsoft.VisualStudio.Component.VC.Tools.x86.x64")                    hasVCTools = true;                else if (id.StartsWith(Win10SDKPrefix)) {                    string[] parts = id.Substring(Win10SDKPrefix.Length).Split('.');                    if (parts.Length > 1 && parts[1] != "Desktop")                        continue;                    uint foundSdkVer;                    if (UInt32.TryParse(parts[0], out foundSdkVer))                        Win10SDKVer = Math.Max(Win10SDKVer, foundSdkVer);                } else if (id == "Microsoft.VisualStudio.Component.Windows81SDK")                    hasWin8SDK = true;                else                    continue;                log.Append(String.Format("  - Found {0}\\n", id));            }            if (!hasMSBuild)                log.Append("  - Missing Visual Studio C++ core features (Microsoft.VisualStudio.VC.MSBuild.Base)\\n");            if (!hasVCTools)                log.Append("  - Missing VC++ 2017 v141 toolset (x86,x64) (Microsoft.VisualStudio.Component.VC.Tools.x86.x64)\\n");            if ((Win10SDKVer == 0) && (!hasWin8SDK))                log.Append("  - Missing a Windows SDK (Microsoft.VisualStudio.Component.Windows10SDK.* or Microsoft.VisualStudio.Component.Windows81SDK)\\n");            if (hasMSBuild && hasVCTools)            {                if (Win10SDKVer > 0)                {                    log.Append("  - Using this installation with Windows 10 SDK"/*\\n*/);                    Console.WriteLine(String.Format("{{\"log\":\"{0}\",\"path\":\"{1}\",\"sdk\":\"10.0.{2}.0\"}}", log.ToString(), path, Win10SDKVer));                    return true;                }                else if (hasWin8SDK)                {                    log.Append("  - Using this installation with Windows 8.1 SDK"/*\\n*/);                    Console.WriteLine(String.Format("{{\"log\":\"{0}\",\"path\":\"{1}\",\"sdk\":\"8.1\"}}", log.ToString(), path));                    return true;                }            }            log.Append("  - Some required components are missing, not using this installation\\n");            return false;        }    }}
 |