/// <summary> /// Given a filename (currently only Tracker.exe and FileTracker.dll are supported), return /// the path to that file. /// </summary> /// <param name="filename"></param> /// <param name="bitness"></param> /// <returns></returns> private static string GetPath(string filename, DotNetFrameworkArchitecture bitness) { // Make sure that if someone starts passing the wrong thing to this method we don't silently // eat it and do something possibly unexpected. ErrorUtilities.VerifyThrow( s_TrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase) || s_FileTrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase), "This method should only be passed s_TrackerFilename or s_FileTrackerFilename, but was passed {0} instead!", filename ); // Look for FileTracker.dll/Tracker.exe in the MSBuild tools directory. They may exist elsewhere on disk, // but other copies aren't guaranteed to be compatible with the latest. var path = ToolLocationHelper.GetPathToBuildToolsFile(filename, ToolLocationHelper.CurrentToolsVersion, bitness); // Due to a Detours limitation, the path to FileTracker32.dll must be // representable in ANSI characters. Look for it first in the global // shared location which is guaranteed to be ANSI. Fall back to // current folder. if (s_FileTrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase)) { string progfilesPath = Path.Combine(FrameworkLocationHelper.GenerateProgramFiles32(), "MSBuild", "15.0", "FileTracker", s_FileTrackerFilename); if (FileSystems.Default.FileExists(progfilesPath)) { return(progfilesPath); } } return(path); }
internal static string GetPathToDotNetFrameworkV40(DotNetFrameworkArchitecture architecture) { switch (architecture) { case DotNetFrameworkArchitecture.Current: if (pathToCurrentDotNetFrameworkV40 == null) { break; } return(pathToCurrentDotNetFrameworkV40); case DotNetFrameworkArchitecture.Bitness32: if (pathToDotNetFramework32V40 == null) { break; } return(pathToDotNetFramework32V40); case DotNetFrameworkArchitecture.Bitness64: if (pathToDotNetFramework64V40 == null) { break; } return(pathToDotNetFramework64V40); default: ErrorUtilities.ThrowInternalErrorUnreachable(); return(null); } if (CheckForFrameworkInstallation(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full", "Install")) { string str = FindDotNetFrameworkPath(Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName), "v4.0", "v4.0", directoryExists, getDirectories, architecture, true); if ((str != null) && !File.Exists(Path.Combine(str, "msbuild.exe"))) { str = null; } switch (architecture) { case DotNetFrameworkArchitecture.Current: pathToCurrentDotNetFrameworkV40 = str; return(str); case DotNetFrameworkArchitecture.Bitness32: pathToDotNetFramework32V40 = str; return(str); case DotNetFrameworkArchitecture.Bitness64: pathToDotNetFramework64V40 = str; return(str); } ErrorUtilities.ThrowInternalErrorUnreachable(); } return(null); }
internal static string GetPathToDotNetFrameworkV11(DotNetFrameworkArchitecture architecture) { switch (architecture) { case DotNetFrameworkArchitecture.Current: if (pathToCurrentDotNetFrameworkV11 == null) { break; } return(pathToCurrentDotNetFrameworkV11); case DotNetFrameworkArchitecture.Bitness32: if (pathToDotNetFramework32V11 == null) { break; } return(pathToDotNetFramework32V11); case DotNetFrameworkArchitecture.Bitness64: if (pathToDotNetFramework64V11 == null) { break; } return(pathToDotNetFramework64V11); default: ErrorUtilities.ThrowInternalErrorUnreachable(); return(null); } if (CheckForFrameworkInstallation(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v1.1.4322", "Install")) { string str = FindDotNetFrameworkPath(Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName), "v1.1", "v1.1.4322", directoryExists, getDirectories, architecture, false); switch (architecture) { case DotNetFrameworkArchitecture.Current: pathToCurrentDotNetFrameworkV11 = str; return(str); case DotNetFrameworkArchitecture.Bitness32: pathToDotNetFramework32V11 = str; return(str); case DotNetFrameworkArchitecture.Bitness64: pathToDotNetFramework64V11 = str; return(str); } ErrorUtilities.ThrowInternalErrorUnreachable(); } return(null); }
public static bool TryParsePlatform(string architecture, out DotNetFrameworkArchitecture frameworkArchitecture) { if (string.IsNullOrWhiteSpace(architecture)) { throw new ArgumentNullException(nameof(architecture)); } string svalue = string.Format( "Bitness{0}", architecture.ToLower().Replace("v", string.Empty).Replace(".", string.Empty) ); return(Enum.TryParse <DotNetFrameworkArchitecture>(svalue, out frameworkArchitecture)); }
/// <summary> /// Given a filename (currently only Tracker.exe and FileTracker.dll are supported), return /// the path to that file. /// </summary> /// <param name="filename"></param> /// <param name="bitness"></param> /// <returns></returns> private static string GetPath(string filename, DotNetFrameworkArchitecture bitness) { // Make sure that if someone starts passing the wrong thing to this method we don't silently // eat it and do something possibly unexpected. ErrorUtilities.VerifyThrow( s_TrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase) || s_FileTrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase), "This method should only be passed s_TrackerFilename or s_FileTrackerFilename, but was passed {0} instead!", filename ); // Look for FileTracker.dll/Tracker.exe in the MSBuild tools directory. They may exist elsewhere on disk, // but other copies aren't guaranteed to be compatible with the latest. return(ToolLocationHelper.GetPathToBuildToolsFile(filename, ToolLocationHelper.CurrentToolsVersion, bitness)); }
public static string GetFrameworkPath(this Project project) { var targetPlatform = project.ConfigurationManager.ActiveConfiguration.Properties.Item("PlatformTarget").Value as string; int targetFramework = Convert.ToInt32(project.Properties.Item("TargetFramework").Value); TargetDotNetFrameworkVersion version = TargetDotNetFrameworkVersion.Version40; switch (targetFramework) { case Fx40: version = TargetDotNetFrameworkVersion.Version40; break; case Fx35: version = TargetDotNetFrameworkVersion.Version35; break; case Fx30: version = TargetDotNetFrameworkVersion.Version30; break; case Fx20: version = TargetDotNetFrameworkVersion.Version20; break; } DotNetFrameworkArchitecture arch = DotNetFrameworkArchitecture.Bitness32; if (targetPlatform == "AnyCpu") { arch = DotNetFrameworkArchitecture.Current; } if (targetPlatform == "x64") { arch = DotNetFrameworkArchitecture.Bitness64; } return(ToolLocationHelper.GetPathToDotNetFramework(version, arch)); }
/// <summary> /// Given a filename (currently only Tracker.exe and FileTracker.dll are supported), return /// the path to that file. /// </summary> /// <param name="filename"></param> /// <param name="bitness"></param> /// <returns></returns> private static string GetPath(string filename, DotNetFrameworkArchitecture bitness) { string trackerPath; // Make sure that if someone starts passing the wrong thing to this method we don't silently // eat it and do something possibly unexpected. ErrorUtilities.VerifyThrow( s_TrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase) || s_FileTrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase), "This method should only be passed s_TrackerFilename or s_FileTrackerFilename, but was passed {0} instead!", filename ); // Look for FileTracker.dll/FileTracker.exe first in the MSBuild tools directory, then fall back to .NET framework directory // and finally to .NET SDK directories. trackerPath = ToolLocationHelper.GetPathToBuildToolsFile(filename, ToolLocationHelper.CurrentToolsVersion, bitness); if (String.IsNullOrEmpty(trackerPath)) { trackerPath = ToolLocationHelper.GetPathToDotNetFrameworkFile(filename, TargetDotNetFrameworkVersion.VersionLatest, bitness); if ((String.IsNullOrEmpty(trackerPath) || !File.Exists(trackerPath)) && s_TrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase)) { // fall back to looking in the SDK directory -- this is where Tracker.exe will be in the typical VS case. First check // in the SDK for the latest target framework and latest Visual Studio version, since we want to make sure that we get // the most up-to-date version of FileTracker. trackerPath = ToolLocationHelper.GetPathToDotNetFrameworkSdkFile(filename, TargetDotNetFrameworkVersion.Version45, VisualStudioVersion.VersionLatest, bitness); // If that didn't work, we may be in a scenario where, e.g., we have VS 10 on Windows 8, which comes with .NET 4.5 // pre-installed. In which case, the Dev11 (or other "latest" SDK) may not exist, but the Dev10 SDK might. Check // for that here. if (trackerPath == null) { trackerPath = ToolLocationHelper.GetPathToDotNetFrameworkSdkFile(filename, TargetDotNetFrameworkVersion.Version40, bitness); } } } return(trackerPath); }
internal static string GetPathToDotNetFramework(Version version, DotNetFrameworkArchitecture architecture) { string str = version.Major + "." + version.Minor; switch (str) { case "1.1": return(GetPathToDotNetFrameworkV11(architecture)); case "2.0": return(GetPathToDotNetFrameworkV20(architecture)); case "3.0": return(GetPathToDotNetFrameworkV30(architecture)); case "3.5": return(GetPathToDotNetFrameworkV35(architecture)); case "4.0": return(GetPathToDotNetFrameworkV40(architecture)); } ErrorUtilities.ThrowArgument("FrameworkLocationHelper.UnsupportedFrameworkVersion", new object[] { str }); return(null); }
internal static string GetPathToDotNetFrameworkV45(DotNetFrameworkArchitecture architecture) { return GetPathToDotNetFramework(dotNetFrameworkVersion45, architecture); }
/// <summary> /// Given a ToolsVersion, find the path to the build tools folder for that ToolsVersion. /// </summary> /// <param name="toolsVersion">The ToolsVersion to look up</param> /// <param name="architecture">Target build tools architecture.</param> /// <returns>The path to the build tools folder for that ToolsVersion, if it exists, or /// null otherwise</returns> internal static string GeneratePathToBuildToolsForToolsVersion(string toolsVersion, DotNetFrameworkArchitecture architecture) { if (string.Compare(toolsVersion, MSBuildConstants.CurrentToolsVersion, StringComparison.Ordinal) == 0) { return GetPathToBuildToolsFromEnvironment(architecture); } // If we're not looking for the current tools version, try the registry. var toolsPath = GetPathToBuildToolsFromRegistry(toolsVersion, architecture); // If all else fails, always use the current environment. return toolsPath ?? GetPathToBuildToolsFromEnvironment(architecture); }
/// <summary> /// Look up the path to the build tools directory in the registry for the requested ToolsVersion and requested architecture /// </summary> private static string GetPathToBuildToolsFromRegistry(string toolsVersion, DotNetFrameworkArchitecture architecture) { string toolsVersionSpecificKey = ToolsVersionsRegistryPath + "\\" + toolsVersion; RegistryView view = RegistryView.Default; switch (architecture) { case DotNetFrameworkArchitecture.Bitness32: view = RegistryView.Registry32; break; case DotNetFrameworkArchitecture.Bitness64: view = RegistryView.Registry64; break; case DotNetFrameworkArchitecture.Current: view = RegistryView.Default; break; } string toolsPath = FindRegistryValueUnderKey(toolsVersionSpecificKey, MSBuildConstants.ToolsPath, view); return toolsPath; }
/// <summary> /// Look up the path to the build tools directory for the requested ToolsVersion in the .exe.config file of this executable /// </summary> private static string GetPathToBuildToolsFromConfig(string toolsVersion, DotNetFrameworkArchitecture architecture) { string toolPath = null; if (ToolsetConfigurationReaderHelpers.ConfigurationFileMayHaveToolsets()) { string toolsPathPropertyName = architecture == DotNetFrameworkArchitecture.Bitness64 ? MSBuildConstants.ToolsPath64 : MSBuildConstants.ToolsPath; try { Configuration configuration = ReadApplicationConfiguration(); ToolsetConfigurationSection configurationSection = ToolsetConfigurationReaderHelpers.ReadToolsetConfigurationSection(configuration); ToolsetElement toolset = configurationSection?.Toolsets.GetElement(toolsVersion); PropertyElement toolsPathFromConfiguration = toolset?.PropertyElements.GetElement(toolsPathPropertyName); if (toolsPathFromConfiguration != null) { toolPath = toolsPathFromConfiguration.Value; if (toolPath != null) { if (!FileUtilities.IsRootedNoThrow(toolPath)) { toolPath = FileUtilities.NormalizePath(Path.Combine(FileUtilities.CurrentExecutableDirectory, toolPath)); } toolPath = FileUtilities.EnsureTrailingSlash(toolPath); } } } catch (ConfigurationException) { // may happen if the .exe.config contains bad data. Shouldn't ever happen in // practice since we'll long since have loaded all toolsets in the toolset loading // code and thrown errors to the user at that point if anything was invalid, but just // in case, just eat the exception here, so that we can go on to look in the registry // to see if there is any valid data there. } } return toolPath; }
/// <summary> /// Given a ToolsVersion, find the path to the build tools folder for that ToolsVersion. /// </summary> /// <param name="toolsVersion">The ToolsVersion to look up</param> /// <returns>The path to the build tools folder for that ToolsVersion, if it exists, or /// null otherwise</returns> internal static string GeneratePathToBuildToolsForToolsVersion(string toolsVersion, DotNetFrameworkArchitecture architecture) { // Much like when reading toolsets, first check the .exe.config string toolsPath = GetPathToBuildToolsFromConfig(toolsVersion, architecture); if (String.IsNullOrEmpty(toolsPath)) { // Or if it's not defined there, look it up in the registry toolsPath = GetPathToBuildToolsFromRegistry(toolsVersion, architecture); } return toolsPath; }
/// <summary> /// Heuristic that first considers the current runtime path and then searches the base of that path for the given /// frameworks version. /// </summary> /// <param name="currentRuntimePath">The path to the runtime that is currently executing.</param> /// <param name="prefix">Should be something like 'v1.2' that indicates the runtime version we want.</param> /// <param name="directoryExists">Delegate to method that can check for the existence of a file.</param> /// <param name="getDirectories">Delegate to method that can return filesystem entries.</param> /// <param name="architecture">.NET framework architecture</param> /// <returns>Will return 'null' if there is no target frameworks on this machine.</returns> internal static string FindDotNetFrameworkPath ( string currentRuntimePath, string prefix, DirectoryExists directoryExists, GetDirectories getDirectories, DotNetFrameworkArchitecture architecture ) { // If the COMPLUS variables are set, they override everything -- that's the directory we want. string complusInstallRoot = Environment.GetEnvironmentVariable("COMPLUS_INSTALLROOT"); string complusVersion = Environment.GetEnvironmentVariable("COMPLUS_VERSION"); if (!String.IsNullOrEmpty(complusInstallRoot) && !String.IsNullOrEmpty(complusVersion)) { return Path.Combine(complusInstallRoot, complusVersion); } // If the current runtime starts with correct prefix, then this is the runtime we want to use. // However, only if we're requesting current architecture -- otherwise, the base path may be different, so we'll need to look it up. string leaf = Path.GetFileName(currentRuntimePath); if (leaf.StartsWith(prefix, StringComparison.Ordinal) && architecture == DotNetFrameworkArchitecture.Current) { return currentRuntimePath; } // We haven't managed to use exact methods to locate the FX, so // search for the correct path with a heuristic. string baseLocation = Path.GetDirectoryName(currentRuntimePath); string searchPattern = prefix + "*"; int indexOfFramework64 = baseLocation.IndexOf("Framework64", StringComparison.OrdinalIgnoreCase); if (indexOfFramework64 != -1 && architecture == DotNetFrameworkArchitecture.Bitness32) { // need to get rid of just the 64, but want to look up 'Framework64' rather than '64' to avoid the case where // the path is something like 'C:\MyPath\64\Framework64'. 9 = length of 'Framework', to make the index match // the location of the '64'. int indexOf64 = indexOfFramework64 + 9; string tempLocation = baseLocation; baseLocation = tempLocation.Substring(0, indexOf64) + tempLocation.Substring(indexOf64 + 2, tempLocation.Length - indexOf64 - 2); } else if (indexOfFramework64 == -1 && architecture == DotNetFrameworkArchitecture.Bitness64) { // need to add 64 -- since this is a heuristic, we assume that we just need to append. baseLocation = baseLocation + "64"; } // we don't need to do anything if it's DotNetFrameworkArchitecture.Current. string[] directories; if (directoryExists(baseLocation)) { directories = getDirectories(baseLocation, searchPattern); } else { // If we can't even find the base path, might as well give up now. return null; } if (directories.Length == 0) { // Couldn't find the path, return a null. return null; } // We don't care which one we choose, but we want to be predictible. // The intention here is to choose the alphabetical maximum. string max = directories[0]; // the max.EndsWith condition: pre beta 2 versions of v3.5 have build number like v3.5.20111. // This was removed in beta2 // We should favor \v3.5 over \v3.5.xxxxx // versions previous to 2.0 have .xxxx version numbers. 3.0 and 3.5 do not. if (!max.EndsWith(prefix, StringComparison.OrdinalIgnoreCase)) { for (int i = 1; i < directories.Length; ++i) { if (directories[i].EndsWith(prefix, StringComparison.OrdinalIgnoreCase)) { max = directories[i]; break; } else if (String.Compare(directories[i], max, StringComparison.OrdinalIgnoreCase) > 0) { max = directories[i]; } } } return max; }
public static string GetPathToDotNetFramework(TargetDotNetFrameworkVersion version, DotNetFrameworkArchitecture architecture) { return(ToolLocationHelper.GetPathToDotNetFramework(version, architecture)); }
/// <summary> /// Gets the full path of .net framework for the given architecture. /// </summary> public virtual string GetPathToDotNetFramework(DotNetFrameworkArchitecture architecture) { string cachedPath; if (this._pathsToDotNetFramework.TryGetValue(architecture, out cachedPath)) { return cachedPath; } // Otherwise, check to see if we're even installed. If not, return null -- no point in setting the static // variables to null when that's what they are already. if (!CheckForFrameworkInstallation(this._dotNetFrameworkRegistryKey, this._dotNetFrameworkSetupRegistryInstalledName)) { return null; } // We're installed and we haven't found this framework path yet -- so find it! string generatedPathToDotNetFramework = FindDotNetFrameworkPath( Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName), this.DotNetFrameworkFolderPrefix, Directory.Exists, Directory.GetDirectories, architecture); if (this._hasMsBuild && generatedPathToDotNetFramework != null && !File.Exists(Path.Combine(generatedPathToDotNetFramework, "msbuild.exe"))) // .net was improperly uninstalled: msbuild.exe isn't there { return null; } if (!string.IsNullOrEmpty(generatedPathToDotNetFramework)) { _pathsToDotNetFramework[architecture] = generatedPathToDotNetFramework; } return generatedPathToDotNetFramework; }
/// <summary> /// Given a filename (currently only Tracker.exe and FileTracker.dll are supported), return /// the path to that file. /// </summary> /// <param name="filename"></param> /// <param name="bitness"></param> /// <returns></returns> private static string GetPath(string filename, DotNetFrameworkArchitecture bitness) { string trackerPath; // Make sure that if someone starts passing the wrong thing to this method we don't silently // eat it and do something possibly unexpected. ErrorUtilities.VerifyThrow( s_TrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase) || s_FileTrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase), "This method should only be passed s_TrackerFilename or s_FileTrackerFilename, but was passed {0} instead!", filename ); // Look for FileTracker.dll/FileTracker.exe first in the MSBuild tools directory, then fall back to .NET framework directory // and finally to .NET SDK directories. trackerPath = ToolLocationHelper.GetPathToBuildToolsFile(filename, ToolLocationHelper.CurrentToolsVersion, bitness); if (String.IsNullOrEmpty(trackerPath)) { trackerPath = ToolLocationHelper.GetPathToDotNetFrameworkFile(filename, TargetDotNetFrameworkVersion.VersionLatest, bitness); if ((String.IsNullOrEmpty(trackerPath) || !File.Exists(trackerPath)) && s_TrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase)) { // fall back to looking in the SDK directory -- this is where Tracker.exe will be in the typical VS case. First check // in the SDK for the latest target framework and latest Visual Studio version, since we want to make sure that we get // the most up-to-date version of FileTracker. trackerPath = ToolLocationHelper.GetPathToDotNetFrameworkSdkFile(filename, TargetDotNetFrameworkVersion.Version45, VisualStudioVersion.VersionLatest, bitness); // If that didn't work, we may be in a scenario where, e.g., we have VS 10 on Windows 8, which comes with .NET 4.5 // pre-installed. In which case, the Dev11 (or other "latest" SDK) may not exist, but the Dev10 SDK might. Check // for that here. if (trackerPath == null) { trackerPath = ToolLocationHelper.GetPathToDotNetFrameworkSdkFile(filename, TargetDotNetFrameworkVersion.Version40, bitness); } } } return trackerPath; }
private IEnumerable <PortableExecutableReference> GetDotNetFrameworkReferences(TargetDotNetFrameworkVersion dotNetFrameworkVersion, DotNetFrameworkArchitecture architecture) { yield return(MetadataReference.CreateFromFile(ToolLocationHelper.GetPathToDotNetFrameworkFile("mscorlib.dll", dotNetFrameworkVersion, architecture))); yield return(MetadataReference.CreateFromFile(ToolLocationHelper.GetPathToDotNetFrameworkFile("System.dll", dotNetFrameworkVersion, architecture))); if (dotNetFrameworkVersion != TargetDotNetFrameworkVersion.Version11 && dotNetFrameworkVersion != TargetDotNetFrameworkVersion.Version20) { yield return(MetadataReference.CreateFromFile(ToolLocationHelper.GetPathToDotNetFrameworkFile("System.Core.dll", dotNetFrameworkVersion, architecture))); } yield return(MetadataReference.CreateFromFile(ToolLocationHelper.GetPathToDotNetFrameworkFile("System.Configuration.dll", dotNetFrameworkVersion, architecture))); }
/// <summary> /// Given a filename (currently only Tracker.exe and FileTracker.dll are supported), return /// the path to that file. /// </summary> /// <param name="filename"></param> /// <param name="bitness"></param> /// <returns></returns> private static string GetPath(string filename, DotNetFrameworkArchitecture bitness) { // Make sure that if someone starts passing the wrong thing to this method we don't silently // eat it and do something possibly unexpected. ErrorUtilities.VerifyThrow( s_TrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase) || s_FileTrackerFilename.Equals(filename, StringComparison.OrdinalIgnoreCase), "This method should only be passed s_TrackerFilename or s_FileTrackerFilename, but was passed {0} instead!", filename ); // Look for FileTracker.dll/Tracker.exe in the MSBuild tools directory. They may exist elsewhere on disk, // but other copies aren't guaranteed to be compatible with the latest. return ToolLocationHelper.GetPathToBuildToolsFile(filename, ToolLocationHelper.CurrentToolsVersion, bitness); }
/// <summary> /// Look up the path to the build tools directory for the requested ToolsVersion in the .exe.config file of this executable /// </summary> private static string GetPathToBuildToolsFromEnvironment(DotNetFrameworkArchitecture architecture) { switch (architecture) { case DotNetFrameworkArchitecture.Bitness64: return BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64; case DotNetFrameworkArchitecture.Bitness32: return BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32; default: return BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory; } }
internal static string GetPathToDotNetFramework(Version version, DotNetFrameworkArchitecture architecture) { return GetDotNetFrameworkSpec(version).GetPathToDotNetFramework(architecture); }
internal static string FindDotNetFrameworkPath(string currentRuntimePath, string prefix, string frameworkVersion, DirectoryExists directoryExists, GetDirectories getDirectories, DotNetFrameworkArchitecture architecture, bool useHeuristic) { string[] strArray; if (Path.GetFileName(currentRuntimePath).StartsWith(prefix, StringComparison.Ordinal) && (architecture == DotNetFrameworkArchitecture.Current)) { return(currentRuntimePath); } string str2 = null; if (architecture == DotNetFrameworkArchitecture.Current) { str2 = ConstructDotNetFrameworkPathFromRuntimeInfo(frameworkVersion); } if ((str2 != null) || !useHeuristic) { return(str2); } string directoryName = Path.GetDirectoryName(currentRuntimePath); string pattern = prefix + "*"; if (directoryName.Contains("64") && (architecture == DotNetFrameworkArchitecture.Bitness32)) { int index = directoryName.IndexOf("64", StringComparison.OrdinalIgnoreCase); string str5 = directoryName; directoryName = str5.Substring(0, index) + str5.Substring(index + 2, (str5.Length - index) - 2); } else if (!directoryName.Contains("64") && (architecture == DotNetFrameworkArchitecture.Bitness64)) { directoryName = directoryName + "64"; } if (directoryExists(directoryName)) { strArray = getDirectories(directoryName, pattern); } else { return(null); } if (strArray.Length == 0) { return(null); } string strB = strArray[0]; if (!strB.EndsWith(prefix, StringComparison.OrdinalIgnoreCase)) { for (int i = 1; i < strArray.Length; i++) { if (strArray[i].EndsWith(prefix, StringComparison.OrdinalIgnoreCase)) { return(strArray[i]); } if (string.Compare(strArray[i], strB, StringComparison.OrdinalIgnoreCase) > 0) { strB = strArray[i]; } } } return(strB); }