Exemplo n.º 1
0
        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;
                }
            }
        }
Exemplo n.º 2
0
        /// <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);
        }