void getBinary(Experiment e) { if (!Directory.Exists(e.localDir)) { throw new Exception("Local scratch directory does not exist: " + e.localDir); } if (!File.Exists(e.localExecutable)) { Console.WriteLine("Downloading binary..."); FileStream fs = null; try { fs = new FileStream(e.localExecutable, FileMode.CreateNew); } catch (IOException) { if (File.Exists(e.localExecutable)) { // All is good, someone else downloaded it! return; } } byte[] data = new byte[0]; Dictionary <string, Object> r = SQLRead("SELECT Binary FROM Binaries WHERE ID=" + e.binaryID); data = (byte[])r["Binary"]; int sz = data.GetUpperBound(0); fs.Write(data, 0, sz); fs.Flush(); fs.Close(); if (data[0] == 0x50 && data[1] == 0x4b && data[2] == 0x03 && data[3] == 0x04) { // This is a zip file. string tfn = Path.Combine(Path.GetTempFileName() + ".zip"); File.Move(e.localExecutable, tfn); e.localExecutable = null; Package pkg = Package.Open(tfn, FileMode.Open); PackageRelationshipCollection rels = pkg.GetRelationships(); if (rels.Count() != 1) { throw new Exception("Missing package relationships"); } PackageRelationship main = rels.First(); foreach (PackagePart part in pkg.GetParts()) { // Uri uriDocumentTarget = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), rel.TargetUri); // PackagePart part = pkg.GetPart(uriDocumentTarget); Stream s = part.GetStream(FileMode.Open, FileAccess.Read); string fn = CreateFilenameFromUri(part.Uri).Substring(1); fs = new FileStream(e.localDir + @"\" + fn, FileMode.OpenOrCreate); CopyStream(s, fs); fs.Close(); if (part.Uri == main.TargetUri) { e.localExecutable = e.localDir + @"\" + fn; } } pkg.Close(); if (e.localExecutable == null) { throw new Exception("Main executable not found in zip."); } try { File.Delete(tfn); } catch (Exception) { } } string ext = Path.GetExtension(e.localExecutable); string localname = e.localExecutable + "-" + myName + ext; File.Move(e.localExecutable, localname); e.localExecutable += "-" + myName + ext; int retry_count = 1000; while (!File.Exists(localname)) { Thread.Sleep(100); retry_count--; if (retry_count == 0) { throw new Exception("Local binary missing."); } } retry_count = 1000; retry: try { FileStream tmp = File.OpenRead(localname); tmp.Close(); } catch { Thread.Sleep(100); retry_count--; if (retry_count == 0) { throw new Exception("Local binary is not readable."); } goto retry; } } }
/// <summary> /// Extracts contents of zip archive to target directory and finds main executable within it. /// </summary> /// <param name="fileName">Name of zip file</param> /// <param name="targetFolder">Foler to extract archive's contents to</param> /// <returns>Name of the main executable</returns> public static string ExtractZip(string fileName, string targetFolder) { string localExecutable = null; int execCount = 0; using (var zip = ZipFile.Read(fileName)) { foreach (var fn in zip.EntryFileNames) { var ext = Path.GetExtension(fn).Substring(1); if (ExecutableExtensions.Contains(ext) || BatchFileExtensions.Contains(ext)) { ++execCount; localExecutable = Path.Combine(targetFolder, fn); } } if (execCount == 1) { // If zip contains exactly one executable, then it is the one we need. zip.ExtractAll(targetFolder); return(localExecutable); } } localExecutable = null; // If single executable expectation failed, try to treat zip as a package with main executable name stored within a relationship using (Package pkg = Package.Open(fileName, FileMode.Open)) { PackageRelationshipCollection rels = pkg.GetRelationships(); var relsCount = rels.Count(); if (relsCount != 1) { throw new Exception("Single executable expectation is failed, when interpreting archive as a package relationships appeared incorrect."); } PackageRelationship main = rels.First(); var parts = pkg.GetParts(); foreach (PackagePart part in parts) { using (Stream s = part.GetStream(FileMode.Open, FileAccess.Read)) { string fn = CreateFilenameFromUri(part.Uri).Substring(1); string targetPath = Path.Combine(targetFolder, fn); using (var fs = new FileStream(targetPath, FileMode.OpenOrCreate)) { CopyStream(s, fs); } if (part.Uri == main.TargetUri) { localExecutable = targetPath; } } } } if (localExecutable == null) { throw new Exception("Main executable not found in zip."); } return(localExecutable); }