Search code examples
c#devenv

programmatically clean solution using devenv


I am trying to clean all the projects in solution from code behind using C#. I have use devenv clean commnad, my method is executed properly without any exception but no action is performed on the solution. All project's bin and obj folder in my solution still contains the compiler generated files. Please let me know where is the problem.

C# code

 public string CleanSolution(BO.Project project)
    {
        try
        {
            if (!File.Exists(project.SolutionFilePath)) return "Solution file not found";
            var cleanCommand = "Devenv  " + project.SolutionFilePath + " /Clean";

            //var cleanProcess = Process.Start(@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe", cleanCommand);
            //if (cleanProcess != null) cleanProcess.WaitForExit();

            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            startInfo.FileName = Environment.ExpandEnvironmentVariables("%comspec%");
            startInfo.Arguments = string.Format(@"/c ""c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"" && devenv.com ""{0}"" /Clean",project.SolutionFilePath);
            process.StartInfo = startInfo;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.UseShellExecute = false;
            process.Start();
            // Read the error stream first and then wait.
            string error = process.StandardError.ReadToEnd();
            StringBuilder q = new StringBuilder();
            while (!process.HasExited)
            {
                q.Append(process.StandardOutput.ReadToEnd());
            }
            string r = q.ToString();
            var message = "Clean Succeeded";
            IsClean = true;
            return message;
        }
        catch (Exception e)
        {
            return string.Format("Message: {0}", e.Message) + Environment.NewLine +
                   string.Format("Stack Tracke: {0}{1}", Environment.NewLine, e.StackTrace) + Environment.NewLine +
                   (e.InnerException != null
                        ? string.Format("Inner Exception: {0}", e.InnerException.Message) + Environment.NewLine
                        : string.Empty) + Environment.NewLine +
                   (e.InnerException != null
                        ? string.Format("Inner Exception Stack Tracke: {0}", e.InnerException.StackTrace) +
                          Environment.NewLine
                        : string.Empty) + Environment.NewLine;
        }
    }

I tried to redirect the output of process so as to see what happens but I am getting empty string as its final output in variable processOutput


Solution

  • That's not how it works, you cannot use vcvarsall as command and devenv ... as arguments.

    As ProcessStartInfo.FileName use "cmd.exe", or better:

    Environment.ExpandEnvironmentVariables("%comspec%")
    

    As ProcessStartInfo.Arguments use:

    @"/c <...>\vcvarsall.bat && devenv.com <...>"
    

    Where <...> are the fragments (directory, arguments, etc.) you already have in your code.

    Note that you should use explicitly use devenv.com (windowless command line version), to make sure that not devenv.exe (normal application) is used.

    To make things more robust, you should make sure that your paths are properly quoted.

    Here is the full example:

    startInfo.FileName = Environment.ExpandEnvironmentVariables("%comspec%")
    startInfo.Arguments = string.Format(
       @"/c """"c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"" && devenv.com ""{0}"" /Clean""",
       project.SolutionFilePath);