File: RedistVersionInfo.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (121 lines) | stat: -rw-r--r-- 5,631 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//------------------------------------------------------------------------------
// <copyright file="RedistVersionInfo.cs" company="Microsoft">
// 
// <OWNER>[....]</OWNER>
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
//------------------------------------------------------------------------------

namespace System.CodeDom.Compiler {
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.CodeDom.Compiler;
    using System.Configuration;
    using System.Collections.Generic;

    using Microsoft.Win32;

    // The default compiler is the one corresponding to the current-running version of the runtime.
    // Customers can choose to use a different one by setting a provider option.
    internal static class RedistVersionInfo {

        // Version identifier added for Dev10.  Takes the full path, doesn't depend on registry key
        internal const String DirectoryPath = "CompilerDirectoryPath";  // location

        // Version identifier added for Orcas.  Depends on registry key.
        internal const String NameTag = "CompilerVersion";    // name of the tag for specifying the version

        internal const String DefaultVersion = InPlaceVersion;      // should match one of the versions below
        internal const String InPlaceVersion = "v4.0";        // Default
        internal const String RedistVersion  = "v3.5";        // May change with servicing 
        internal const String RedistVersion20= "v2.0";

        private const string MSBuildToolsPath = "MSBuildToolsPath";
        private const string dotNetFrameworkRegistryPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\";

        public static string GetCompilerPath(IDictionary<string, string> provOptions, string compilerExecutable) {

            // Get the location of the runtime, the usual answer
            string compPath = Executor.GetRuntimeInstallDirectory();

            // if provOptions is provided check to see if it alters what version we should bind to.
            // provOptions can be null if someone does new VB/CSCodeProvider(), in which case
            // they get the default behavior.
            if (provOptions != null) {

                string directoryPath;
                bool directoryPathPresent = provOptions.TryGetValue(DirectoryPath, out directoryPath);
                string versionVal;
                bool versionValPresent = provOptions.TryGetValue(NameTag, out versionVal);
                
                if(directoryPathPresent && versionValPresent)
                {
                    throw new InvalidOperationException(SR.GetString(SR.Cannot_Specify_Both_Compiler_Path_And_Version, DirectoryPath, NameTag));
                }
                
                // If they have an explicit path, use it.  Otherwise, look it up from the registry.
                if (directoryPathPresent) {
                    return directoryPath;
                }
                
                // If they have specified a version number in providerOptions, use it.
                if (versionValPresent) {
                    switch (versionVal) {

                        case RedistVersionInfo.InPlaceVersion:
                            // Use the RuntimeInstallDirectory, already obtained
                            break;

                        case RedistVersionInfo.RedistVersion:
                            // lock to the Orcas version, if it's not available throw (we'll throw at compile time)
                            compPath = GetCompilerPathFromRegistry(versionVal);
                            break;

                        case RedistVersionInfo.RedistVersion20:
                            //look up 2.0 compiler path from registry
                            compPath = GetCompilerPathFromRegistry(versionVal);
                            break;

                        default:
                            compPath = null;
                            break;
                    }
                }
            }

            if (compPath == null)
                throw new InvalidOperationException(SR.GetString(SR.CompilerNotFound, compilerExecutable));

            return compPath;
        }

        /// this method returns the location of the Orcas compilers, but will return whatever 
        /// version is requested via the COMPlus_ environment variables first
        private static string GetCompilerPathFromRegistry(String versionVal) {
            string dir = null;

            // if this is running in a private running environment such as Razzle, we would use the path
            // based on the environment variables: COMPLUS_InstallRoot and COMPLUS_Version.
            string comPlus_InstallRoot = Environment.GetEnvironmentVariable("COMPLUS_InstallRoot");
            string comPlus_Version = Environment.GetEnvironmentVariable("COMPLUS_Version");

            if (!string.IsNullOrEmpty(comPlus_InstallRoot) && !string.IsNullOrEmpty(comPlus_Version))
            {
                dir = Path.Combine(comPlus_InstallRoot, comPlus_Version);
                if (Directory.Exists(dir))
                    return dir;
            }

            String versionWithoutV = versionVal.Substring(1);
            String registryPath = dotNetFrameworkRegistryPath + versionWithoutV; 
            dir = Registry.GetValue(registryPath, MSBuildToolsPath, null) as string;

            if (dir != null && Directory.Exists(dir)) {
                return dir;
            }
            return null;
        }
    }
}