diff --git a/Main.cs b/Main.cs
index a424751..32d777b 100644
--- a/Main.cs
+++ b/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;
}
}
+
+ ///
+ /// List of downloads to be performed by the wrapper before starting
+ /// a service.
+ ///
+ public List Downloads
+ {
+ get
+ {
+ List r = new List();
+ foreach (XmlNode n in dom.SelectNodes("//download"))
+ {
+ r.Add(new Download(n));
+ }
+ return r;
+ }
+ }
+ }
+
+ ///
+ /// Specify the download activities prior to the launch.
+ /// This enables self-updating services.
+ ///
+ 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)