// ---------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // ---------------------------------------------------------------------------- using System; using System.IO; using System.Collections.Generic; using System.Text; using System.Security.AccessControl; using Microsoft.Win32; namespace RegMSBuildSafe { static class Program { static bool verbose; static int Main(string[] args) { verbose = false; if (args.Length == 0) { Console.WriteLine("This tool manages registry entries that Visual Studio uses to determine"); Console.WriteLine("whether a .targets file imported by an MSBuild project is considered 'safe'."); Console.WriteLine(); Console.WriteLine("Use -? for help."); return -1; } try { foreach (string arg in args) { if (arg.Length == 0) continue; if (arg[0] == '/' || arg[0] == '-') { string flag = arg.Substring(1).ToLower(); if (flag == "i" || flag == "install") { return InstallSafeImports(); } else if (flag == "u" || flag == "uninstall") { string prefix = GetSafeImportPrefix(); return UninstallSafeImports(prefix); } else if (flag == "us" || flag == "uninstallsing") { return UninstallSafeImports(SafeImportNamePrefix); } else if (flag == "l" || flag == "list") { string prefix = GetSafeImportPrefix(); return ListSafeImports(prefix); } else if (flag == "ls" || flag == "listsing") { return ListSafeImports(SafeImportNamePrefix); } else if (flag == "la" || flag == "listall") { return ListSafeImports(""); } else if (flag == "v" || flag == "verbose") { verbose = true; } else if (flag == "?" || flag == "help") { Usage(); return 0; } else { Usage(); return -1; } } else { Usage(); return -1; } } Usage(); return -1; } catch (UnauthorizedAccessException ex) { ShowException(ex); Console.Error.WriteLine("Make sure you are running with Administrator rights, and if necessary,"); Console.Error.WriteLine("have elevated privileges."); return -1; } catch (Exception ex) { ShowException(ex); return -1; } } static void ShowException(Exception ex) { for (Exception focus = ex; focus != null; focus = focus.InnerException) { Console.Error.WriteLine("{0}: {1}", ex.GetType().FullName, ex.Message); } } static int InstallSafeImports() { string prefix = SafeImportNamePrefix; string[] targets = GetSingularityTargets(); using (RegistryKey key = Registry.LocalMachine.OpenSubKey( SafeImportsPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue)) { foreach (string target in targets) { string name = prefix + target; key.SetValue(name, target); if (verbose) Console.WriteLine("Set value: " + name); } } return 0; } static int UninstallSafeImports(string prefix) { if (String.IsNullOrEmpty(prefix)) throw new Exception("The prefix must not be an empty string."); if (!prefix.StartsWith(SafeImportNamePrefix, StringComparison.OrdinalIgnoreCase)) throw new Exception("The prefix can only specify Singularity-related values."); using (RegistryKey key = Registry.LocalMachine.OpenSubKey( SafeImportsPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue | RegistryRights.QueryValues)) { string[] names = key.GetValueNames(); foreach (string name in names) { if (name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { key.DeleteValue(name, false); if (verbose) Console.WriteLine("Deleted value: " + name); } } } return 0; } /// /// Returns a list of the absolute paths of all of the interesting .targets files /// for Singularity. /// /// static string[] GetSingularityTargets() { string root = GetSingularityRoot(); List alltargets = new List(); string targets_dir = Path.Combine(root, "Targets"); string[] targets = Directory.GetFiles(targets_dir, "*.targets", SearchOption.TopDirectoryOnly); alltargets.AddRange(targets); alltargets.Add(Path.Combine(root, "Paths.targets")); alltargets.Add(Path.Combine(root, "Applications\\Paths.targets")); return alltargets.ToArray(); } static string GetSafeImportPrefix() { string singularity_root = GetSingularityRoot(); return SafeImportNamePrefix + singularity_root; } static string GetSingularityRoot() { string singularity_root = Environment.GetEnvironmentVariable("SINGULARITY_ROOT"); if (String.IsNullOrEmpty(singularity_root)) throw new Exception("The SINGULARITY_ROOT environment variable is not set."); return singularity_root; } const string SafeImportNamePrefix = "Singularity:"; static int ListSafeImports(string prefix) { using (RegistryKey key = Registry.LocalMachine.OpenSubKey( SafeImportsPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.QueryValues)) { string[] names = key.GetValueNames(); foreach (string name in names) { if (!name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) continue; Console.WriteLine(name); } } return 0; } static void Usage() { Console.WriteLine("This tool registers the MSBuild .targets files used by Singularity"); Console.WriteLine("as 'safe' for use by Visual Studio. This makes Visual Studio stop"); Console.WriteLine("complaining about loading projects that import scary .targets files."); Console.WriteLine(); Console.WriteLine("Usage:"); Console.WriteLine(); Console.WriteLine(" -v Turn on verbose output."); Console.WriteLine(" -i Install registry values."); Console.WriteLine(" -u Uninstall registry values for this Singularity tree."); Console.WriteLine(" -us Uninstall registry values for all Singularity trees."); Console.WriteLine(" -l List safe imports for this Singularity tree."); Console.WriteLine(" -ls List safe imports for all Singularity projects."); Console.WriteLine(" -la List safe imports (all of them, not just for Singularity."); Console.WriteLine(); Console.WriteLine("The values are stored in HKEY_LOCAL_MACHINE\\" + SafeImportsPath + "."); Console.WriteLine("The environment variable SINGULARITY_ROOT must be set, so that the"); Console.WriteLine("tool can locate the .targets files. All targets files found in the"); Console.WriteLine("%SINGULARITY_ROOT%\\Targets directory will be added to the registry."); } const string SafeImportsPath = @"Software\Microsoft\VisualStudio\8.0\MSBuild\SafeImports"; } }