Exemplo n.º 1
0
        /// <summary>
        /// Traverses the specified path, creating any missing elements along the way. Uses existing nodes if found.
        /// </summary>
        /// <param name="selector"></param>
        /// <returns></returns>
        public Node makeNodeTree(string selector)
        {
            Node     n = this;
            Selector s = new Selector(selector);

            foreach (string part in s)
            {
                IList <Node> results = n.childrenByName(part);
                //Add it if doesn't exist
                if (results == null || results.Count == 0)
                {
                    Node newNode = new Node(part);
                    if (n.children == null)
                    {
                        n.children = new List <Node>();
                    }
                    n.Children.Add(newNode);
                    n = newNode;
                }
                else
                {
                    n = results[0];
                }
            }
            return(n);
        }
Exemplo n.º 2
0
        public void EnsureLoaded(Node manifest, string assemblyName, Stopwatch sw = null)
        {
            if (TargetFolder == null)
            {
                this.AcceptIssue(
                    new Issue("Applicaiton does not have IOPermission; Native dependencies for " + assemblyName +
                              " will not be downloaded if missing"));
                return;
            }
            string platform = IntPtr.Size == 8 ? "64" : "32";

            Queue<Dependency> q = new Queue<Dependency>();
            try {
                foreach (Node c in manifest.childrenByName("file")) {
                    string bitness = c.Attrs["bitness"];//Skip files with the wrong bitness
                    if (bitness != null && !bitness.Equals(platform, StringComparison.OrdinalIgnoreCase)) continue;

                    string name = c.Attrs["name"]; //Skip duplicate names
                    if (string.IsNullOrEmpty(name)) this.AcceptIssue(new Issues.Issue("Missing attribute 'name' in native dependency manifest for " + assemblyName, Issues.IssueSeverity.Warning));
                    if (filesVerified.Contains(name)) continue;

                    //What is the expected size? If none listed, any size will work.
                    int fileBytes = 0;
                    if (c.Attrs["fileBytes"] != null && !int.TryParse(c.Attrs["fileBytes"], System.Globalization.NumberStyles.Number, NumberFormatInfo.InvariantInfo, out fileBytes))
                        this.AcceptIssue(new Issues.Issue("Failed to parse fileBytes value " + c.Attrs["fileBytes"] + " in native dependency manifest for " + assemblyName, Issues.IssueSeverity.Warning));

                    //Download url?
                    string url = c.Attrs["url"];

                    string destPath = Path.Combine(TargetFolder, name);

                    long existingLength = 0;

                    //Does it already exist?
                    if (File.Exists(destPath)) {
                        if (fileBytes < 1) {
                            filesVerified.Add(name);
                            continue;
                        } else {
                            existingLength = new FileInfo(destPath).Length;
                            if (existingLength == fileBytes) {
                                filesVerified.Add(name);
                                continue;
                            }
                        }
                    }

                    var d = new Dependency() { Exists = existingLength > 0, Name = name, Url = url, DestPath = destPath, ExistingLength = existingLength, ExpectedLength = fileBytes, Client = new WebClient(), RequestingAssembly =assemblyName };
                    q.Enqueue(d);
                }

                sw.Stop();
                if (sw.ElapsedMilliseconds > 100 && q.Count < 1) this.AcceptIssue(new Issues.Issue("Verifying native dependencies for " + assemblyName + " took " + sw.ElapsedMilliseconds + "ms.", Issues.IssueSeverity.Warning));

                ServicePointManager.DefaultConnectionLimit = 1000; //Allow more than 2 simultaneous http requests.
                StringBuilder message = new StringBuilder();
                if (q.Count > 0) {
                    Stopwatch dsw = new Stopwatch();
                    dsw.Start();
                    using (var cd = new Countdown(q.Count)) {
                        foreach (var current in q.ToArray()) {
                            var d = current;
                            ThreadPool.QueueUserWorkItem(x => {
                                DownloadFile(d, message);
                                cd.Signal();
                            });
                        }
                        cd.Wait();
                    }
                    dsw.Stop();
                    this.AcceptIssue(new Issues.Issue("Some native dependencies for " + assemblyName + " were missing, but were downloaded successfully. This delayed startup time by " + (sw.ElapsedMilliseconds + dsw.ElapsedMilliseconds).ToString() + "ms.", message.ToString(), Issues.IssueSeverity.Warning));

                }

            } finally {
                foreach (Dependency d in q.ToArray()) {
                    d.Client.Dispose();
                }
            }
        }