|
|
@@ -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)
|