// // Copyright (c) ZeroC, Inc. All rights reserved. // using System; using System.Diagnostics; using System.IO; using System.Threading; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; public class SignTask : Task { [Required] public string WorkingDirectory { get; set; } [Required] public ITaskItem[] Files { get; set; } public string AdditionalOptions { get; set; } protected string GenerateCommandLineCommands() { CommandLineBuilder builder = new CommandLineBuilder(false); builder.AppendSwitch("sign"); if(AdditionalOptions != null) { builder.AppendTextUnquoted(" "); builder.AppendTextUnquoted(AdditionalOptions); } builder.AppendFileNamesIfNotNull(Files, " "); return builder.ToString(); } public override bool Execute() { string commandLineCommands = GenerateCommandLineCommands(); int status = 0; string output = ""; string error = ""; int nRetries = 0; while(nRetries++ < 10) { output = ""; error = ""; status = RunCommand(WorkingDirectory, "signtool.exe", commandLineCommands, ref output, ref error); if(status != 0 && error.IndexOf("timestamp server") != -1) { Thread.Sleep(10); continue; } break; } if(status == 0) { Log.LogMessage(MessageImportance.High, output.Trim()); } else { Log.LogError(error.Trim()); } return status == 0; } public class StreamReader { public string Output { get; private set; } public string Error { get; private set; } public void ouput(object sendingProcess, DataReceivedEventArgs outLine) { if(outLine.Data != null) { Output += outLine.Data + "\n"; } } public void error(object sendingProcess, DataReceivedEventArgs outLine) { if(outLine.Data != null) { Error += outLine.Data + "\n"; } } } public static int RunCommand(string workingDir, string command, string args, ref string output, ref string error) { Process process = new Process(); process.StartInfo.FileName = command; process.StartInfo.Arguments = args; process.StartInfo.CreateNoWindow = true; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.WorkingDirectory = workingDir; var streamReader = new StreamReader(); process.OutputDataReceived += new DataReceivedEventHandler(streamReader.ouput); process.ErrorDataReceived += new DataReceivedEventHandler(streamReader.error); try { process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); error = streamReader.Error; output = streamReader.Output; return process.ExitCode; } catch(Exception ex) { error = ex.ToString(); return 1; } } }