コードでbuildを制御し、関連資料を収集する

22603 ワード

最近、WPの言語ファイルのコンパイルをしていて、複数の言語のコンパイルを見つけるのは本当に大変ですね.そこで自動コンパイルに関するコードを集めた.ある日、言語ファイルをexcelに入れて、すべての言語dllをワンクリックで解決することを夢見ています.
コードは次のとおりです.
  static void Main(string[] args)
        {
            //string path = @"E:\OpenSource\SMSHelper\SMSHelper\SMSHelper.csproj";
            string path2 = @"SMSHelper\SMSHelper\SMSHelper.csproj";
            string path1 = @"SMSHelper\Language\AppResLib\AppResLib.vcxproj";

            BuildByManager2(path2);
            Console.Read();
        }

        /// <summary>
        /// use Microsoft.Build.BuildEngine.Engine to build
        /// </summary>
        /// <remarks>
        /// 1.target framework must be full version, not client profile
        /// 2.must add reference Microsoft.Build.Engine, add reference Microsoft.Build.Framework(optional)
        /// 3.can't build C++ project,  why?
        /// </remarks>
        /// <see cref="http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/cdc297c5-cde3-40a2-a7fe-38eeab36f1bb/"/>
        static void buildByEngine(string projectFile)
        {
            // Instantiate a new Engine object
            Engine engine = new Engine();

            //Point to the correct path that contains the 2.0 clr/tools
            //engine.BinPath = @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\";

            // Instantiate a new FileLogger to generate build log
            FileLogger logger = new FileLogger();

            // Set logfile parameter to indicate the log destination
            logger.Parameters = @"logfile=build.log";

            // Register the logger with the engine
            engine.RegisterLogger(logger);

            // Build a project file
            bool success = engine.BuildProjectFile(projectFile);

            if (success)
                Console.WriteLine("Success!");
            else
                Console.WriteLine("Build failed - look at c:\temp\build.log for details");
        }

        /// <summary>
        /// easy mode to build.
        /// </summary>
        /// <remarks>
        /// client profile is ok.
        /// </remarks>
        /// <see cref="http://www.cnblogs.com/winner/archive/2008/05/26/1207903.html"/>
        /// <param name="projectFile"></param>
        static void buildByCommand(string projectFile)
        {
            var commandPath = GetFrameworkDirectory() + "MSBuild";
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.Start();
            p.StandardInput.WriteLine(commandPath + "  " + projectFile);
            p.StandardInput.WriteLine("exit");
            string strRst = p.StandardOutput.ReadToEnd();
            Console.WriteLine(strRst);
            p.Close();
        }

        /// <summary>
        /// easy mode to build.
        /// </summary>
        /// <param name="projectFile"></param>
        /// <see cref="http://stackoverflow.com/questions/7264682/running-msbuild-programmatically"/>
        static void buildByCommand2(string projectFile)
        {
            var p = new Process();
            p.StartInfo = new ProcessStartInfo(GetFrameworkDirectory() + "MSBuild");
            p.StartInfo.Arguments = projectFile;
            p.Start();
        }

        /// <summary>
        /// get framework path
        /// </summary>
        /// <see cref="http://stackoverflow.com/questions/375860/getting-the-net-framework-directory-path"/>
        /// <returns></returns>
        static string GetFrameworkDirectory()
        {
            // This is the location of the .Net Framework Registry Key
            string framworkRegPath = @"Software\Microsoft\.NetFramework";

            // Get a non-writable key from the registry
            RegistryKey netFramework = Registry.LocalMachine.OpenSubKey(framworkRegPath, false);

            // Retrieve the install root path for the framework
            string installRoot = netFramework.GetValue("InstallRoot").ToString();

            // Retrieve the version of the framework executing this program
            string version = string.Format(@"v{0}.{1}.{2}\",
              Environment.Version.Major,
              Environment.Version.Minor,
              Environment.Version.Build);

            // Return the path of the framework
            return System.IO.Path.Combine(installRoot, version);
        }

        /// <summary>
        /// use ProjectCollection to build
        /// </summary>
        /// <param name="projectFile"></param>
        /// <see cref=" http://stackoverflow.com/questions/6511380/how-do-i-build-a-solution-programatically-in-c"/>
        static void buildByprojectCollection(string projectFile)
        {
            List<ILogger> loggers = new List<ILogger>();
            loggers.Add(new ConsoleLogger());
            var projectCollection = new ProjectCollection();
            projectCollection.RegisterLoggers(loggers);
            var project = projectCollection.LoadProject(projectFile); // Needs a reference to System.Xml
            try
            {
                project.Build();
            }
            finally
            {
                projectCollection.UnregisterAllLoggers();
            }
        }

        /// <summary>
        /// use [Microsoft.Build.Evaluation.Project] to build
        /// </summary>
        /// <param name="projectFile"></param>
        /// <see cref=" http://stackoverflow.com/questions/6511380/how-do-i-build-a-solution-programatically-in-c"/>
        static void buildByProject(string projectFile)
        {
            Microsoft.Build.Evaluation.Project project = new Microsoft.Build.Evaluation.Project(projectFile, null, "4.0");
            var ok = project.Build(new ConsoleLogger());
            Console.WriteLine(ok);
        }

        /// <summary>
        /// use BuildManager
        /// </summary>
        /// <param name="projectFile"></param>
        /// <see cref="http://stackoverflow.com/questions/6511380/how-do-i-build-a-solution-programatically-in-c"/>
        static void buildByManager(string projectFile)
        {
            var props = new Dictionary<string, string>();
            props["Configuration"] = "Release";
//props["Platform"] = "Win32";
//if c++
//props["OutDir"] = @"S:\dddd\";
//if c#
props["OutputPath"] = @"S:\dddd\";

var request = new BuildRequestData(projectFile, props, null, new string[] { "Build" }, null); var parms = new BuildParameters(); parms.Loggers = new List<ILogger> { new ConsoleLogger() }; var result = BuildManager.DefaultBuildManager.Build(parms, request); Console.WriteLine(result); } /// <summary> /// use BuildManager /// </summary> /// <param name="msbuildFileName"></param> /// <see cref="http://stackoverflow.com/questions/9942499/building-programatically-a-project"/> public static void BuildByManager2(string msbuildFileName) { ConsoleLogger logger = new ConsoleLogger(LoggerVerbosity.Normal); BuildManager manager = BuildManager.DefaultBuildManager; ProjectInstance projectInstance = new ProjectInstance(msbuildFileName); var result = manager.Build( new BuildParameters() { DetailedSummary = true, Loggers = new List<ILogger>() { logger } }, new BuildRequestData(projectInstance, new string[] { "Build" })); var buildResult = result.ResultsByTarget["Build"]; var buildResultItems = buildResult.Items; }