Browse Source

Adding a download service. This enables self-updating services

git-svn-id: https://svn.kenai.com/svn/winsw~subversion/trunk@30 c8b2a3fe-9b5b-6a51-a37e-dc31b0e308fa
kohsuke 17 years ago
parent
commit
b8dbc77d7e
1 changed files with 74 additions and 1 deletions
  1. 74 1
      Main.cs

+ 74 - 1
Main.cs

@@ -7,6 +7,7 @@ using System.Runtime.InteropServices;
 using System.ServiceProcess;
 using System.Text;
 using System.IO;
+using System.Net;
 using WMI;
 using System.Xml;
 using System.Threading;
@@ -372,6 +373,63 @@ namespace winsw
                 return map;
             }
         }
+
+        /// <summary>
+        /// List of downloads to be performed by the wrapper before starting
+        /// a service.
+        /// </summary>
+        public List<Download> Downloads
+        {
+            get
+            {
+                List<Download> r = new List<Download>();
+                foreach (XmlNode n in dom.SelectNodes("//download"))
+                {
+                    r.Add(new Download(n));
+                }
+                return r;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Specify the download activities prior to the launch.
+    /// This enables self-updating services.
+    /// </summary>
+    public class Download
+    {
+        public readonly string From;
+        public readonly string To;
+
+        internal Download(XmlNode n)
+        {
+            From = n.Attributes["from"].Value;
+            To = n.Attributes["to"].Value;
+        }
+
+        public void Perform()
+        {
+            WebRequest req = WebRequest.Create(From);
+            WebResponse rsp = req.GetResponse();
+            FileStream tmpstream = new FileStream(To+".tmp", FileMode.Create);
+            CopyStream(rsp.GetResponseStream(), tmpstream);
+            // only after we successfully downloaded a file, overwrite the existing one
+            File.Delete(To);
+            File.Move(To + ".tmp", To);
+        }
+
+        private static void CopyStream(Stream i, Stream o)
+        {
+            byte[] buf = new byte[8192];
+            while (true)
+            {
+                int len = i.Read(buf, 0, buf.Length);
+                if (len <= 0) return;
+                o.Write(buf, 0, len);
+            }
+            i.Close();
+            o.Close();
+        }
     }
 
     public class WrapperService : ServiceBase
@@ -546,9 +604,24 @@ namespace winsw
             {
                 LogEvent("envar " + key + '=' + envs[key]);
             }
- 
+
             HandleFileCopies();
 
+            // handle downloads
+            foreach (Download d in descriptor.Downloads)
+            {
+                LogEvent("Downloading: " + d.From+ " to "+d.To);
+                try
+                {
+                    d.Perform();
+                }
+                catch (Exception e)
+                {
+                    LogEvent("Failed to download " + d.From, EventLogEntryType.Warning);
+                    // but just keep going
+                }
+            }
+
             string startarguments = descriptor.Startarguments;
 
             if (startarguments == null)