IIS website and windows service installation

Jan 29, 2015 at 5:16 PM
Firstly I'd like to congratulate you on the excellent solution Wix# is for everybody trying to implement setups and I hope I'll be a helping hand in the future improvement.

While developing a setup solution for a project I work on, I encountered two limitations that I solved indirectly by changing the Wix# source, but I feel they could be a good addition to Wix#.

The way you add IIS virtual directories is fine, but in my case I wanted to install a new website with a new AppPool, something that can't be achieved for now. I think you should add a Website array and similar functionality the way you do with IISVirtualDir or change current implementation to allow an exception when you pass as Alias "/" or something similar. I believe the majority of IIS installations are without a virtual directory anyway.

I also had to install a windows service and which had a dummy Service base and no installer, therefore I couldn't use InstallUtil or the Wix way. The path I chose was partially there in your code. You use internally sc.exe in CommonTasks.cs ServiceDo, and I just added a public ServiceCommand that allows to do everything with sc.exe. That can be also added as an option.

And a correction... in Controls\CustomUI.cs you set WIXUI_INSTALLDIR to TARGETDIR but should be INSTALLDIR that Wix uses.

If you'd like I can provide code as well for these. I'd also like to see a better integration with VS as others mentioned, but I know this would be a lot of work that perhaps is better left after other tasks are done.

Thanks again for your great work. Keep at it!
Coordinator
Jan 30, 2015 at 3:52 AM
Thank you for your feedback.
Indeed there can a lot improvements to the existing functionality . Particularly related to IIS.
Please send my your code and I will process and incorporate as much as possible/practical.

Thank you again for your support. :)
Jan 30, 2015 at 7:15 PM
diff --git a/src/WixSharp/CommonTasks.cs b/src/WixSharp/CommonTasks.cs
index 3c3ab13..bcdec5a 100644
--- a/src/WixSharp/CommonTasks.cs
+++ b/src/WixSharp/CommonTasks.cs
@@ -383,6 +383,26 @@ namespace WixSharp.CommonTasks
             return ServiceDo("stop", service, throwOnError);
         }
 
+        /// <summary>
+        /// Use sc.exe fully
+        /// </summary>
+        /// <param name="command"></param>
+        /// <param name="service"></param>
+        /// <param name="parameters"></param>
+        /// <param name="throwOnError"></param>
+        /// <returns></returns>
+        static public string ServiceCommand(string command, string service, string parameters = "", bool throwOnError = true)
+        {
+            var util = new ExternalTool { ExePath = "sc.exe", Arguments = command + " " + service + " " + parameters };
+
+            var buf = new StringBuilder();
+            int retval = util.ConsoleRun(line => buf.AppendLine(line));
+
+            if (retval != 0 && throwOnError)
+                throw new Exception(buf.ToString());
+            return buf.ToString();
+        }
+
         static string ServiceDo(string action, string service, bool throwOnError)
         {
             var util = new ExternalTool { ExePath = "sc.exe", Arguments = action + " \"" + service + "\"" };
diff --git a/src/WixSharp/Compiler.cs b/src/WixSharp/Compiler.cs
index 6b88810..a20f806 100644
--- a/src/WixSharp/Compiler.cs
+++ b/src/WixSharp/Compiler.cs
@@ -1512,7 +1512,7 @@ namespace WixSharp
                                 .AddAttributes(condition.Attributes));
         }
 
-        private static void InsertWebSite(WebSite webSite, string dirID, XElement element)
+        private static void InsertWebSite(WebSite webSite, string dirID, XElement element, IISVirtualDir wVDir = null)
         {
             XNamespace ns = "http://schemas.microsoft.com/wix/IIsExtension";
 
@@ -1532,33 +1532,12 @@ namespace WixSharp
 
                 xAddress.AddAttributes(address.Attributes);
             }
-        }
-
-        private static void InsertIISElements(XElement dirItem, XElement component, IISVirtualDir[] wVDirs, Project project)
-        {
-            //http://ranjithk.com/2009/12/17/automating-web-deployment-using-windows-installer-xml-wix/
 
-            XNamespace ns = "http://schemas.microsoft.com/wix/IIsExtension";
-
-            string dirID = dirItem.Attribute("Id").Value;
-            var xProduct = component.Parent("Product");
-
-            var uniqueWebSites = new List<WebSite>();
-
-            bool wasInserted = true;
-            foreach (IISVirtualDir wVDir in wVDirs)
+            if (wVDir != null)
             {
-                wasInserted = true;
-
-                XElement xWebApp;
-                var xVDir = component.AddElement(new XElement(ns + "WebVirtualDir",
-                                                     new XAttribute("Id", wVDir.Name.Expand()),
-                                                     new XAttribute("Alias", wVDir.Alias.IsEmpty() ? wVDir.Name : wVDir.Alias),
-                                                     new XAttribute("Directory", dirID),
-                                                     new XAttribute("WebSite", wVDir.WebSite.Name.Expand()),
-                                                     xWebApp = new XElement(ns + "WebApplication",
-                                                         new XAttribute("Id", wVDir.AppName.Expand() + "WebApplication"),
-                                                         new XAttribute("Name", wVDir.AppName))));
+                XElement xWebApp = xWebSite.AddElement(new XElement(ns + "WebApplication",
+                    new XAttribute("Id", wVDir.AppName.Expand() + "WebApplication"),
+                    new XAttribute("Name", wVDir.AppName)));
                 if (wVDir.AllowSessions.HasValue)
                     xWebApp.Add(new XAttribute("AllowSessions", wVDir.AllowSessions.Value.ToYesNo()));
                 if (wVDir.Buffer.HasValue)
@@ -1577,6 +1556,59 @@ namespace WixSharp
                     xWebApp.Add(new XAttribute("ServerDebugging", wVDir.ServerDebugging.Value.ToYesNo()));
                 if (wVDir.SessionTimeout.HasValue)
                     xWebApp.Add(new XAttribute("SessionTimeout", wVDir.SessionTimeout.Value));
+                
+                if (wVDir.WebAppPool != null)
+                {
+                    id = wVDir.Name.Expand() + "_AppPool";
+
+                    xWebApp.Add(new XAttribute("WebAppPool", id));
+                }
+            }
+        }
+
+        private static void InsertIISElements(XElement dirItem, XElement component, IISVirtualDir[] wVDirs, Project project)
+        {
+            //http://ranjithk.com/2009/12/17/automating-web-deployment-using-windows-installer-xml-wix/
+
+            XNamespace ns = "http://schemas.microsoft.com/wix/IIsExtension";
+
+            string dirID = dirItem.Attribute("Id").Value;
+            var xProduct = component.Parent("Product");
+
+            var uniqueWebSites = new List<WebSite>();
+
+            bool wasInserted = true;
+            foreach (IISVirtualDir wVDir in wVDirs)
+            {
+                wasInserted = true;
+
+                //XElement xWebApp;
+                //var xVDir = component.AddElement(new XElement(ns + "WebVirtualDir",
+                //                                     new XAttribute("Id", wVDir.Name.Expand()),
+                //                                     new XAttribute("Alias", wVDir.Alias.IsEmpty() ? wVDir.Name : wVDir.Alias),
+                //                                     new XAttribute("Directory", dirID),
+                //                                     new XAttribute("WebSite", wVDir.WebSite.Name.Expand()),
+                //                                     xWebApp = new XElement(ns + "WebApplication",
+                //                                         new XAttribute("Id", wVDir.AppName.Expand() + "WebApplication"),
+                //                                         new XAttribute("Name", wVDir.AppName))));
+                //if (wVDir.AllowSessions.HasValue)
+                //    xWebApp.Add(new XAttribute("AllowSessions", wVDir.AllowSessions.Value.ToYesNo()));
+                //if (wVDir.Buffer.HasValue)
+                //    xWebApp.Add(new XAttribute("Buffer", wVDir.Buffer.Value.ToYesNo()));
+                //if (wVDir.ClientDebugging.HasValue)
+                //    xWebApp.Add(new XAttribute("ClientDebugging", wVDir.ClientDebugging.Value.ToYesNo()));
+                //if (wVDir.DefaultScript.HasValue)
+                //    xWebApp.Add(new XAttribute("DefaultScript", wVDir.DefaultScript.Value.ToString()));
+                //if (wVDir.Isolation.HasValue)
+                //    xWebApp.Add(new XAttribute("Isolation", wVDir.Isolation.Value.ToString()));
+                //if (wVDir.ParentPaths.HasValue)
+                //    xWebApp.Add(new XAttribute("ParentPaths", wVDir.ParentPaths.Value.ToYesNo()));
+                //if (wVDir.ScriptTimeout.HasValue)
+                //    xWebApp.Add(new XAttribute("ScriptTimeout", wVDir.ScriptTimeout.Value));
+                //if (wVDir.ServerDebugging.HasValue)
+                //    xWebApp.Add(new XAttribute("ServerDebugging", wVDir.ServerDebugging.Value.ToYesNo()));
+                //if (wVDir.SessionTimeout.HasValue)
+                //    xWebApp.Add(new XAttribute("SessionTimeout", wVDir.SessionTimeout.Value));
 
                 //do not create WebSite on IIS but install WebApp into existing
                 if (!wVDir.WebSite.InstallWebSite)
@@ -1586,14 +1618,14 @@ namespace WixSharp
                 }
                 else
                 {
-                    InsertWebSite(wVDir.WebSite, dirID, component);
+                    InsertWebSite(wVDir.WebSite, dirID, component, wVDir);
                 }
 
                 if (wVDir.WebAppPool != null)
                 {
                     var id = wVDir.Name.Expand() + "_AppPool";
 
-                    xWebApp.Add(new XAttribute("WebAppPool", id));
+                    //xWebApp.Add(new XAttribute("WebAppPool", id));
 
                     var xAppPool = component.AddElement(new XElement(ns + "WebAppPool",
                                                             new XAttribute("Id", id),
@@ -1611,7 +1643,7 @@ namespace WixSharp
 
                     xDirProp.AddAttributes(wVDir.WebDirProperties.Attributes);
 
-                    xVDir.Add(new XAttribute("DirProperties", propId));
+                    //xVDir.Add(new XAttribute("DirProperties", propId));
                 }
             }
 
diff --git a/src/WixSharp/Controls/CustomUI.cs b/src/WixSharp/Controls/CustomUI.cs
index 7214fa4..e2b9361 100644
--- a/src/WixSharp/Controls/CustomUI.cs
+++ b/src/WixSharp/Controls/CustomUI.cs
@@ -173,7 +173,7 @@ namespace WixSharp
         public Dictionary<string, string> Properties = new Dictionary<string, string>()
         {
             {"DefaultUIFont", "WixUI_Font_Normal"},
-            {"WIXUI_INSTALLDIR", "TARGETDIR"},
+            {"WIXUI_INSTALLDIR", "INSTALLDIR"},
             {"PIDTemplate", "####-####-####-####"},
             {"ARPNOMODIFY", "1"}
         };