public void AppPackage_MultiRead() { // Verify that a package can be opened for reading by multiple streams. string tempPath = GetTempFileName(); string tempDir = Helper.AddTrailingSlash(Path.GetTempPath()); AppRef appRef = AppRef.Parse("appref://myapps/mypackage.zip?version=1.2.3.4"); AppPackage pack1 = null; AppPackage pack2 = null; FileStream fs = null; MemoryStream ms; try { pack1 = AppPackage.Create(tempPath, appRef, @" LaunchType = Test.MyType:MyAssembly.dll; LaunchMethod = Foo; LaunchArgs = Bar; "); using (ms = new MemoryStream(4096)) { for (int i = 0; i < 4096; i++) { ms.WriteByte((byte)i); } ms.Position = 0; pack1.AddFile("Test.dat", ms); } pack1.Close(); pack1 = null; pack1 = AppPackage.Open(tempPath); pack2 = AppPackage.Open(tempPath); fs = new FileStream(tempPath, FileMode.Open, FileAccess.Read); } finally { if (pack1 != null) { pack1.Close(); } if (pack2 != null) { pack2.Close(); } if (fs != null) { fs.Close(); } Delete(tempPath); } }
public void AppPackage_MD5() { string tempPath = GetTempFileName(); string tempDir = Helper.AddTrailingSlash(Path.GetTempPath()); AppPackage package = null; MemoryStream ms; byte[] md5; try { package = AppPackage.Create(tempPath, AppRef.Parse("appref://myapps/mypackage.zip?version=1.2.3.4"), @" LaunchType = Test.MyType:MyAssembly.dll; LaunchMethod = Foo; LaunchArgs = Bar; "); using (ms = new MemoryStream(4096)) { for (int i = 0; i < 4096; i++) { ms.WriteByte((byte)i); } ms.Position = 0; package.AddFile("Test.dat", ms); } package.Close(); package = null; // Verify that a MD5 hash computed manually on the package file jibes // with what AppPackage computes. using (var fs = new EnhancedFileStream(tempPath, FileMode.Open, FileAccess.Read)) { md5 = MD5Hasher.Compute(fs, fs.Length); } package = AppPackage.Open(tempPath); CollectionAssert.AreEqual(md5, package.MD5); package.Close(); package = null; } finally { if (package != null) { package.Close(); } Delete(tempPath); } }
public void AppPackage_ExtractTo() { string tempPath = GetTempFileName(); string tempDir = Helper.AddTrailingSlash(Path.GetTempPath()); AppPackage package = null; try { package = AppPackage.Create(tempPath, AppRef.Parse("appref://myapps/mypackage.zip?version=1.2.3.4"), @" LaunchType = Test.MyType:MyAssembly.dll; LaunchMethod = Foo; LaunchArgs = Bar; "); package.AddFile("File1.txt", Helper.ToUTF8("Hello World! #1\r\n")); package.AddFile("File2.txt", Helper.ToUTF8("Hello World! #2\r\n")); package.Close(); package = null; package = AppPackage.Open(tempPath); package.ExtractTo(tempDir); package.Close(); package = null; Assert.IsTrue(File.Exists(tempDir + "Package.ini")); Assert.IsTrue(File.Exists(tempDir + "File1.txt")); Assert.IsTrue(File.Exists(tempDir + "File2.txt")); using (var reader = new StreamReader(tempDir + "File1.txt")) { Assert.AreEqual("Hello World! #1", reader.ReadLine()); } using (var reader = new StreamReader(tempDir + "File2.txt")) { Assert.AreEqual("Hello World! #2", reader.ReadLine()); } } finally { if (package != null) { package.Close(); } Delete(tempPath); } }
private void CreatePackage(string folder, AppRef appRef) { AppPackage package; package = AppPackage.Create(Helper.AddTrailingSlash(folder) + appRef.FileName, appRef, @" LaunchType = Test.MyType:MyAssembly.dll; LaunchMethod = Foo; LaunchArgs = Bar; "); package.AddFile("Test1.txt", Helper.ToUTF8("Hello World!\r\n")); byte[] buf = new byte[1000000]; for (int i = 0; i < buf.Length; i++) { buf[i] = (byte)Helper.Rand(); // Use Rand() to disable compression } package.AddFile("Test2.dat", buf); package.Close(); }
/// <summary> /// Executes the specified PACK command. /// </summary> /// <param name="args">The command arguments.</param> /// <returns>0 on success, a non-zero error code otherwise.</returns> public static int Execute(string[] args) { const string usage = @" Usage: ------------------------------------------------------------------------------- vegomatic pack [-r] [-out:<path>] <appref> <path-0> <path-1>... <path-N> Creates an application package from a set of assembly and data files. -r Indicates that subfolders are to be searched recursively for files to be added to the archive. -out:path Specifies where the generated packaged file is to be written. If this specifies a folder then the package will be named using the standard package file naming convention in that folder. If this option is not present, then the package will be saved in the current folder using the standard name. <appref> The application reference to be used for this package. See the note below describing how the version number can be loaded from an assembly. <path-#> Path of the files or directories to be added to the archive. File specifications may include wildcards. AppRef Format ------------- Application references are URIs formatted as: appref://Root/Segment0/Segment1/../SegmentN.zip?version=1.2.3.4 where the Root and Segment#s uniquely identify the application and the version query parameter specifies the version number. Note that vegomatic supports a specialized notation for apprefs that indicate that the version should be loaded from an assembly's version number rather than being specified directly on the command line. This can make it easy to automate the creation of application packages during the build process. To accomplish this, set the version to an ""@"" followed by the path to the assembly file. Here's an example: vegomatic pack appref://myapps/[email protected] In this case, vegomatic will load myassembly.dll from the current folder and use the assembly's version number when creating the package. Package.ini File ---------------- One of the files that must be included in all applications is the PACKAGE.INI file. This is a text file formatted using the standard LillTek Platform config conventions that describes the metadata to be associated with the package. One required setting is the APPREF setting which should be set to the same appref value specified on the command line. This can be accomplished via the $(appref) macro as in: AppRef = $(appref) Vegomatic will replace this macro with the appref specified on the command line before adding the PACKAGE.INI file to the package. "; AppPackage package = null; bool recursive = false; string outPath = null; string sAppRef; AppRef appRef; int argPos; int cAdded; bool packageIni; if (args.Length < 2) { Program.Error(usage); return(1); } for (argPos = 0; argPos < args.Length; argPos++) { string arg = args[argPos]; if (!arg.StartsWith("-")) { break; } else if (arg == "-r") { recursive = true; } else if (arg.StartsWith("-out:")) { outPath = arg.Substring(5); } else { Program.Error(usage); return(1); } } // Parse the application reference, reading the version number // from the referenced assembly file if requested. // $todo(jeff.lill): // // The version parsing code is really simplistic. // It assumes that "version" is the only possible // query parameter or than it appears first in // the appref URI. string assemblyPath; string appName; int pos; sAppRef = args[argPos++]; pos = sAppRef.ToLowerInvariant().IndexOf("?version=@"); if (pos == -1) { appRef = AppRef.Parse(sAppRef); } else { appName = sAppRef.Substring(0, pos); assemblyPath = sAppRef.Substring(pos + 10); appRef = AppRef.Parse(appName + "?version=" + Helper.GetVersion(Assembly.ReflectionOnlyLoadFrom(assemblyPath)).ToString()); } if (outPath == null) { outPath = appRef.FileName; } else if (Directory.Exists(outPath)) { outPath = Helper.AddTrailingSlash(outPath) + appRef.FileName; } if (argPos == args.Length) { Program.Error(usage); return(1); } Helper.CreateFileTree(outPath); if (File.Exists(outPath)) { File.Delete(outPath); } package = AppPackage.Create(outPath, appRef, null); cAdded = 0; packageIni = false; try { for (; argPos < args.Length; argPos++) { string path = args[argPos]; bool hasWildcards; bool isFolder; string basePath; hasWildcards = path.IndexOfAny(Helper.FileWildcards) != -1; if (!hasWildcards) { isFolder = (File.GetAttributes(path) & FileAttributes.Directory) != 0; } else { isFolder = false; } basePath = Path.GetFullPath(path.Replace('?', 'x').Replace('*', 'x')); pos = basePath.LastIndexOf(Helper.PathSepChar); if (pos == -1) { throw new Exception(string.Format("Invalid file path [{0}].", path)); } basePath = basePath.Substring(0, pos); if (isFolder) { Program.Output("Adding: {0}", path); foreach (string file in Helper.GetFilesByPattern(path + Helper.PathSepString + "*.*", SearchOption.AllDirectories)) { if (String.Compare(outPath, file, true) == 0) { continue; // Ignore the zip archive being created } Program.Output("Adding: {0}", file); packageIni = AddFile(package, file, basePath) || packageIni; cAdded++; } } else { foreach (string file in Helper.GetFilesByPattern(path, recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { if (String.Compare(outPath, file, true) == 0) { continue; // Ignore the zip archive being created } Program.Output("Adding: {0}", file); packageIni = AddFile(package, file, basePath) || packageIni; cAdded++; } } } package.Close(); if (!packageIni) { throw new Exception("PACKAGE.INI file with the package metadata is missing."); } } catch (Exception e) { Program.Error("{0}: {1}", e.GetType().Name, e.Message); } finally { if (package != null) { package.Close(); } } Program.Output(""); Program.Output("[{0}] files added.", cAdded); return(0); }
public void AppPackage_Basic() { string tempPath = GetTempFileName(); string tempDir = Helper.AddTrailingSlash(Path.GetTempPath()); string testPath = tempDir + "Test.txt"; AppPackage package = null; MemoryStream ms; StreamReader reader; try { // Generate the package package = AppPackage.Create(tempPath, AppRef.Parse("appref://myapps/mypackage.zip?version=1.2.3.4"), @" LaunchType = Test.MyType:MyAssembly.dll; LaunchMethod = Foo; LaunchArgs = Bar; "); using (StreamWriter writer = new StreamWriter(testPath)) { for (int i = 0; i < 4000; i++) { writer.WriteLine("Hello World!"); } } package.AddFile(testPath, tempDir); using (ms = new MemoryStream(4096)) { for (int i = 0; i < 4096; i++) { ms.WriteByte((byte)i); } ms.Position = 0; package.AddFile("Test.dat", ms); } package.Close(); package = null; // Verify that the package can be opened and the contents look good. package = AppPackage.Open(tempPath); Assert.AreEqual(new AppRef("appref://myapps/mypackage.zip?version=1.2.3.4"), package.AppRef); Assert.AreEqual(new Version(1, 2, 3, 4), package.Version); Assert.AreEqual("Test.MyType:MyAssembly.dll", package.Settings.Get("LaunchType")); Assert.AreEqual("Foo", package.Settings.Get("LaunchMethod")); Assert.AreEqual("Bar", package.Settings.Get("LaunchArgs")); Assert.IsTrue(package.ContainsFile("Test.txt")); Assert.IsTrue(package.ContainsFile("Test.dat")); ms = new MemoryStream(); package.CopyFile("Test.txt", ms); ms.Position = 0; reader = new StreamReader(ms); for (int i = 0; i < 4000; i++) { Assert.AreEqual("Hello World!", reader.ReadLine()); } string tempPath2 = Path.GetTempFileName(); try { using (var fs = new FileStream(tempPath2, FileMode.Create, FileAccess.ReadWrite)) { package.CopyFile("test.dat", fs); Assert.AreEqual(4096, fs.Length); fs.Position = 0; for (int i = 0; i < 4096; i++) { Assert.AreEqual((byte)i, fs.ReadByte()); } } } finally { File.Delete(tempPath2); } package.Close(); package = null; } finally { if (package != null) { package.Close(); } Delete(tempPath); Delete(testPath); } }