diff --git a/.gitignore b/.gitignore
index fc86a341..162ebdbf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,6 @@ autom4te.cache
missing
*Makefile
*Makefile.in
-*.dll
*.exe
bin/
*.userprefs
diff --git a/deps/vs2017/Microsoft.VisualStudio.Setup.Configuration.Interop.dll b/deps/vs2017/Microsoft.VisualStudio.Setup.Configuration.Interop.dll
new file mode 100644
index 00000000..9c0fc33b
Binary files /dev/null and b/deps/vs2017/Microsoft.VisualStudio.Setup.Configuration.Interop.dll differ
diff --git a/deps/vs2017/Microsoft.VisualStudio.Setup.Configuration.Interop.xml b/deps/vs2017/Microsoft.VisualStudio.Setup.Configuration.Interop.xml
new file mode 100644
index 00000000..5d922347
--- /dev/null
+++ b/deps/vs2017/Microsoft.VisualStudio.Setup.Configuration.Interop.xml
@@ -0,0 +1,485 @@
+
+
+
+ Microsoft.VisualStudio.Setup.Configuration.Interop
+
+
+
+
+ A enumerator of installed objects.
+
+
+
+
+ Retrieves the next set of product instances in the enumeration sequence.
+
+ The number of product instances to retrieve.
+ A pointer to an array of .
+ A pointer to the number of product instances retrieved. If celt is 1 this parameter may be NULL.
+
+
+
+ Skips the next set of product instances in the enumeration sequence.
+
+ The number of product instances to skip.
+
+
+
+ Resets the enumeration sequence to the beginning.
+
+
+
+
+ Creates a new enumeration object in the same state as the current enumeration object: the new object points to the same place in the enumeration sequence.
+
+ A pointer to a pointer to a new interface. If the method fails, this parameter is undefined.
+
+
+
+ The state of an .
+
+
+
+
+ The instance state has not been determined.
+
+
+
+
+ The instance installation path exists.
+
+
+
+
+ A product is registered to the instance.
+
+
+
+
+ No reboot is required for the instance.
+
+
+
+
+ No errors were reported for the instance.
+
+
+
+
+ The instance represents a complete install.
+
+
+
+
+ Gets information about product instances set up on the machine.
+
+
+
+
+ Enumerates all completed product instances installed.
+
+ An enumeration of installed product instances.
+
+
+
+ Gets the instance for the current process path.
+
+ The instance for the current process path.
+
+
+
+ Gets the instance for the given path.
+
+ Path used to determine instance
+ The instance for the given path.
+
+
+
+ Enumerates all product instances.
+
+ An enumeration of all product instances.
+
+
+
+ Gets information about product instances set up on the machine.
+
+
+
+
+ Enumerates all product instances installed.
+
+ An enumeration of installed product instances.
+
+
+
+ Gets the instance for the current process path.
+
+ The instance for the current process path.
+
+
+
+ Gets the instance for the given path.
+
+ Path used to determine instance
+ The instance for the given path.
+
+
+
+ Information about the error state of the instance.
+
+
+
+
+ Gets an array of failed package references.
+
+ An array of failed package references.
+
+
+
+ Gets an array of skipped package references.
+
+ An array of skipped package references.
+
+
+
+ A reference to a failed package.
+
+
+ You can enumerate all properties of basic types by casting to an .
+
+
+
+
+ Gets the general package identifier.
+
+ The general package identifier.
+
+
+
+ Gets the version of the package.
+
+ The version of the package.
+
+
+
+ Gets the target process architecture of the package.
+
+ The target process architecture of the package.
+
+
+
+ Gets the language and optional region identifier.
+
+ The language and optional region identifier.
+
+
+
+ Gets the build branch of the package.
+
+ The build branch of the package.
+
+
+
+ Gets the type of the package.
+
+ The type of the package.
+
+
+
+ Gets the unique identifier consisting of all defined tokens.
+
+ The unique identifier consisting of all defined tokens.
+
+
+
+ Gets a value indicating whether the package refers to an external extension.
+
+ A value indicating whether the package refers to an external extension.
+
+
+
+ Helper functions.
+
+
+
+
+ Parses a dotted quad version string into a 64-bit unsigned integer.
+
+ The dotted quad version string to parse, e.g. 1.2.3.4.
+ A 64-bit unsigned integer representing the version. You can compare this to other versions.
+
+
+
+ Parses a dotted quad version string into a 64-bit unsigned integer.
+
+ The string containing 1 or 2 dotted quad version strings to parse, e.g. [1.0,) that means 1.0.0.0 or newer.
+ A 64-bit unsigned integer representing the minimum version, which may be 0. You can compare this to other versions.
+ A 64-bit unsigned integer representing the maximum version, which may be MAXULONGLONG. You can compare this to other versions.
+
+
+
+ Information about an instance of a product.
+
+
+ You can enumerate all properties of basic types by casting to an .
+
+
+
+
+ Gets the instance identifier (should match the name of the parent instance directory).
+
+ The instance identifier.
+
+
+
+ Gets the local date and time when the installation was originally installed.
+
+ The local date and time when the installation was originally installed.
+
+
+
+ Gets the unique name of the installation, often indicating the branch and other information used for telemetry.
+
+ The unique name of the installation, often indicating the branch and other information used for telemetry.
+
+
+
+ Gets the path to the installation root of the product.
+
+ The path to the installation root of the product.
+
+
+
+ Gets the version of the product installed in this instance.
+
+ The version of the product installed in this instance.
+
+
+
+ Gets the display name (title) of the product installed in this instance.
+
+ The LCID for the display name.
+ The display name (title) of the product installed in this instance.
+
+
+
+ Gets the description of the product installed in this instance.
+
+ The LCID for the description.
+ The description of the product installed in this instance.
+
+
+
+ Resolves the optional relative path to the root path of the instance.
+
+ A relative path within the instance to resolve, or NULL to get the root path.
+ The full path to the optional relative path within the instance. If the relative path is NULL, the root path will always terminate in a backslash.
+
+
+
+ Gets the state of the instance.
+
+ The state of the instance.
+
+
+
+ Gets an array of package references registered to the instance.
+
+ An array of package references registered to the instance.
+
+
+
+ Gets a package reference to the product registered to the instance
+
+ A package reference to the product registered to the instance. This may be null if does not return .
+
+
+
+ Gets the relative path to the product application, if available.
+
+ The relative path to the product application, if available.
+
+
+
+ Gets the error state of the instance, if available.
+
+ The error state of the instance, if available.
+
+
+
+ Gets a value indicating whether the instance can be launched.
+
+ Whether the instance can be launched.
+
+ An instance could have had errors during install but still be launched. Some features may not work correctly, but others will.
+
+
+
+
+ Gets a value indicating whether the instance is complete.
+
+ Whether the instance is complete.
+
+ An instance is complete if it had no errors during install, resume, or repair.
+
+
+
+
+ Gets product-specific properties.
+
+ An of product-specific properties, or null if no properties are defined.
+
+
+
+ Gets the directory path to the setup engine that installed the instance.
+
+ The directory path to the setup engine that installed the instance.
+
+
+
+ Information about an instance of a product.
+
+
+ You can enumerate all properties of basic types by casting to an .
+
+
+
+
+ Gets the instance identifier (should match the name of the parent instance directory).
+
+ The instance identifier.
+
+
+
+ Gets the local date and time when the installation was originally installed.
+
+ The local date and time when the installation was originally installed.
+
+
+
+ Gets the unique name of the installation, often indicating the branch and other information used for telemetry.
+
+ The unique name of the installation, often indicating the branch and other information used for telemetry.
+
+
+
+ Gets the path to the installation root of the product.
+
+ The path to the installation root of the product.
+
+
+
+ Gets the version of the product installed in this instance.
+
+ The version of the product installed in this instance.
+
+
+
+ Gets the display name (title) of the product installed in this instance.
+
+ The LCID for the display name.
+ The display name (title) of the product installed in this instance.
+
+
+
+ Gets the description of the product installed in this instance.
+
+ The LCID for the description.
+ The description of the product installed in this instance.
+
+
+
+ Resolves the optional relative path to the root path of the instance.
+
+ A relative path within the instance to resolve, or NULL to get the root path.
+ The full path to the optional relative path within the instance. If the relative path is NULL, the root path will always terminate in a backslash.
+
+
+
+ A reference to a package.
+
+
+ You can enumerate all properties of basic types by casting to an .
+
+
+
+
+ Gets the general package identifier.
+
+ The general package identifier.
+
+
+
+ Gets the version of the package.
+
+ The version of the package.
+
+
+
+ Gets the target process architecture of the package.
+
+ The target process architecture of the package.
+
+
+
+ Gets the language and optional region identifier.
+
+ The language and optional region identifier.
+
+
+
+ Gets the build branch of the package.
+
+ The build branch of the package.
+
+
+
+ Gets the type of the package.
+
+ The type of the package.
+
+
+
+ Gets the unique identifier consisting of all defined tokens.
+
+ The unique identifier consisting of all defined tokens.
+
+
+
+ Gets a value indicating whether the package refers to an external extension.
+
+ A value indicating whether the package refers to an external extension.
+
+
+
+ Provides named properties.
+
+
+ You can get this from an , , or derivative.
+
+
+
+
+ Gets an array of property names in this property store.
+
+ An array of property names in this property store.
+
+
+
+ Gets the value of a named property in this property store.
+
+ The name of the property to get.
+ The value of the property.
+
+
+
+ The implementation of .
+
+
+
+
+ Class that implements .
+
+
+
+
diff --git a/src/Core/Toolchains/MSVCToolchain.cs b/src/Core/Toolchains/MSVCToolchain.cs
index 35ad456d..fe59dae6 100644
--- a/src/Core/Toolchains/MSVCToolchain.cs
+++ b/src/Core/Toolchains/MSVCToolchain.cs
@@ -5,28 +5,31 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Win32;
+using Microsoft.VisualStudio.Setup.Configuration;
+using System.Runtime.InteropServices;
namespace CppSharp
{
- /// Represents a Visual Studio version.
+ /// Represents a Visual Studio version.
public enum VisualStudioVersion
{
VS2012 = 11,
VS2013 = 12,
VS2015 = 14,
+ VS2017 = 15,
Latest,
}
- /// Represents a toolchain with associated version and directory.
+ /// Represents a toolchain with associated version and directory.
public struct ToolchainVersion
{
- /// Version of the toolchain.
+ /// Version of the toolchain.
public float Version;
- /// Directory location of the toolchain.
+ /// Directory location of the toolchain.
public string Directory;
- /// Extra data value associated with the toolchain.
+ /// Extra data value associated with the toolchain.
public string Value;
public override string ToString()
@@ -35,6 +38,17 @@ namespace CppSharp
}
}
+ ///
+ /// Describes the major and minor version of something.
+ /// Each version must be at least non negative and smaller than 100
+ ///
+ public struct Version
+ {
+ public int Major;
+
+ public int Minor;
+ }
+
public static class MSVCToolchain
{
static void DumpSdks(string sku, IEnumerable sdks)
@@ -44,7 +58,7 @@ namespace CppSharp
Console.WriteLine("\t({0}) {1}", sdk.Version, sdk.Directory);
}
- /// Dumps the detected SDK versions.
+ /// Dumps the detected SDK versions.
public static void DumpSdks()
{
List vsSdks;
@@ -68,7 +82,7 @@ namespace CppSharp
DumpSdks("MSBuild", msbuildSdks);
}
- /// Dumps include directories for selected toolchain.
+ /// Dumps include directories for selected toolchain.
public static void DumpSdkIncludes(VisualStudioVersion vsVersion =
VisualStudioVersion.Latest)
{
@@ -78,20 +92,23 @@ namespace CppSharp
Console.WriteLine("\t{0}", include);
}
- public static int GetCLVersion(VisualStudioVersion vsVersion)
+ public static Version GetCLVersion(VisualStudioVersion vsVersion)
{
- int clVersion;
+ Version clVersion;
switch (vsVersion)
{
case VisualStudioVersion.VS2012:
- clVersion = 17;
+ clVersion = new Version { Major = 17, Minor = 0};
break;
case VisualStudioVersion.VS2013:
- clVersion = 18;
+ clVersion = new Version { Major = 18, Minor = 0 };
break;
case VisualStudioVersion.VS2015:
+ clVersion = new Version { Major = 19, Minor = 0 };
+ break;
+ case VisualStudioVersion.VS2017:
case VisualStudioVersion.Latest:
- clVersion = 19;
+ clVersion = new Version { Major = 19, Minor = 10 };
break;
default:
throw new Exception("Unknown Visual Studio version");
@@ -109,8 +126,10 @@ namespace CppSharp
case VisualStudioVersion.VS2013:
return 12;
case VisualStudioVersion.VS2015:
- case VisualStudioVersion.Latest:
return 14;
+ case VisualStudioVersion.VS2017:
+ case VisualStudioVersion.Latest:
+ return 15;
default:
throw new Exception("Unknown Visual Studio version");
}
@@ -163,30 +182,30 @@ namespace CppSharp
var windowsKitSdk = (!string.IsNullOrWhiteSpace(kitsRootKey))
? windowsKitsSdks.Find(version => version.Value == kitsRootKey)
: windowsKitsSdks.Last();
-
// If for some reason we cannot find the SDK version reported by VS
// in the system, then fallback to the latest version found.
if (windowsKitSdk.Value == null)
- windowsKitSdk = windowsKitsSdks.Last();
-
+ windowsKitSdk = windowsKitsSdks.Last();
return windowsKitSdk;
}
-
/// Gets the system include folders for the given Visual Studio version.
public static List GetSystemIncludes(VisualStudioVersion vsVersion)
{
var vsSdk = GetVSToolchain(vsVersion);
- int windowsSdkMajorVer;
- var windowsKitSdk = GetWindowsKitsToolchain(vsVersion, out windowsSdkMajorVer);
-
var vsDir = vsSdk.Directory;
vsDir = vsDir.Substring(0, vsDir.LastIndexOf(@"\Common7\IDE",
StringComparison.Ordinal));
var includes = new List();
+ if(vsVersion == VisualStudioVersion.VS2017 ||
+ vsVersion == VisualStudioVersion.Latest)
+ return GetSystemIncludesVS2017(vsDir);
includes.Add(Path.Combine(vsDir, @"VC\include"));
+ int windowsSdkMajorVer;
+ var windowsKitSdk = GetWindowsKitsToolchain(vsVersion, out windowsSdkMajorVer);
+
List windowsSdks;
GetWindowsSdks(out windowsSdks);
@@ -283,7 +302,11 @@ namespace CppSharp
return includes;
}
+ ///
/// Gets .NET framework installation directories.
+ ///
+ /// Collection holding information about available .Net-framework-sdks
+ /// Success of the operation
public static bool GetNetFrameworkSdks(out List versions)
{
versions = new List();
@@ -304,7 +327,11 @@ namespace CppSharp
return versions.Count != 0;
}
+ ///
/// Gets MSBuild installation directories.
+ ///
+ /// Collection holding information about available ms-build-sdks
+ /// Success of the operation
public static bool GetMSBuildSdks(out List versions)
{
versions = new List();
@@ -325,7 +352,11 @@ namespace CppSharp
return versions.Count != 0;
}
+ ///
/// Gets Windows SDK installation directories.
+ ///
+ /// Collection holding information about available windows-sdks
+ /// Success of the operation
public static bool GetWindowsSdks(out List versions)
{
versions = new List();
@@ -339,14 +370,16 @@ namespace CppSharp
GetToolchainsFromSystemRegistry(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows",
"InstallationFolder", versions, RegistryView.Registry64);
- }
-
+ }
versions.Sort((v1, v2) => (int)(v1.Version - v2.Version));
-
return versions.Count != 0;
}
+ ///
/// Gets Windows Kits SDK installation directories.
+ ///
+ /// Collection holding information about available WindowsKitsSdks
+ /// Success of the operation
public static bool GetWindowsKitsSdks(out List versions)
{
versions = new List();
@@ -367,7 +400,11 @@ namespace CppSharp
return true;
}
+ ///
/// Gets Visual Studio installation directories.
+ ///
+ /// Collection holding information about available Visual Studio instances
+ /// Success of the operation
public static bool GetVisualStudioSdks(out List versions)
{
versions = new List();
@@ -394,8 +431,10 @@ namespace CppSharp
"InstallDir", versions, RegistryView.Registry64);
}
- versions.Sort((v1, v2) => (int)(v1.Version - v2.Version));
+ //Check for VS 2017
+ GetVs2017Instances(versions);
+ versions.Sort((v1, v2) => (int)(v1.Version - v2.Version));
return true;
}
@@ -539,5 +578,147 @@ namespace CppSharp
return hive;
}
+
+#region VS2017
+
+ ///
+ /// Returns all system includes of the installed VS 2017 instance.
+ ///
+ /// Path to the visual studio installation (for identifying the correct instance)
+ /// The system includes
+ private static List GetSystemIncludesVS2017(string vsDir)
+ {
+ List includes = new List();
+ //They includes are in a different folder
+ const int REGDB_E_CLASSNOTREG = unchecked((int)0x80040154);
+ try
+ {
+ var query = new SetupConfiguration();
+ var query2 = (ISetupConfiguration2)query;
+ var e = query2.EnumAllInstances();
+
+ var helper = (ISetupHelper)query;
+
+ int fetched;
+ var instances = new ISetupInstance[1];
+ do
+ {
+ e.Next(1, instances, out fetched);
+ if (fetched > 0)
+ {
+ var instance = (ISetupInstance2)instances[0];
+ if (instance.GetInstallationPath() != vsDir) continue;
+ var packages = instance.GetPackages();
+ var vc_tools = from package in packages
+ where package.GetId().Contains("Microsoft.VisualStudio.Component.VC.Tools")
+ orderby package.GetId()
+ select package;
+ if (vc_tools.Count() > 0)
+ { // Tools found, get path
+ var path = instance.GetInstallationPath();
+ var versionFilePath = path + @"\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt";
+ var version = System.IO.File.ReadLines(versionFilePath).ElementAt(0).Trim();
+ includes.Add(path + @"\VC\Tools\MSVC\" + version + @"\include");
+ includes.Add(path + @"\VC\Tools\MSVC\" + version + @"\atlmfc\include");
+ }
+ var sdks = from package in packages
+ where package.GetId().Contains("Windows10SDK") || package.GetId().Contains("Windows81SDK") || package.GetId().Contains("Win10SDK_10")
+ select package;
+ var win10sdks = from sdk in sdks
+ where sdk.GetId().Contains("Windows10SDK")
+ select sdk;
+ var win8sdks = from sdk in sdks
+ where sdk.GetId().Contains("Windows81SDK")
+ select sdk;
+ if (win10sdks.Count() > 0)
+ {
+ var sdk = win10sdks.Last();
+ var path = @"C:\Program Files (x86)\Windows Kits\10\include\" + "10.0." + sdk.GetId().Substring(46) + ".0"; //Microsoft.VisualStudio.Component.Windows10SDK. = 46 chars
+ var shared = Path.Combine(path, "shared");
+ var um = Path.Combine(path, "um");
+ var winrt = Path.Combine(path, "winrt");
+ var ucrt = Path.Combine(path, "ucrt");
+ Console.WriteLine(path);
+ if (Directory.Exists(shared) &&
+ Directory.Exists(um) &&
+ Directory.Exists(winrt) &&
+ Directory.Exists(ucrt))
+ {
+ includes.Add(shared);
+ includes.Add(um);
+ includes.Add(winrt);
+ includes.Add(ucrt);
+ }
+ }
+ else if (win8sdks.Count() > 0)
+ {
+ includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\shared");
+ includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\um");
+ includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\winrt");
+ }
+
+ return includes; //We've collected all information.
+ }
+
+ }
+ while (fetched > 0);
+ }
+ catch (COMException ex) when (ex.HResult == REGDB_E_CLASSNOTREG)
+ {
+ Console.WriteLine("The query API is not registered. Assuming no instances are installed.");
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error 0x{ex.HResult:x8}: {ex.Message}");
+ }
+ return includes;
+ }
+
+ ///
+ /// Tries to get all vs 2017 instances.
+ ///
+ /// Collection holding available visual studio instances
+ /// Success of the operation
+ private static bool GetVs2017Instances(ICollection versions)
+ {
+ const int REGDB_E_CLASSNOTREG = unchecked((int)0x80040154);
+ try
+ {
+ var query = new SetupConfiguration();
+ var query2 = (ISetupConfiguration2)query;
+ var e = query2.EnumAllInstances();
+ int fetched;
+ var instances = new ISetupInstance[1];
+ do
+ {
+ e.Next(1, instances, out fetched);
+ if (fetched > 0)
+ {
+ var instance = (ISetupInstance2)instances[0];
+ var packages = instance.GetPackages();
+ var toolchain = new ToolchainVersion
+ {
+ Directory = instance.GetInstallationPath() + @"\Common7\IDE",
+ Version = Single.Parse(instance.GetInstallationVersion().Remove(2)),
+ Value = null // Not used currently
+ };
+ versions.Add(toolchain);
+ }
+ }
+ while (fetched > 0);
+ }
+ catch (COMException ex) when (ex.HResult == REGDB_E_CLASSNOTREG)
+ {
+ Console.WriteLine("The query API is not registered. Assuming no instances are installed.");
+ return false;
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error 0x{ex.HResult:x8}: {ex.Message}");
+ return false;
+ }
+ return true;
+ }
+#endregion
}
}
diff --git a/src/Core/premake5.lua b/src/Core/premake5.lua
index 8e38a678..78c6899e 100644
--- a/src/Core/premake5.lua
+++ b/src/Core/premake5.lua
@@ -8,9 +8,12 @@ project "CppSharp"
files { "**.cs" }
vpaths { ["*"] = "*" }
-
+
+ libdirs{ depsdir .."/vs2017" }
+
links
{
"System",
"System.Core",
+ "Microsoft.VisualStudio.Setup.Configuration.Interop"
}
diff --git a/src/Parser/ParserOptions.cs b/src/Parser/ParserOptions.cs
index 04c774e9..bb331db7 100644
--- a/src/Parser/ParserOptions.cs
+++ b/src/Parser/ParserOptions.cs
@@ -20,7 +20,8 @@ namespace CppSharp.Parser
NoBuiltinIncludes = true;
NoStandardIncludes = true;
Abi = CppAbi.Microsoft;
- ToolSetToUse = MSVCToolchain.GetCLVersion(vsVersion) * 10000000;
+ var clVersion = MSVCToolchain.GetCLVersion(vsVersion);
+ ToolSetToUse = clVersion.Major * 10000000 + clVersion.Minor * 100000;
AddArguments("-fms-extensions");
AddArguments("-fms-compatibility");