1 //------------------------------------------------------------------------------
2 // <copyright file="RedistVersionInfo.cs" company="Microsoft">
4 // <OWNER>Microsoft</OWNER>
5 // Copyright (c) Microsoft Corporation. All rights reserved.
7 //------------------------------------------------------------------------------
9 namespace System
.CodeDom
.Compiler
{
11 using System
.Diagnostics
;
13 using System
.CodeDom
.Compiler
;
14 using System
.Configuration
;
15 using System
.Collections
.Generic
;
17 using Microsoft
.Win32
;
19 // The default compiler is the one corresponding to the current-running version of the runtime.
20 // Customers can choose to use a different one by setting a provider option.
21 internal static class RedistVersionInfo
{
23 // Version identifier added for Dev10. Takes the full path, doesn't depend on registry key
24 internal const String DirectoryPath
= "CompilerDirectoryPath"; // location
26 // Version identifier added for Orcas. Depends on registry key.
27 internal const String NameTag
= "CompilerVersion"; // name of the tag for specifying the version
29 internal const String DefaultVersion
= InPlaceVersion
; // should match one of the versions below
30 internal const String InPlaceVersion
= "v4.0"; // Default
31 internal const String RedistVersion
= "v3.5"; // May change with servicing
32 internal const String RedistVersion20
= "v2.0";
34 private const string MSBuildToolsPath
= "MSBuildToolsPath";
35 private const string dotNetFrameworkRegistryPath
= "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\";
37 public static string GetCompilerPath(IDictionary
<string, string> provOptions
, string compilerExecutable
) {
39 // Get the location of the runtime, the usual answer
40 string compPath
= Executor
.GetRuntimeInstallDirectory();
42 // if provOptions is provided check to see if it alters what version we should bind to.
43 // provOptions can be null if someone does new VB/CSCodeProvider(), in which case
44 // they get the default behavior.
45 if (provOptions
!= null) {
48 bool directoryPathPresent
= provOptions
.TryGetValue(DirectoryPath
, out directoryPath
);
50 bool versionValPresent
= provOptions
.TryGetValue(NameTag
, out versionVal
);
52 if(directoryPathPresent
&& versionValPresent
)
54 throw new InvalidOperationException(SR
.GetString(SR
.Cannot_Specify_Both_Compiler_Path_And_Version
, DirectoryPath
, NameTag
));
57 // If they have an explicit path, use it. Otherwise, look it up from the registry.
58 if (directoryPathPresent
) {
62 // If they have specified a version number in providerOptions, use it.
63 if (versionValPresent
) {
66 case RedistVersionInfo
.InPlaceVersion
:
67 // Use the RuntimeInstallDirectory, already obtained
70 case RedistVersionInfo
.RedistVersion
:
71 // lock to the Orcas version, if it's not available throw (we'll throw at compile time)
72 compPath
= GetCompilerPathFromRegistry(versionVal
);
75 case RedistVersionInfo
.RedistVersion20
:
76 //look up 2.0 compiler path from registry
77 compPath
= GetCompilerPathFromRegistry(versionVal
);
88 throw new InvalidOperationException(SR
.GetString(SR
.CompilerNotFound
, compilerExecutable
));
93 /// this method returns the location of the Orcas compilers, but will return whatever
94 /// version is requested via the COMPlus_ environment variables first
95 private static string GetCompilerPathFromRegistry(String versionVal
) {
98 // if this is running in a private running environment such as Razzle, we would use the path
99 // based on the environment variables: COMPLUS_InstallRoot and COMPLUS_Version.
100 string comPlus_InstallRoot
= Environment
.GetEnvironmentVariable("COMPLUS_InstallRoot");
101 string comPlus_Version
= Environment
.GetEnvironmentVariable("COMPLUS_Version");
103 if (!string.IsNullOrEmpty(comPlus_InstallRoot
) && !string.IsNullOrEmpty(comPlus_Version
))
105 dir
= Path
.Combine(comPlus_InstallRoot
, comPlus_Version
);
106 if (Directory
.Exists(dir
))
110 String versionWithoutV
= versionVal
.Substring(1);
111 String registryPath
= dotNetFrameworkRegistryPath
+ versionWithoutV
;
112 dir
= Registry
.GetValue(registryPath
, MSBuildToolsPath
, null) as string;
114 if (dir
!= null && Directory
.Exists(dir
)) {