private IEnumerable <string> BuildX64() { clearTargetBuildFlags(); var setEnv = ProgramFinder.ProgramFiles.ScanForFile("setenv.cmd"); if (string.IsNullOrEmpty(setEnv)) { throw new Exception("Cannot locate SDK SetEnv command. Please install the Windows SDK"); } var se = new ProcessUtility("cmd.exe"); se.Exec(@"/c ""{0}"" /{1} & set ", setEnv, "x64"); foreach (var x in se.StandardOut.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) { if (x.Contains("=")) { var v = x.Split('='); Environment.SetEnvironmentVariable(v[0], v[1]); } } var target_cpu = Environment.GetEnvironmentVariable("TARGET_CPU"); if (string.IsNullOrEmpty(target_cpu) || (target_cpu == "x86")) { throw new Exception( "Cannot set the SDK environment. Please install the Windows SDK and use the setenv.cmd command to set your environment"); } return(null); }
private void ExtractCert() { certPath = Path.Combine(tempFolder, "CoAppTest.pfx"); File.WriteAllBytes(certPath, Resources.CoAppTestCert); pkPath = Path.Combine(tempFolder, "CoAppTest.pk"); File.WriteAllBytes(pkPath, Resources.CoAppTestCertPublicKey); var cerPath = Assembly.GetExecutingAssembly().ExtractFileResourceToTemp("CoAppTest.cer"); pktExtract.Exec("-nologo -quiet {0}", cerPath); publicKeyToken = pktExtract.StandardOut.Trim(); }
private IEnumerable <string> BuildMSIL() { clearTargetBuildFlags(); var setEnv = ProgramFinder.ProgramFiles.ScanForFile("VSVARS32.bat"); if (string.IsNullOrEmpty(setEnv)) { throw new Exception("Cannot locate VCVARS32.bat command. Please install something?"); } var se = new ProcessUtility(setEnv); se.Exec(""); return(null); }
private void RebuildWebsite() { Task.Factory.StartNew(() => { try { Console.WriteLine("Rebuilding website."); Environment.CurrentDirectory = Environment.GetEnvironmentVariable("STORAGE"); if (_cmdexe.Exec(@"/c rebuild_site.cmd") != 0) { Console.WriteLine("Site rebuild result:\r\n{0}", _cmdexe.StandardOut); return; } Console.WriteLine("Rebuilt Website."); } catch (Exception e) { } }); }
private int main(string[] args) { bool mergeAssemblies = false; Dictionary <string, IEnumerable <string> > options = args.Switches(); IEnumerable <string> parameters = args.Parameters(); foreach (string arg in options.Keys) { IEnumerable <string> argumentParameters = options[arg]; switch (arg) { case "nologo": this.Assembly().SetLogo(""); quiet = true; break; case "merge": mergeAssemblies = true; break; case "keep-temp-files": keepTempFiles = true; break; case "rescan-tools": ProgramFinder.IgnoreCache = true; break; case "debug": debug = true; break; case "sampleusage": SampleUsage(); return(0); case "sampleclass": SampleClass(); return(0); case "output-filename": finalOuputFilename = argumentParameters.FirstOrDefault(); break; case "create-header": headerFilename = argumentParameters.FirstOrDefault(); break; case "platform": platform = (argumentParameters.FirstOrDefault() ?? "x86").Equals("x64", StringComparison.CurrentCultureIgnoreCase) ? "x64" : "x86"; break; case "create-lib": createLib = true; break; case "help": Help(); return(0); default: Logo(); return(Fail("Error: unrecognized switch:{0}", arg)); } } if (parameters.Count() != 1) { Help(); return(0); } if (!quiet) { Logo(); } var ILDasm = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("ildasm.exe", "4.0.30319.1")); var ILAsm = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("ilasm.exe", "4.0.30319.1")); var Lib = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("lib.exe")); string originalAssemblyPath = parameters.First().GetFullPath(); if (!File.Exists(originalAssemblyPath)) { return(Fail("Error: the specified original assembly \r\n [{0}]\r\ndoes not exist.", originalAssemblyPath)); } string shimAssemblyPath = GenerateShimAssembly(originalAssemblyPath); finalOuputFilename = string.IsNullOrEmpty(finalOuputFilename) ? (mergeAssemblies ? originalAssemblyPath : shimAssemblyPath) : finalOuputFilename; string temporaryIlFilename = shimAssemblyPath + ".il"; int rc = ILDasm.Exec(@"/text /nobar /typelist ""{0}""", shimAssemblyPath); if (0 != rc) { return(Fail("Error: unable to disassemble the temporary assembly\r\n [{0}]\r\nMore Information:\r\n{1}", shimAssemblyPath, ILDasm.StandardOut)); } Delete(shimAssemblyPath); // eliminate it regardless of result. string ilSource = Regex.Replace(ILDasm.StandardOut, @"IL_0000:.*ldstr.*\""(?<x>.*)\""", "${x}"); if (mergeAssemblies) { int start = ilSource.IndexOf("\r\n.method"); int end = ilSource.LastIndexOf("// end of global method"); ilSource = ilSource.Substring(start, end - start); // arg! needed this to make sure the resources came out. grrr rc = ILDasm.Exec(@"/nobar /typelist ""{0}"" /out=""{1}""", originalAssemblyPath, temporaryIlFilename); rc = ILDasm.Exec(@"/nobar /text /typelist ""{0}""", originalAssemblyPath); if (0 != rc) { return(Fail("Error: unable to disassemble the target assembly\r\n [{0}]\r\nMore Information:\r\n{1}", shimAssemblyPath, ILDasm.StandardOut)); } string ilTargetSource = ILDasm.StandardOut; start = Math.Min(ilTargetSource.IndexOf(".method"), ilTargetSource.IndexOf(".class")); ilSource = ilTargetSource.Substring(0, start) + ilSource + ilTargetSource.Substring(start); } File.WriteAllText(temporaryIlFilename, ilSource); rc = ILAsm.Exec(@"{3} /dll {2} /output={0} ""{1}""", shimAssemblyPath, temporaryIlFilename, debug ? "/debug" : "", platform == "x64" ? "/X64" : ""); if (!debug) { Delete(temporaryIlFilename); // delete temp file regardless of result. } if (0 != rc) { return(Fail("Error: unable to assemble the merged assembly\r\n [{0}]\r\n [{1}]\r\nMore Information:\r\n{2}", shimAssemblyPath, temporaryIlFilename, ILAsm.StandardError)); } if (originalAssemblyPath.Equals(finalOuputFilename, StringComparison.CurrentCultureIgnoreCase)) { File.Delete(originalAssemblyPath + ".orig"); File.Move(originalAssemblyPath, originalAssemblyPath + ".orig"); } File.Delete(finalOuputFilename); File.Move(shimAssemblyPath, finalOuputFilename); if (!quiet) { Console.WriteLine("Created Exported functions in Assembly: {0}", finalOuputFilename); } if (createLib) { string defFile = Path.GetFileNameWithoutExtension(finalOuputFilename) + ".def"; string libFile = Path.GetFileNameWithoutExtension(finalOuputFilename) + ".lib"; File.WriteAllLines(defFile, exports); Lib.ExecNoRedirections("/NOLOGO /machine:{0} /def:{1} /OUT:{2}", platform, defFile, libFile); } if (headerFilename != null) { foreach (var e in enumTypeDefs) { functions.Insert(1, e.Value); } File.WriteAllLines(headerFilename, functions); } return(0); }
private ProcessUtility Exec(string script, string currentDirectory) { var cmdexe = new ProcessUtility("cmd.exe"); if (script.Contains("\r")) { script = @"@echo off @setlocal @cd ""{0}"" ".format(currentDirectory) + script; var scriptpath = WriteTempScript(script); cmdexe.Exec("/c {0}", scriptpath); } else { cmdexe.Exec("/c {0}", script); } return cmdexe; }
private int main(string[] args) { var options = args.Switches(); var parameters = args.Parameters(); #region Parse Options try { foreach (string arg in options.Keys) { IEnumerable<string> argumentParameters = options[arg]; switch (arg) { /* global switches */ case "load-config": // all ready done, but don't get too picky. break; case "nologo": this.Assembly().SetLogo(""); break; case "verbose": verbose = true; break; case "help": return Help(); case "cert-file": certFile = argumentParameters.First(); break; case "cert-pass": certPass = argumentParameters.First(); break; case "msm-dir": msmDir = argumentParameters.First(); break; case "version": version = argumentParameters.First(); break; } } Logo(); #endregion _candle = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("candle.exe")); _light = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("light.exe")); _signTool = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("signTool.exe")); var pfxStore = PfxStoreLoader.Load(certFile, certPass); if (pfxStore != null) { var codeSigningCert = pfxStore.FindCodeSigningCert(); if (codeSigningCert == null) return Fail("No code signing certificate found."); } else { return Fail("Couldn't open the certificate file."); } var files = Directory.EnumerateFiles(msmDir, "*.msm", SearchOption.TopDirectoryOnly); var groups = from f in files let fi = new FileInfo(f) where fi.Name.StartsWith("Microsoft") && !fi.Name.Contains("Debug") let version = new String(fi.Name.Split('_')[1].Substring(2).TakeAllBut(1).ToArray()) group f by version into versions select new { Version = versions.Key, ArchGroups = (from a in versions let possArch = new String(a.TakeAllBut(4).TakeFromEnd(3).ToArray()) group a by possArch into archs select new { Arch = archs.Key, Files = archs }) }; foreach (var g in groups) { var vers = g.Version; if (version == null || version.ExtendVersion() == vers.ExtendVersion()) { foreach (var a in g.ArchGroups) { Console.WriteLine("Building {0} for {1}".format(vers, a.Arch)); var outputFile = "{0}-{1}-{2}.msi".format("VC", vers.ExtendVersion(), a.Arch); XDocument wix; var huid = new Huid("Visual C/C++ Runtime Library", vers.ExtendVersion(), a.Arch, ""); using (var reader = new StringReader(Resources.WixTemplate)) { wix = XDocument.Load(reader); } var productTag = wix.Descendants("Product").First(); var targetDir = (from d in productTag.Descendants() where d.Name == "Directory" && d.Attribute("Id").Value == "TARGETDIR" select d).First(); productTag.SetAttributeValue("Name", "Visual C/C++ Runtime Library"); productTag.SetAttributeValue("Version", vers.ExtendVersion()); productTag.SetAttributeValue("Manufacturer", "Microsoft"); productTag.SetAttributeValue("Id", huid.ToString()); int counter = 0; var ids = new List<int>(); foreach (var f in a.Files) { targetDir.Add( new XElement("Merge", new XAttribute("Id", "VC" + counter), new XAttribute("SourceFile", f), new XAttribute("DiskId", "1"), new XAttribute("Language", "0"))); ids.Add(counter); counter++; } var feature = productTag.Descendants("Feature").First(); foreach (var i in ids) { feature.Add( new XElement("MergeRef", new XAttribute("Id", "VC" + i))); } var packageTag = productTag.Descendants("Package").First(); packageTag.SetAttributeValue("Platform", a.Arch); //add the Wix namespace XNamespace wixNS = "http://schemas.microsoft.com/wix/2006/wi"; foreach (var n in wix.Descendants()) { n.Name = wixNS + n.Name.LocalName; } var tempPrefix = Path.GetTempFileName(); File.WriteAllText(tempPrefix + ".wxs", wix.ToString()); if (_candle.Exec("-nologo -sw1075 -out {0}.wixobj {0}.wxs", tempPrefix) != 0) return Fail(_candle.StandardOut); //we suppress the lack of UpgradeCode warning since we don't use them if (_light.Exec("-nologo -sw1076 -out {1} {0}.wixobj", tempPrefix, outputFile) != 0) return Fail(_light.StandardOut); if (!signFile(outputFile)) return Fail("Couldn't sign file"); } } } } catch (ConsoleException e) { return Fail(" {0}", e.Message); } catch (Exception e) { Console.WriteLine(e.StackTrace); return Fail(" {0}", e.Message); } return 0; }
public void CreateMSILBinary(TestTarget binary, string binaryTemplate, string extension, string arch, string commandLine, List <string> autopkgFiles) { var outputPath = Path.Combine(this.tempFolder, arch); if (binary.Built) { return; } foreach (var dep in binary.Dependencies) { CreateDLL(dep, arch, autopkgFiles); } if (binary.Ignore) { return; } //Console.WriteLine("Building Binary [{0}-{1}]", binary.Name, binary.Version); //var importLibrary = new StringBuilder(); var callLibrary = new StringBuilder(); foreach (var dll in binary.Dependencies) { //importLibrary.Append(LibraryReferenceTemplate.Replace("[$LIBNAME]", dll.Name).Replace("[$LIBVERSION]", dll.Version).Replace("[$PUBLICKEYTOKEN]", publicKeyToken).Replace("[$ARCH]", arch)); callLibrary.Append(Resources.MSILLibraryFunctionCallTemplate.Replace("[$LIBNAME]", dll.Name).Replace("[$LIBVERSION]", dll.Version)); } var tempFolder = Path.Combine(Path.GetTempPath(), binary.Name + "-" + binary.Version); Directory.CreateDirectory(tempFolder); var outputBinaryFolder = Path.Combine(outputPath, binary.Name + "-" + binary.Version); Directory.CreateDirectory(outputBinaryFolder); Environment.CurrentDirectory = outputBinaryFolder; foreach (var dll in binary.Dependencies) { var currentRef = Path.Combine(Path.GetTempPath(), dll.Name + "-" + dll.Version); commandLine = @"{0} /reference:""{1}""".format(commandLine, Path.Combine(currentRef, dll.Name + ".dll")); } var binaryText = binaryTemplate.Replace("[$LIBNAME]", binary.Name).Replace("[$LIBVERSION]", binary.Version).Replace("[$CALL_LIBRARY]", callLibrary.ToString()).Replace("[$PUBLICKEYTOKEN]", publicKeyToken).Replace("[$ARCH]", arch); var tempCSFile = Path.Combine(tempFolder, binary.Name + ".cs"); File.WriteAllText(tempCSFile, binaryText); // compile it var outputBinary = Path.Combine(outputBinaryFolder, binary.Name + extension); if (csc_msil.Exec(commandLine, outputBinary, pkPath, tempCSFile) != 0) { throw new Exception(csc_msil.StandardOut); } binary.Built = true; //TODO: create autopkg }
private void CreateBinary(TestTarget binary, string binaryTemplate, string extension, string arch, string commandLine, List <string> autopkgFiles) { var outputPath = Path.Combine(this.tempFolder, arch); if (binary.Built) { return; } foreach (var dep in binary.Dependencies) { CreateDLL(dep, arch, autopkgFiles); } if (binary.Ignore) { return; } //Console.WriteLine("Building Binary [{0}-{1}]", binary.Name, binary.Version); var importLibrary = new StringBuilder(); var callLibrary = new StringBuilder(); foreach (var dll in binary.Dependencies) { importLibrary.Append(Resources.LibraryReferenceTemplate.Replace("[$LIBNAME]", dll.Name).Replace("[$LIBVERSION]", dll.Version).Replace("[$PUBLICKEYTOKEN]", publicKeyToken).Replace("[$ARCH]", arch)); callLibrary.Append(Resources.LibraryFunctionCallTemplate.Replace("[$LIBNAME]", dll.Name).Replace("[$LIBVERSION]", dll.Version).Replace("[$PUBLICKEYTOKEN]", publicKeyToken).Replace("[$ARCH]", arch)); } var tempFolder = Path.Combine(Path.GetTempPath(), binary.Name + "-" + binary.Version); Directory.CreateDirectory(tempFolder); var outputBinaryFolder = Path.Combine(outputPath, binary.Name + "-" + binary.Version); Directory.CreateDirectory(outputBinaryFolder); Environment.CurrentDirectory = outputBinaryFolder; foreach (var dll in binary.Dependencies) { var defFile = Resources.ModuleDefinitionFileTemplate + "print_" + dll.Name; File.WriteAllText(Path.Combine(tempFolder, dll.Name + ".def"), defFile); if (lib.Exec("/out:{0} /def:{1} /machine:{2}", Path.Combine(tempFolder, dll.Name + ".lib"), Path.Combine(tempFolder, dll.Name + ".def"), arch == "x86" ? arch : "x64") != 0) { throw new Exception(lib.StandardOut); } commandLine = @"{0} /link ""{1}""".format(commandLine, Path.Combine(tempFolder, dll.Name + ".lib")); } // make C file var binaryText = binaryTemplate.Replace("[$LIBNAME]", binary.Name).Replace("[$LIBVERSION]", binary.Version).Replace("[$IMPORT_LIBRARY]", importLibrary.ToString()).Replace("[$CALL_LIBRARY]", callLibrary.ToString()).Replace("[$PUBLICKEYTOKEN]", publicKeyToken).Replace("[$ARCH]", arch); var tempCFile = Path.Combine(tempFolder, binary.Name + ".c"); File.WriteAllText(tempCFile, binaryText); // compile it var outputBinary = Path.Combine(outputBinaryFolder, binary.Name + extension); if (cl.Exec(commandLine, tempCFile, outputBinary) != 0) { throw new Exception(cl.StandardOut); } binary.Built = true; //TODO create the autopkg file var propSheet = new PropertySheet(); //propSheet.Keys }
private int main(string[] args) { bool mergeAssemblies = false; Dictionary<string, IEnumerable<string>> options = args.Switches(); IEnumerable<string> parameters = args.Parameters(); foreach (string arg in options.Keys) { IEnumerable<string> argumentParameters = options[arg]; switch (arg) { case "nologo": this.Assembly().SetLogo(""); quiet = true; break; case "merge": mergeAssemblies = true; break; case "keep-temp-files": keepTempFiles = true; break; case "rescan-tools": ProgramFinder.IgnoreCache = true; break; case "debug": debug = true; break; case "sampleusage": SampleUsage(); return 0; case "sampleclass": SampleClass(); return 0; case "output-filename": finalOuputFilename = argumentParameters.FirstOrDefault(); break; case "create-header": headerFilename = argumentParameters.FirstOrDefault(); break; case "platform": platform = (argumentParameters.FirstOrDefault() ?? "x86").Equals("x64", StringComparison.CurrentCultureIgnoreCase) ? "x64" : "x86"; break; case "create-lib": createLib = true; break; case "help": Help(); return 0; default: Logo(); return Fail("Error: unrecognized switch:{0}", arg); } } if (parameters.Count() != 1) { Help(); return 0; } if (!quiet) { Logo(); } var ILDasm = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("ildasm.exe", "4.0.30319.1")); var ILAsm = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("ilasm.exe", "4.0.30319.1")); var Lib = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("lib.exe")); string originalAssemblyPath = parameters.First().GetFullPath(); if (!File.Exists(originalAssemblyPath)) { return Fail("Error: the specified original assembly \r\n [{0}]\r\ndoes not exist.", originalAssemblyPath); } string shimAssemblyPath = GenerateShimAssembly(originalAssemblyPath); finalOuputFilename = string.IsNullOrEmpty(finalOuputFilename) ? (mergeAssemblies ? originalAssemblyPath : shimAssemblyPath) : finalOuputFilename; string temporaryIlFilename = shimAssemblyPath + ".il"; int rc = ILDasm.Exec(@"/text /nobar /typelist ""{0}""", shimAssemblyPath); if (0 != rc) { return Fail("Error: unable to disassemble the temporary assembly\r\n [{0}]\r\nMore Information:\r\n{1}", shimAssemblyPath, ILDasm.StandardOut); } Delete(shimAssemblyPath); // eliminate it regardless of result. string ilSource = Regex.Replace(ILDasm.StandardOut, @"IL_0000:.*ldstr.*\""(?<x>.*)\""", "${x}"); if (mergeAssemblies) { int start = ilSource.IndexOf("\r\n.method"); int end = ilSource.LastIndexOf("// end of global method"); ilSource = ilSource.Substring(start, end - start); // arg! needed this to make sure the resources came out. grrr rc = ILDasm.Exec(@"/nobar /typelist ""{0}"" /out=""{1}""", originalAssemblyPath, temporaryIlFilename); rc = ILDasm.Exec(@"/nobar /text /typelist ""{0}""", originalAssemblyPath); if (0 != rc) { return Fail("Error: unable to disassemble the target assembly\r\n [{0}]\r\nMore Information:\r\n{1}", shimAssemblyPath, ILDasm.StandardOut); } string ilTargetSource = ILDasm.StandardOut; start = Math.Min(ilTargetSource.IndexOf(".method"), ilTargetSource.IndexOf(".class")); ilSource = ilTargetSource.Substring(0, start) + ilSource + ilTargetSource.Substring(start); } File.WriteAllText(temporaryIlFilename, ilSource); rc = ILAsm.Exec(@"{3} /dll {2} /output={0} ""{1}""", shimAssemblyPath, temporaryIlFilename, debug ? "/debug" : "", platform == "x64" ? "/X64" : ""); if (!debug) { Delete(temporaryIlFilename); // delete temp file regardless of result. } if (0 != rc) { return Fail("Error: unable to assemble the merged assembly\r\n [{0}]\r\n [{1}]\r\nMore Information:\r\n{2}", shimAssemblyPath, temporaryIlFilename, ILAsm.StandardError); } if (originalAssemblyPath.Equals(finalOuputFilename, StringComparison.CurrentCultureIgnoreCase)) { File.Delete(originalAssemblyPath + ".orig"); File.Move(originalAssemblyPath, originalAssemblyPath + ".orig"); } File.Delete(finalOuputFilename); File.Move(shimAssemblyPath, finalOuputFilename); if (!quiet) { Console.WriteLine("Created Exported functions in Assembly: {0}", finalOuputFilename); } if (createLib) { string defFile = Path.GetFileNameWithoutExtension(finalOuputFilename) + ".def"; string libFile = Path.GetFileNameWithoutExtension(finalOuputFilename) + ".lib"; File.WriteAllLines(defFile, exports); Lib.ExecNoRedirections("/NOLOGO /machine:{0} /def:{1} /OUT:{2}", platform, defFile, libFile); } if (headerFilename != null) { foreach (var e in enumTypeDefs) { functions.Insert(1, e.Value); } File.WriteAllLines(headerFilename, functions); } return 0; }
/// <summary> /// The (non-static) startup method /// </summary> /// <param name = "args"> /// The command line arguments. /// </param> /// <returns> /// Process return code. /// </returns> protected override int Main(IEnumerable<string> args) { try { pkgMgr = new PackageManager(); #region command line parsing // default: var options = args.Switches(); var parameters = args.Parameters(); foreach (var arg in options.Keys) { var argumentParameters = options[arg]; switch (arg) { /* options */ /* global switches */ case "load-config": // all ready done, but don't get too picky. break; case "nologo": this.Assembly().SetLogo(string.Empty); break; case "show-tools": showTools = Boolean.Parse(argumentParameters.First()); break; case "help": return Help(); default: if (arg.StartsWith("package-")) { var argName = arg.Substring(8); var argValue = argumentParameters.First(); switch (argName) { case "name": package.PackageName = argValue; break; case "version": package.PackageVersion = argValue; break; case "arch": package.PackageArch = argValue; break; case "icon": package.IconPath = argValue; break; case "short-desc": package.ShortDescriptionPath = argValue; break; case "description": package.DescriptionPath = argValue; break; case "author-version": package.AuthorVersion = argValue; break; case "display-name": package.DisplayName = argValue; break; case "policy": package.BindingPolicy = argValue; break; case "license": package.LicensePath = argValue; break; case "license-url": package.LicenseUrlEntry = argValue; break; case "orig-location": package.Location = argValue; break; case "feed-location": package.Feed = argValue; break; default: throw new ConsoleException(Resources.UnknownParameter, arg); } } else if (arg.StartsWith("identity-")) { var argName = arg.Substring(9); var argValue = argumentParameters.First(); switch (argName) { case "cert-file": package.CertificateFile = argValue; break; case "cert-pass": certificatePassword = argValue; break; case "email": package.PubEmail = argValue; break; case "website": package.PubWebsite = argValue; break; default: throw new ConsoleException(Resources.UnknownParameter, arg); } } //we do else if (arg.StartsWith("dependency-")) { var argName = arg.Substring(11); var argValue = argumentParameters.First(); ; switch (argName) { case "add": package.DependencyNames.Add(argValue); break; default: throw new ConsoleException(Resources.UnknownParameter, arg); } } else if (arg.StartsWith("app-")) { if (package.Apps == null) package.Apps = new App(); parseAppArgument(arg.Substring(4), argumentParameters.First()); } else if (arg.StartsWith("sharedlib-")) { if (package.SharedLibs == null) package.SharedLibs = new SharedLib(); parseSharedLibArgument(arg.Substring(10), argumentParameters.First()); } else { throw new ConsoleException(Resources.UnknownParameter, arg); } break; } } Logo(); /* if (parameters.Count() < 1) { throw new ConsoleException(Resources.MissingCommand); } */ #endregion // GS01: I'm putting this in here so that feed resoltion happens before we actually get around to doing something. // Look into the necessity later. Tasklet.WaitforCurrentChildTasks(); #region Tool Scanning Console.Write(Resources.ToolLookup); _candle = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("candle.exe")); _light = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("light.exe")); _mt = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("mt.exe")); _makecat = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("makecat.exe")); _al = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("al.exe")); _signTool = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("signTool.exe")); _sn = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("sn.exe")); _pktExtract = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("pktExtract.exe")); if (_candle.Executable == null) errors.Add(Resources.MissingCandle); if (_light.Executable == null) errors.Add(Resources.MissingLight); if (_mt.Executable == null) errors.Add(Resources.MissingMt); if (_makecat.Executable == null) errors.Add(Resources.MissingMakeCat); if (_al.Executable == null) errors.Add(Resources.MissingAl); if (_signTool.Executable == null) errors.Add(Resources.MissingSignTool); if (_sn.Executable == null) errors.Add(Resources.MissingSn); if (_pktExtract.Executable == null) errors.Add(Resources.MissingPktExtract); if (errors.AreFatal()) { throw new ConsoleException(errors.StringOut()); } Console.WriteLine(Resources.Finished); if (showTools) { Console.WriteLine("Tools:"); Console.WriteLine(_candle.Executable); Console.WriteLine(_light.Executable); Console.WriteLine(_mt.Executable); Console.WriteLine(_makecat.Executable); Console.WriteLine(_al.Executable); Console.WriteLine(_signTool.Executable); Console.WriteLine(_sn.Executable); } #endregion Console.WriteLine(Resources.ScanningInstalledPackages); var installedPackages = pkgMgr.GetInstalledPackages(new PackageManagerMessages { PackageScanning = (progress) => { Resources.Scanning.PrintProgressBar(progress); } }); installedPackages.Wait(); // the progress bar never sends in a line break Console.WriteLine(); //TODO check for invalid file paths //TODO check for pre-signed files and whether they're properly signed //TODO make sure files in app roles are proper children //TODO this doesn't work if the packages are a superceding version of the one given //TODO this doesn't work if the packages are in the same directory //get the dependencies and Assemblies foreach (var dep in package.DependencyNames) { var depPackage = (from p in installedPackages.Result where p.CosmeticName.IsWildcardMatch(dep) orderby p.Version descending select p).FirstOrDefault(); if (depPackage == null) { errors.Add(Resources.DepNotSatifiable.format(dep)); } else { package.DependencyInfo.Add(depPackage); } } //TODO make sure the numbers are not larger than the max a part of a version string var policyRegex = new Regex(@"^policy\.\d{1,5}\.\d{1,5}\.\S+$"); var dependentAssemblies = from p in package.DependencyInfo from a in p.Assemblies where !a.Type.Contains("policy") && !policyRegex.IsMatch(a.Name) select a; #region Sanity checking primarily //let's check for valid roles! if (package.SharedLibs == null && package.Apps == null) errors.Add(Resources.NoRoles); if (package.PackageArch == null || (!ValidArchs.Contains(package.PackageArch.ToLower()) && package.PackageArch != "auto")) errors.Add(Resources.MissingPackageArch); if (package.PackageVersion == null || !package.PackageVersion.IsValidVersion() && package.PackageVersion != "auto") errors.Add(Resources.MissingPackageVersion); if ((package.PackageArch == "auto" || package.PackageVersion == "auto") && firstBinFile == null) errors.Add(Resources.NoBinaryFileProvided); //get Arch and Version if it's auto if (package.PackageArch == "auto") { if (firstBinFile != null) { var binType = ProgramFinder.GetExeType(firstBinFile); if (binType.HasFlag(ExecutableInfo.any) || binType.HasFlag(ExecutableInfo.managed)) package.PackageArch = "any"; else if (binType.HasFlag(ExecutableInfo.x86)) package.PackageArch = "x86"; else if (binType.HasFlag(ExecutableInfo.x64)) package.PackageArch = "x64"; else errors.Add(Resources.NoArchDiscovered.format(firstBinFile)); } } if (package.PackageVersion == "auto") { if (firstBinFile != null) { var versionStr = ProgramFinder.GetToolVersion(firstBinFile); if (versionStr == null || !versionStr.IsValidVersion()) errors.Add(Resources.NoVersionDiscovered.format(firstBinFile)); else package.PackageVersion = versionStr; } } //TODO make sure the name is valid! //make sure the major minors given are valid if (package.SharedLibs != null) { foreach (var i in package.SharedLibs.MajorMinorsToReplace) { if (!i.IsValidMajorMinorVersion()) { errors.Add(Resources.InvalidMajorMinor.format(i)); } } } //load and check pfx file var pfxStore = PfxStoreLoader.Load(package.CertificateFile, certificatePassword); if (pfxStore == null) errors.Add(Resources.InvalidPfx); else { var codeSigningCert = pfxStore.FindCodeSigningCert(); if (codeSigningCert == null) errors.Add(Resources.NoCodeSigningCert); else { if ((package.PubToken = codeSigningCert.PublicKeyTokenAsString()) == null) { errors.Add(Resources.FailedPktExtraction); } var nameParts = codeSigningCert.GetSubjectNameParts(); if (nameParts.ContainsKey("CN")) { package.PubName = nameParts["CN"]; } else { errors.Add(Resources.NoNameExtracted.format(package.CertificateFile)); } if (package.PubEmail == "auto") { if (nameParts.ContainsKey("E")) { package.PubEmail = nameParts["E"]; } else { errors.Add(Resources.NoPubEmailFound.format(package.CertificateFile)); } } } } if (package.PubEmail != null && !package.PubEmail.IsEmail()) { errors.Add(Resources.InvalidEmail.format(package.PubEmail)); } if (package.IconPath != null) { try { var iconFile = File.ReadAllBytes(package.IconPath); using (var bytes = new MemoryStream(iconFile)) { Image image = Image.FromStream(bytes); if (image.RawFormat != ImageFormat.Png || image.Height != REQUIRED_ICON_HEIGHT || image.Width != REQUIRED_ICON_WIDTH) { errors.Add(Resources.InvalidIconFile. format(package.IconPath, REQUIRED_ICON_WIDTH, REQUIRED_ICON_HEIGHT)); } } package.Icon = Convert.ToBase64String(iconFile); } catch (OutOfMemoryException) { errors.Add(Resources.InvalidIconFile. format(package.IconPath, REQUIRED_ICON_WIDTH, REQUIRED_ICON_HEIGHT)); } catch (IOException) { errors.Add(Resources.FailedIconFileOpen.format(package.IconPath)); } } else { package.Icon = Convert.ToBase64String(Resources.blankicon); } if (package.ShortDescriptionPath != null) { try { package.ShortDescription = File.ReadAllText(package.ShortDescriptionPath); if (package.ShortDescriptionPath.Length > MAX_SUMMARY_DESCRIPTION_LENGTH) { errors.Add(Resources.ShortDescriptionTooLong. format(package.ShortDescriptionPath, MAX_SUMMARY_DESCRIPTION_LENGTH)); } } catch (NotSupportedException) { errors.Add(Resources.InvalidShortDescriptionFile.format(package.ShortDescriptionPath)); } catch (IOException) { errors.Add(Resources.FailedShortDescriptionFileOpen.format(package.ShortDescriptionPath)); } } if (package.DescriptionPath != null) { try { package.Description = File.ReadAllText(package.DescriptionPath); } catch (NotSupportedException) { errors.Add(Resources.InvalidDescriptionFile.format(package.DescriptionPath)); } catch (IOException) { errors.Add(Resources.FailedDescriptionFileOpen.format(package.DescriptionPath)); } } if (package.PublishDate != null) { try { DateTime.Parse(package.PublishDate); } catch (FormatException) { errors.Add(Resources.InvalidPublishDate.format(package.PublishDate)); } } else { package.PublishDate = DateTime.Now.ToShortDateString(); } if (package.LicensePath != null) { try { package.LicenseText = File.ReadAllText(package.LicensePath); if (package.LicenseUrlEntry != null) { try { var uri = new Uri(package.LicenseUrlEntry); if (!uri.IsHttpScheme()) errors.Add(Resources.InvalidLicenseUrlScheme.format(package.LicenseUrlEntry)); package.LicenseUrl = package.CreateUrl(package.LicenseUrlEntry, "license"); } catch (UriFormatException) { errors.Add(Resources.InvalidLicenseUrl.format(package.LicenseUrlEntry)); } } } catch (NotSupportedException) { errors.Add(Resources.InvalidLicenseText.format(package.LicensePath)); } catch (IOException) { errors.Add(Resources.FailedLicenseFileOpen.format(package.LicensePath)); } } else { if (package.LicenseUrlEntry != null) { errors.Add(Resources.LicenseUrlWithoutText, false); } } if (package.Feed != null) { try { var uri = new Uri(package.Feed); if (!uri.IsHttpScheme()) errors.Add(Resources.InvalidFeedUrlScheme.format(package.Feed)); package.FeedUrl = package.CreateUrl(package.Feed, "feed_location"); } catch (UriFormatException) { errors.Add(Resources.InvalidFeedUrl.format(package.Feed)); } } if (package.Location != null) { try { var uri = new Uri(package.Location); if (!uri.IsHttpScheme()) errors.Add(Resources.InvalidOriginalUrlScheme.format(package.Location)); package.LocationUrl = package.CreateUrl(package.Location, "original_location"); } catch (UriFormatException) { errors.Add(Resources.InvalidOriginalUrl.format(package.Location)); } } if (errors.AreFatal()) { throw new ConsoleException(errors.StringOut()); } foreach (Match m in Regex.Matches(package.BindingPolicy, @"{{(\$CURRENT-\d+)}}")) { var i = m.Groups[1].Value; var two = i.Split('-'); package.BindingPolicy = package.BindingPolicy.Replace(m.Value, (package.PackageVersion.VersionStringToUInt64() - UInt64.Parse(two[1])).UInt64VersiontoString()); } if (package.BindingPolicy.IsValidVersion()) { if (package.BindingPolicy.VersionStringToUInt64() >= package.PackageVersion.VersionStringToUInt64()) { errors.Add(Resources.BindingVersionTooHigh.format(package.BindingPolicy)); } else { package.BindingMin = package.BindingPolicy; package.BindingMax = package.BindingPolicy; } } else { var parts = package.BindingPolicy.Split('-'); bool ret = parts.Length == 2; for (int i = 0; ret && i < 2; i++) { ret &= parts[i].IsValidVersion(); } if (!ret) { errors.Add(Resources.InvalidPolicy.format(package.BindingPolicy)); } else { if (parts[0].VersionStringToUInt64() >= package.PackageVersion.VersionStringToUInt64()) { errors.Add(Resources.BindingVersionTooHigh.format(parts[0])); } if (parts[1].VersionStringToUInt64() >= package.PackageVersion.VersionStringToUInt64()) { errors.Add(Resources.BindingVersionTooHigh.format(parts[1])); } package.BindingMin = parts[0]; package.BindingMax = parts[1]; } } //find all the files that need to be found recursively if (package.Apps != null) { var wildcards = (from p in package.Apps.FilePaths where p.Contains("*") select p).ToList(); foreach (var w in wildcards) { package.Apps.FilePaths.AddRange(w.FindFilesSmarter(SearchOption.AllDirectories)); } //remove wildcards package.Apps.FilePaths.RemoveAll((fp) => fp.Contains("*")); //remove duplicates based on canonical path and make them relative var exeFiles = package.Apps.PrimaryExes.Values.Select((e) => e.ExeFile); var sharedLibFiles = package.SharedLibs.Assemblies.Values. SelectMany((a) => a.PrimaryFile.SingleItemAsEnumerable().Concat(a.OtherFiles)); package.Apps.FilePaths = package.Apps.FilePaths.Except(exeFiles.Concat(sharedLibFiles), new PathEqualityComparer()).Select((p) => Environment.CurrentDirectory.RelativePathTo(p)).ToList(); } if (errors.AreFatal()) { throw new ConsoleException(errors.StringOut()); } #endregion #region Handle Shared Libraries //first create the string of all the dependencies elements var sharedlib = package.SharedLibs; if (sharedlib != null) { Console.Write(Resources.SharedLibCreation); if (package.PackageArch != "any") { var dependencyStr = new StringBuilder(); foreach (var dep in dependentAssemblies) { dependencyStr.Append(DependencyEntry.Replace("[$LIBTYPE]", dep.Type).Replace("[$LIBNAME]", dep.Name). Replace("[$LIBVERSION]", dep.Version).Replace("[$ARCH]", dep.Arch). Replace("[$PUBLICKEYTOKEN]", dep.PublicKeyToken)); } foreach (var a in sharedlib.Assemblies.Values) { var manifestFilesString = new StringBuilder(); var filesString = new StringBuilder(); filesString.Append(FileEntry.Replace("[$FILE]", Path.GetFileName(a.PrimaryFile))); foreach (var f in a.OtherFiles) { filesString.Append(FileEntry.Replace("[$FILE]", Path.GetFileName(f))); } manifestFilesString.Append(SharedLibraryManifest.Replace("[$LIBNAME]", a.Name). Replace("[$LIBVERSION]", package.PackageVersion). Replace("[$DEPENDENCY]", dependencyStr.ToString()).Replace("[$PUBLICKEYTOKEN]", package.PubToken). Replace("[$ARCH]", package.PackageArch).Replace("[$FILES]", filesString.ToString())); a.Manifest = Path.Combine(new FileInfo(a.PrimaryFile).DirectoryName, a.PrimaryFile + ".manifest"); //TODO do file checking File.WriteAllText(a.Manifest, manifestFilesString.ToString()); // sign all the non-primary BinFiles var binFiles = from f in a.OtherFiles where Path.GetExtension(f) == ".exe" || Path.GetExtension(f) == ".dll" select f; foreach (var f in binFiles) { signFile(f); } //manifest created. Let's embed it. if (!createManifestAndEmbed(a.PrimaryFile)) { throw new ConsoleException(errors.StringOut()); } //sign the primary file if (!signFile(a.PrimaryFile)) throw new ConsoleException(errors.StringOut()); a.CatFile = a.PrimaryFile + ".cat"; if (!createAndSignCat(a.Manifest)) { throw new ConsoleException(errors.StringOut()); } //we're going to create the policy assemblies foreach (var p in package.SharedLibs.MajorMinorsToReplace) { var pa = new PolicyAssemblyDescription(p, a.Name); package.SharedLibs.PolicyAssemblies.Add(pa); var paManifestString = PublisherConfiguration.Replace("[$ASSMNAME]", a.Name). Replace("[$LIBMAJORMINOR]", p).Replace("[$PUBLICKEYTOKEN]", package.PubToken). Replace("[$LIBVERSION]", package.PackageVersion).Replace("[$ARCH]", package.PackageArch). Replace("[$OLDVERSION]", package.BindingPolicy); pa.Manifest = Path.Combine(new FileInfo(a.PrimaryFile).DirectoryName, pa.Name + ".manifest"); File.WriteAllText(pa.Manifest, paManifestString); pa.CatFile = pa.Manifest.Replace(".manifest", "") + ".cat"; if (!createAndSignCat(pa.Manifest)) throw new ConsoleException(errors.StringOut()); } } } else { // it's .NET foreach (var a in sharedlib.Assemblies.Values) { if (!StrongName(a.PrimaryFile)) { throw new ConsoleException(errors.StringOut()); } if (!signFile(a.PrimaryFile)) throw new ConsoleException(errors.StringOut()); foreach (var p in package.SharedLibs.MajorMinorsToReplace) { var pa = new PolicyAssemblyDescription(p, a.Name); package.SharedLibs.PolicyAssemblies.Add(pa); pa.PrimaryFile = Path.Combine(new FileInfo(a.PrimaryFile).DirectoryName, pa.Name + ".dll"); var paManifestString = MSILPublisherConfiguration.Replace("[$ASSMNAME]", a.Name). Replace("[$PUBLICKEYTOKEN]", package.PubToken). Replace("[$LIBVERSION]", package.PackageVersion). Replace("[$OLDVERSION]", package.BindingPolicy); pa.Manifest = pa.PrimaryFile + ".config"; // cleanupFiles.Add(pa.Manifest); File.WriteAllText(pa.Manifest, paManifestString); if (!extractPublicKey()) throw new ConsoleException(errors.StringOut()); if (_al.Exec("/link:{0} /out:{1} /delaysign+ /keyfile:{2} /v:{3}", pa.Manifest, pa.PrimaryFile, publicKeyFile, package.PackageVersion) != 0) { errors.Add(Resources.FailedPolicyAssemblyBuild.format(pa.PrimaryFile)); throw new ConsoleException(errors.StringOut()); } if (!StrongName(pa.PrimaryFile)) { throw new ConsoleException(errors.StringOut()); } if (!signFile(pa.PrimaryFile)) { throw new ConsoleException(errors.StringOut()); } } } } Console.WriteLine(Resources.Finished); } #endregion #region Handle Apps var apps = package.Apps; if (apps != null) { Console.Write(Resources.AppCreation); if (package.PackageArch != "any") { //it's native var dependencyStr = new StringBuilder(); foreach (var dep in dependentAssemblies) { dependencyStr.Append(DependencyEntry.Replace("[$LIBTYPE]", dep.Type).Replace("[$LIBNAME]", dep.Name). Replace("[$LIBVERSION]", dep.Version).Replace("[$ARCH]", dep.Arch). Replace("[$PUBLICKEYTOKEN]", dep.PublicKeyToken)); } //we needs to add in the other assemblies in this package if (sharedlib != null) { foreach (var dep in sharedlib.Assemblies.Values) { dependencyStr.Append(DependencyEntry.Replace("[$LIBTYPE]", "win32"). Replace("[$LIBNAME]", dep.Name).Replace("[$LIBVERSION]", package.PackageVersion). Replace("[$ARCH]", package.PackageArch).Replace("[$PUBLICKEYTOKEN]", package.PubToken)); } } foreach (var e in apps.PrimaryExes.Values) { var configFilename = e.ExeFile + ".config"; File.WriteAllText(configFilename, dependencyStr.ToString()); if (!embedManifest(e.ExeFile, configFilename)) //we can't keep working on this one but we'll try the rest before failing continue; signFile(e.ExeFile); } } else { //it's .net foreach (var e in apps.PrimaryExes.Values) { if (!StrongName(e.ExeFile)) { //we can't keep working on this one but we'll try the rest before failing continue; } signFile(e.ExeFile); } } } if (errors.AreFatal()) throw new ConsoleException(errors.StringOut()); Console.WriteLine(Resources.Finished); #endregion #region Write Msi OutToFile Console.Write(Resources.CreatingMSI); var tempPrefix = Path.GetTempFileName(); File.WriteAllText(tempPrefix + ".wxs", package.ConvertToWix()); var outputFile = "{0}-{1}-{2}.msi".format(package.PackageName, package.PackageVersion, package.PackageArch); /* if (!_dontCreateMsi) { */ //we suppress the lack of UpgradeCode warning since we don't use them if (_candle.Exec("-nologo -sw1075 -out {0}.wixobj {0}.wxs", tempPrefix) != 0) errors.Add(Resources.FailedCandleExe.format(_candle.StandardOut)); if (errors.AreFatal()) throw new ConsoleException(errors.StringOut()); //we suppress the lack of UpgradeCode warning since we don't use them if (_light.Exec("-nologo -sw1076 -out {1} {0}.wixobj", tempPrefix, outputFile) != 0) errors.Add(Resources.FailedLightExe.format(_light.StandardOut)); if (errors.AreFatal()) throw new ConsoleException(errors.StringOut()); signFile(outputFile); if (errors.AreFatal()) throw new ConsoleException(errors.StringOut()); Console.WriteLine(Resources.Finished); #endregion Console.WriteLine(errors.StringOut()); } catch (ConsoleException failure) { CancellationTokenSource.Cancel(); Fail("{0}\r\n\r\n {1}", failure.Message, Resources.ForCommandLineHelp); } finally { foreach (var f in cleanupFiles) { File.Delete(f); } } return 0; }
public static string PublicKeyTokenAsString(this X509Certificate2 cert) { var tempfile = Path.GetTempFileName() + ".cer"; File.WriteAllBytes(tempfile, cert.GetRawCertData()); var _pktExtract = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("pktExtract.exe")); _pktExtract.Exec("-nologo -quiet {0}", tempfile); var publicKeyToken = _pktExtract.StandardOut.Trim(); File.Delete(tempfile); return publicKeyToken; }
/// <summary> /// The (non-static) startup method /// </summary> /// <param name = "args"> /// The command line arguments. /// </param> /// <returns> /// Process return code. /// </returns> protected override int Main(IEnumerable<string> args) { try { _package.CertificateFile = _certificateSettings["#CurrentCertificate"].EncryptedStringValue; PackageManager.Instance.Connect("autopackage"); if (!PackageManager.Instance.IsReady.WaitOne(5000)) { //Verbose("# not connected..."); throw new ConsoleException("# Unable to connect to CoApp Service."); } _pkgMgr = PackageManager.Instance; PropertySheet propSheet; _pkgMgr.AddFeed(Environment.CurrentDirectory); var exceptions = new List<Exception>(); #region command line parsing var configLoaded = false; // default: var options = args.Switches(); var parameters = args.Parameters(); foreach (var arg in options.Keys) { var argumentParameters = options[arg]; switch (arg) { /* options */ /* global switches */ case "load-config": // all ready done, but don't get too picky. break; case "load": propSheet = PropertySheet.Load(argumentParameters.First()); PropSheetParser parser = new PropSheetParser(_package); //parser.Parse(propSheet); configLoaded = true; break; case "nologo": this.Assembly().SetLogo(string.Empty); break; case "show-tools": _showTools = Boolean.Parse(argumentParameters.First()); break; case "password": _package.CertificatePassword = argumentParameters.First(); break; case "autosign": _autosign = true; break; case "remember": _remember = true; break; case "accept-old-bs": _acceptOldBs = true; break; case "help": return Help(); default: throw new ConsoleException(Resources.UnknownParameter, arg); } } Logo(); if (!configLoaded) throw new ConsoleException(Resources.NoConfigFileLoaded); #endregion // GS01: I'm putting this in here so that feed resoltion happens before we actually get around to doing something. // Look into the necessity later. // Tasklet.WaitforCurrentChildTasks(); #region Tool Scanning Console.Write(Resources.ToolLookup); _candle = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("candle.exe")); _light = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("light.exe")); _mt = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("mt.exe")); _makecat = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("makecat.exe")); _al = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("al.exe")); _signTool = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("signTool.exe")); _sn = new ProcessUtility(ProgramFinder.ProgramFilesAndDotNet.ScanForFile("sn.exe")); if (_candle.Executable == null) exceptions.Add(CreateEndUserException(144)); if (_light.Executable == null) exceptions.Add(CreateEndUserException(145)); if (_mt.Executable == null) exceptions.Add(CreateEndUserException(146)); if (_makecat.Executable == null) exceptions.Add(CreateEndUserException(147)); if (_al.Executable == null) exceptions.Add(CreateEndUserException(148)); if (_signTool.Executable == null) exceptions.Add(CreateEndUserException(149)); if (_sn.Executable == null) exceptions.Add(CreateEndUserException(150)); if (exceptions.Count > 0) { throw new AggregateException(exceptions); } Console.WriteLine(Resources.Finished); if (_showTools) { Console.WriteLine("Tools:"); Console.WriteLine(_candle.Executable); Console.WriteLine(_light.Executable); Console.WriteLine(_mt.Executable); Console.WriteLine(_makecat.Executable); Console.WriteLine(_al.Executable); Console.WriteLine(_sn.Executable); Console.WriteLine(_signTool.Executable); } ReadPassword(); #endregion Console.WriteLine(Resources.ScanningInstalledPackages); //TODO What will happen when we have feeds in other places???? IEnumerable<Package> allPackages = null; /* var tsk = _pkgMgr.GetPackagesInScanLocations(new PackageManagerMessages { PackageScanning = (progress) => Resources.Scanning.PrintProgressBar(progress) }).ContinueWith((antecedent) => { allPackages = antecedent.Result; " ".PrintProgressBar(100); Console.WriteLine("\r"); },TaskContinuationOptions.AttachedToParent); tsk.Wait(); */ //find all the files that need to be found recursively //verify that the lefthand side of includes are valid subpaths foreach (var i in _package.AllIncludes.Keys) { foreach (var include in _package.AllIncludes[i]) { if (!include.L.IsSimpleSubPath()) { exceptions.Add(CreateEndUserPropertyException(i.IncludeToProp[include.L], 160, include.L)); } } } if (_package.Apps != null) { if (_package.Apps.GlobalBinEntry != null) { if (!_package.Apps.GlobalBinEntry.IsBoolean()) { exceptions.Add(CreateEndUserPropertyException(_package.Apps.GlobalBinEntryProp, 152)); } else { _package.Apps.GlobalBin = Boolean.Parse(_package.Apps.GlobalBinEntry); } } _package.Apps.EvaluateIncludes(); //set up the input files foreach (var e in _package.Apps.PrimaryExes) { var input = (from a in _package.Apps.FinalInclude where a.R.Path.IsWildcardMatch(e.ExeFile) select a).FirstOrDefault(); if (input == null) { if (!File.Exists(e.ExeFile)) exceptions.Add(CreateEndUserException(153, e.ExeFile)); else { //Exefile wasn't found in the Includes but it really does exist _package.Apps.FinalInclude = _package.Apps.FinalInclude.Concat(new OutputTup { L = new FileInfo(e.ExeFile.Original).Name, R = e.ExeFile }.SingleItemAsEnumerable()); } } else { e.ExeFile = input.R; } if (e.GlobalBinEntry != null) { if (!e.GlobalBinEntry.IsBoolean()) { exceptions.Add(CreateEndUserPropertyException(e.GlobalBinEntryProp, 152)); } else { e.GlobalBin = Boolean.Parse(e.GlobalBinEntry); } } } } if (_package.SharedLibs != null) { var shared = _package.SharedLibs; var sharedEntryValid = false; if (shared.GlobalEntry != null) { if (!shared.GlobalEntry.IsBoolean()) { exceptions.Add(CreateEndUserPropertyException(shared.GlobalEntryProp, 170)); } else { shared.Global = Boolean.Parse(shared.GlobalEntry); sharedEntryValid = true; } } foreach (var a in _package.SharedLibs.Assemblies) { a.EvaluateIncludes(true); if (a.GlobalEntry != null) { if (!a.GlobalEntry.IsBoolean()) { exceptions.Add(CreateEndUserPropertyException(a.GlobalEntryProp, 170)); } else { a.Global = Boolean.Parse(a.GlobalEntry); } } else if (sharedEntryValid) { a.Global = shared.Global; } } } if (_package.DeveloperLibs != null) { BasicIncludeAndExclude[] items = { _package.DeveloperLibs.Headers, _package.DeveloperLibs.ImportLibs, _package.DeveloperLibs.StaticLibs }; foreach (var sec in items) { if (sec.GlobalLinkEntry != null) { if (!sec.GlobalLinkEntry.IsBoolean()) { exceptions.Add(CreateEndUserPropertyException(sec.GlobalLinkEntryProp, 169)); } else { sec.GlobalLink = Boolean.Parse(sec.GlobalLinkEntry); } } sec.EvaluateIncludes(); } //add the proper prefix to all the files _package.DeveloperLibs.Headers.AddPrefix(HEADERS_DIR_NAME); _package.DeveloperLibs.ImportLibs.AddPrefix(IMPORTLIB_DIR_NAME); _package.DeveloperLibs.StaticLibs.AddPrefix(STATICLIB_DIR_NAME); } if (_package.SourceCodes != null) { var sc = _package.SourceCodes; sc.EvaluateIncludes(); sc.AddPrefix(SRC_DIR_NAME); } //copy all the stuff that needs to go to Temp TO Temp _package.Prepare(); foreach (var dep in _package.DependencyNames) { /* var temp = new EditableTup<string, string> {L = dep.L, R = _package.ResolveVariables(dep.R)}; //TODO this doesn't work if a packages is a superceding version of the one given var depPackage = (from p in allPackages where p.CosmeticName.IsWildcardMatch(temp.R) orderby p.Version descending select p).FirstOrDefault(); if (depPackage == null) { if (_package.DependencyNamesProp.ContainsKey(temp.R)) { exceptions.Add(CreateEndUserPropertyException(_package.DependencyNamesProp[dep.R], 133, dep.R)); } else { exceptions.Add(CreateEndUserException(133, dep.R)); } } else { _package.DependencyInfo.Add(depPackage); }*/ } //TODO make sure the numbers are not larger than the max a part of a version string var policyRegex = new Regex(@"^policy\.\d{1,5}\.\d{1,5}\.\S+$"); /* var dependentAssemblies = from p in _package.DependencyInfo from a in p.Assemblies where !a.Type.Contains("policy") && !policyRegex.IsMatch(a.Name) select a; */ //let's check for valid roles! if (_package.Roles.IsNullOrEmpty()) exceptions.Add(CreateEndUserException(131)); //make sure the major minors given are valid if (_package.SharedLibs != null) { foreach (var i in _package.SharedLibs.MajorMinorsToReplace) { if (!i.IsValidMajorMinorVersion()) { if (_package.SharedLibs.MajorMinorsToReplaceProp.ContainsKey(i)) { exceptions.Add(CreateEndUserPropertyException(_package.SharedLibs.MajorMinorsToReplaceProp[i], 132, i)); } else { exceptions.Add(CreateEndUserException(132, i)); } } } } if (_package.Apps != null) { foreach (var e in _package.Apps.PrimaryExes) { if (e.StartMenu != null) { if (!e.StartMenu.IsSimpleSubPath()) { exceptions.Add(CreateEndUserPropertyException(e.StartMenuProp, 168, e.StartMenu)); continue; } if (!e.StartMenu.EndsWith(".lnk")) { e.StartMenu += ".lnk"; } } } } if (exceptions.Count > 0) { throw new AggregateException(exceptions); } #region Handle Shared Libraries //first create the string of all the dependencies elements var sharedlib = _package.SharedLibs; if (sharedlib != null) { //set all the assembly names properly foreach (var a in sharedlib.Assemblies) { if (a.Name == null) { var fi = new FileInfo(a.PrimaryFile); a.Name = fi.NameWithoutExt().Replace(" ", "_"); } } Console.Write(Resources.SharedLibCreation); if (_package.PackageArch != "any") { var dependencyStr = new StringBuilder(); /* foreach (var dep in dependentAssemblies) { dependencyStr.Append(DependencyEntry.Replace("[$LIBTYPE]", dep.Type).Replace("[$LIBNAME]", dep.Name). Replace("[$LIBVERSION]", dep.Version).Replace("[$ARCH]", dep.Arch). Replace("[$PUBLICKEYTOKEN]", dep.PublicKeyToken)); } */ foreach (var a in sharedlib.Assemblies) { /* var manifestFilesString = new StringBuilder(); var filesString = new StringBuilder(); filesString.Append(FileEntry.Replace("[$FILE]", Path.GetFileName(a.PrimaryFile))); foreach (var f in a.FinalInclude) { filesString.Append(FileEntry.Replace("[$FILE]", f.L)); } manifestFilesString.Append(SharedLibraryManifest.Replace("[$LIBNAME]", a.Name). Replace("[$LIBVERSION]", _package.PackageVersion). Replace("[$DEPENDENCY]", dependencyStr.ToString()).Replace("[$PUBLICKEYTOKEN]", _package.PubToken). Replace("[$ARCH]", _package.PackageArch).Replace("[$FILES]", filesString.ToString())); a.Manifest = Path.Combine(new FileInfo(a.PrimaryFile).DirectoryName, a.PrimaryFile + ".manifest"); //TODO do file checking File.WriteAllText(a.Manifest, manifestFilesString.ToString()); */ // sign all the non-primary BinFiles var binFiles = from f in a.FinalInclude.BinaryFiles() select f.R; exceptions.AddRange(VerifySigning(binFiles, false)); //manifest created. Let's embed it. if (!EmbedManifest(a.PrimaryFile)) { exceptions.Add(CreateEndUserException(137, a.PrimaryFile + ".manifest", a.PrimaryFile)); continue; } //sign the primary file if (!SignFile(a.PrimaryFile)) { exceptions.Add(CreateEndUserException(136, a.PrimaryFile)); continue; } a.CatFile = a.PrimaryFile + ".cat"; if (!CreateAndSignCat(a.Manifest)) { exceptions.Add(CreateEndUserException(138, a.Manifest + ".cdf")); continue; } //we're going to create the policy assemblies foreach (var p in _package.SharedLibs.MajorMinorsToReplace) { var pa = new PolicyAssemblyDescription(p, a.Name); _package.SharedLibs.PolicyAssemblies.Add(pa); var paManifestString = PublisherConfiguration.Replace("[$ASSMNAME]", a.Name). Replace("[$LIBMAJORMINOR]", p).Replace("[$PUBLICKEYTOKEN]", _package.PubToken). Replace("[$LIBVERSION]", _package.PackageVersion).Replace("[$ARCH]", _package.PackageArch). Replace("[$OLDVERSION]", _package.BindingPolicy); pa.Manifest = Path.Combine(new FileInfo(a.PrimaryFile).DirectoryName, pa.Name + ".manifest"); File.WriteAllText(pa.Manifest, paManifestString); pa.CatFile = pa.Manifest.Replace(".manifest", "") + ".cat"; if (!CreateAndSignCat(pa.Manifest)) { exceptions.Add(CreateEndUserException(138, pa.Manifest + ".cdf")); continue; } } } } else { // it's .NET foreach (var a in sharedlib.Assemblies) { if (!_codeSigningCert.FinishStrongNaming(a.PrimaryFile)) { exceptions.Add(CreateEndUserException(139, a.PrimaryFile)); continue; } if (!SignFile(a.PrimaryFile)) { exceptions.Add(CreateEndUserException(136, a.PrimaryFile)); continue; } foreach (var p in _package.SharedLibs.MajorMinorsToReplace) { var pa = new PolicyAssemblyDescription(p, a.Name); _package.SharedLibs.PolicyAssemblies.Add(pa); pa.PrimaryFile = Path.Combine(new FileInfo(a.PrimaryFile).DirectoryName, pa.Name + ".dll"); var paManifestString = MSILPublisherConfiguration.Replace("[$ASSMNAME]", a.Name). Replace("[$PUBLICKEYTOKEN]", _package.PubToken). Replace("[$LIBVERSION]", _package.PackageVersion). Replace("[$OLDVERSION]", _package.BindingMin + "-" + _package.BindingMax); pa.Manifest = pa.PrimaryFile + ".config"; // cleanupFiles.Add(pa.Manifest); File.WriteAllText(pa.Manifest, paManifestString); if (!ExtractPublicKey()) { exceptions.Add(CreateEndUserPropertyException(_package.SharedLibs.MajorMinorsToReplaceProp[p], 140, _package.CertificateFile)); continue; } if (_al.Exec("/link:{0} /out:{1} /delaysign+ /keyfile:{2} /v:{3}", pa.Manifest, pa.PrimaryFile, _publicKeyFile, _package.PackageVersion) != 0) { exceptions.Add(CreateEndUserPropertyException(_package.SharedLibs.MajorMinorsToReplaceProp[p], 141, pa.PrimaryFile)); continue; } if (!_codeSigningCert.FinishStrongNaming(pa.PrimaryFile)) { exceptions.Add(CreateEndUserPropertyException(_package.SharedLibs.MajorMinorsToReplaceProp[p], 139, pa.PrimaryFile)); continue; } if (!SignFile(pa.PrimaryFile)) { exceptions.Add(CreateEndUserPropertyException(_package.SharedLibs.MajorMinorsToReplaceProp[p], 136, pa.PrimaryFile)); continue; } } } } if (exceptions.Count > 0) { throw new AggregateException(exceptions); } Console.WriteLine(Resources.Finished); } #endregion #region Handle Apps var apps = _package.Apps; if (apps != null) { Console.Write(Resources.AppCreation); if (_package.PackageArch != "any") { //it's native var dependencyStr = new StringBuilder(); /* foreach (var dep in dependentAssemblies) { dependencyStr.Append(DependencyEntry.Replace("[$LIBTYPE]", dep.Type).Replace("[$LIBNAME]", dep.Name). Replace("[$LIBVERSION]", dep.Version).Replace("[$ARCH]", dep.Arch). Replace("[$PUBLICKEYTOKEN]", dep.PublicKeyToken)); } //we needs to add in the other assemblies in this package if (sharedlib != null) { foreach (var dep in sharedlib.Assemblies) { dependencyStr.Append(DependencyEntry.Replace("[$LIBTYPE]", "win32"). Replace("[$LIBNAME]", dep.Name).Replace("[$LIBVERSION]", _package.PackageVersion). Replace("[$ARCH]", _package.PackageArch).Replace("[$PUBLICKEYTOKEN]", _package.PubToken)); } }*/ foreach (var e in apps.PrimaryExes) { /* if (dependencyStr.Length > 0) { var configFilename = e.InputFile + ".config"; var execManifest = new StringBuilder(); execManifest.Append(ExecutableManifest.Replace("[$DEPENDENCY]", dependencyStr.ToString())); File.WriteAllText(configFilename, execManifest.ToString()); if (!EmbedManifest(e.InputFile, configFilename)) { exceptions.Add(CreateEndUserException(137, configFilename, e.InputFile)); continue; } }*/ if (!SignFile(e.InputFile)) { exceptions.Add(CreateEndUserException(136, e.InputFile)); continue; } } } else { //it's .net foreach (var e in apps.PrimaryExes) { if (!_codeSigningCert.FinishStrongNaming(e.InputFile)) { exceptions.Add(CreateEndUserException(139, e.InputFile)); continue; } if (!SignFile(e.InputFile)) { exceptions.Add(CreateEndUserException(136, e.InputFile)); continue; } } } if (exceptions.Count > 0) { throw new AggregateException(exceptions); } Console.WriteLine(Resources.Finished); } //check if every binary is actually signed at all //yes this is really messy var binFilesToCheck = Enumerable.Empty<TempedFile>(); if (apps != null) binFilesToCheck = binFilesToCheck.Concat(from i in apps.BinaryFilesMinusPrimaries select i.R); if (_package.SourceCodes != null) binFilesToCheck = binFilesToCheck.Concat(from i in _package.SourceCodes.FinalInclude.BinaryFiles() select i.R); if (_package.DeveloperLibs != null) binFilesToCheck = binFilesToCheck.Concat(from i in _package.DeveloperLibs.Headers.FinalInclude. Concat(_package.DeveloperLibs.ImportLibs.FinalInclude). Concat(_package.DeveloperLibs.StaticLibs.FinalInclude). BinaryFiles() select i.R); exceptions.AddRange(VerifySigning(binFilesToCheck)); exceptions.AddRange(DownloadBootstrapManifest()); if (exceptions.Count > 0) { throw new AggregateException(exceptions); } #endregion #region Write Msi OutToFile Console.Write(Resources.CreatingMSI); var tempPrefix = Path.GetTempFileName(); File.WriteAllText(tempPrefix + ".wxs", _package.ConvertToWix()); //we suppress the lack of UpgradeCode warning since we don't use them if (_candle.Exec("-nologo -sw1075 -out {0}.wixobj {0}.wxs", tempPrefix) != 0) exceptions.Add(CreateEndUserException(142, _candle.StandardOut)); if (exceptions.Count > 0) { throw new AggregateException(exceptions); } //we suppress the lack of UpgradeCode warning since we don't use them if (_light.Exec("-nologo -sw1076 -out {1} {0}.wixobj", tempPrefix, _package.DefaultOutputFile) != 0) exceptions.Add(CreateEndUserException(143, _light.StandardOut)); if (exceptions.Count > 0) { throw new AggregateException(exceptions); } if (!SignFile(_package.DefaultOutputFile)) { exceptions.Add(CreateEndUserException(136, _package.DefaultOutputFile)); } if (exceptions.Count > 0) { throw new AggregateException(exceptions); } if (_remember) { //Verbose("Storing certificate details in the registry."); _certificateSettings["#CurrentCertificate"].EncryptedStringValue = _package.CertificateFile; _certificateSettings[Path.GetFileName(_package.CertificateFile), "Password"].EncryptedStringValue = _package.CertificatePassword; } Console.WriteLine(Resources.Finished); #endregion } catch (AggregateException failures) { CancellationTokenSource.Cancel(); Fail("{0}\r\n\r\n {1}", failures.InnerExceptions, Resources.ForCommandLineHelp); } catch (Exception failure) { CancellationTokenSource.Cancel(); Fail("{0}\r\n\r\n {1}", "{0} - stacktrace: {1}".format(failure.Message, failure.StackTrace) , Resources.ForCommandLineHelp); } finally { foreach (var f in _cleanupFiles) { File.Delete(f); } } return 0; }