/// <summary> /// Executes the program with the specified command-line arguments. /// </summary> /// <param name="args">An array of <see cref="string" /> containing the command-line arguments.</param> /// <returns>Zero if the program executed successfully, otherwise a non-zero value.</returns> public static int Main(string[] args) { CurrentDevelopmentEnvironment = DevelopmentEnvironment.LoadCurrentDevelopmentEnvironment(); if (!CurrentDevelopmentEnvironment.Success || CurrentDevelopmentEnvironment.Errors.Count > 0) { foreach (string error in CurrentDevelopmentEnvironment.Errors) { Utility.WriteError(error); } return(-1); } Assembly thisAssembly = Assembly.GetExecutingAssembly(); #if NETFRAMEWORK if (AppDomain.CurrentDomain.IsDefaultAppDomain()) { AppDomain appDomain = AppDomain.CreateDomain( thisAssembly.FullName, securityInfo: null, info: new AppDomainSetup { ApplicationBase = CurrentDevelopmentEnvironment.MSBuildExe.DirectoryName, ConfigurationFile = Path.Combine(CurrentDevelopmentEnvironment.MSBuildExe.DirectoryName !, Path.ChangeExtension(CurrentDevelopmentEnvironment.MSBuildExe.Name, ".exe.config")), });
private static void RegisterMSBuildAssemblyResolver(DevelopmentEnvironment developmentEnvironment) { if (developmentEnvironment.MSBuildDll == null || !developmentEnvironment.MSBuildDll.Exists) { return; } AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { AssemblyName assemblyName = new AssemblyName(args.Name); string candidatePath = Path.Combine(developmentEnvironment.MSBuildDll.DirectoryName, $"{assemblyName.Name}.dll"); if (File.Exists(candidatePath)) { return(Assembly.LoadFrom(candidatePath)); } return(null); }; }
/// <summary> /// Executes the program. /// </summary> /// <param name="args">The command-line arguments.</param> /// <returns>0 if the program ran successfully, otherwise a non-zero number.</returns> public static int Main(string[] args) { try { // Determine the path to the current slngen.exe FileInfo thisAssemblyFileInfo = new FileInfo(Assembly.GetExecutingAssembly().Location); DevelopmentEnvironment developmentEnvironment = DevelopmentEnvironment.LoadCurrentDevelopmentEnvironment(); if (!developmentEnvironment.Success) { foreach (string error in developmentEnvironment.Errors) { Utility.WriteError(error); } // If the development environment couldn't be determined, then we can't proceed since we have no idea what framework to use or MSBuild/dotnet are not available. return(1); } bool useDotnet = developmentEnvironment.MSBuildExe == null; // Default to .NET Framework on Windows if MSBuild.exe is on the PATH string framework = Utility.RunningOnWindows && !useDotnet ? "net472" : string.Empty; if (useDotnet) { switch (developmentEnvironment.DotNetSdkMajorVersion) { case "3": framework = "netcoreapp3.1"; break; case "5": framework = "net5.0"; break; case "6": framework = "net6.0"; break; default: Console.WriteLine($"The .NET SDK {developmentEnvironment.DotNetSdkVersion} is not supported"); return(-1); } } else { FileVersionInfo msBuildVersionInfo = FileVersionInfo.GetVersionInfo(developmentEnvironment.MSBuildExe.FullName); switch (msBuildVersionInfo.FileMajorPart) { case 15: framework = "net461"; break; default: framework = "net472"; break; } } FileInfo slnGenFileInfo = new FileInfo(Path.Combine(thisAssemblyFileInfo.DirectoryName !, "..", thisAssemblyFileInfo.DirectoryName !.EndsWith("any") ? ".." : string.Empty, "slngen", framework, useDotnet ? "slngen.dll" : "slngen.exe")); if (!slnGenFileInfo.Exists) { Console.WriteLine($"SlnGen not found: {slnGenFileInfo.FullName}"); return(-1); } Process process = new Process { StartInfo = new ProcessStartInfo { FileName = useDotnet ? "dotnet" : slnGenFileInfo.FullName, }, }; if (useDotnet) { process.StartInfo.ArgumentList.Add(slnGenFileInfo.FullName); } foreach (string argument in Environment.GetCommandLineArgs().Skip(1)) { process.StartInfo.ArgumentList.Add(argument); } process.Start(); process.WaitForExit(); return(process.ExitCode); } catch (Exception e) { Console.WriteLine($"Unhandled exception: {e}"); return(1); } }
private static DevelopmentEnvironment LoadDevelopmentEnvironmentFromCurrentWindow() { string basePath = null; using (ManualResetEvent processExited = new ManualResetEvent(false)) using (Process process = new Process { EnableRaisingEvents = true, StartInfo = new ProcessStartInfo { Arguments = "--info", CreateNoWindow = true, FileName = "dotnet", UseShellExecute = false, RedirectStandardError = true, RedirectStandardInput = true, RedirectStandardOutput = true, WorkingDirectory = Environment.CurrentDirectory, }, }) { process.StartInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] = "en-US"; process.StartInfo.EnvironmentVariables["DOTNET_CLI_TELEMETRY_OPTOUT"] = bool.TrueString; process.ErrorDataReceived += (sender, args) => { }; process.OutputDataReceived += (sender, args) => { if (!String.IsNullOrWhiteSpace(args?.Data)) { Match match = DotNetBasePathRegex.Match(args.Data); if (match.Success && match.Groups["Path"].Success) { basePath = match.Groups["Path"].Value.Trim(); } } }; process.Exited += (sender, args) => { processExited.Set(); }; try { if (!process.Start()) { return(new DevelopmentEnvironment("Failed to find .NET Core SDK, could not start dotnet")); } } catch (Exception e) { return(new DevelopmentEnvironment("Failed to find .NET Core SDK, failed launching dotnet", e.ToString())); } process.StandardInput.Close(); process.BeginErrorReadLine(); process.BeginOutputReadLine(); switch (WaitHandle.WaitAny(new WaitHandle[] { processExited }, TimeSpan.FromSeconds(5))) { case WaitHandle.WaitTimeout: break; case 0: break; } if (!process.HasExited) { try { process.Kill(); } catch { } } if (!basePath.IsNullOrWhiteSpace()) { DevelopmentEnvironment developmentEnvironment = new DevelopmentEnvironment { MSBuildDll = new FileInfo(Path.Combine(basePath, "MSBuild.dll")), }; RegisterMSBuildAssemblyResolver(developmentEnvironment); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && TryFindMSBuildOnPath(out string msbuildExePath)) { developmentEnvironment.MSBuildExe = new FileInfo(msbuildExePath); developmentEnvironment.VisualStudio = VisualStudioConfiguration.GetInstanceForPath(msbuildExePath); } return(developmentEnvironment); } return(new DevelopmentEnvironment("Failed to find .NET Core SDK, ensure you have .NET Core SDK installed and if you have a global.json that it specifies a version you have installed.")); } }