Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add net.tcp to the "Enabled protocols" by using a WIX 3.5 project/setup?

We have a few MSI packages (generated by WIX) that install WCF services. Most of these services need net.tcp for their endpoint bindings.

I'd like to make our deployment life easier and automate the process of adding net.tcp. I already know the WixIisExtension.dll and make use of its useful functions (create web site, virt. directory, etc.).

Can I use the WixIisExtension to enable the net.tcp protocol? If not, how can I achieve that?

like image 295
DonKotlino Avatar asked Jun 29 '10 12:06

DonKotlino


3 Answers

Add a new Project to your Setup Solution (Windows Installer XML -> C# Custom Action Project)

In this Project add a reference to the Assembly Microsoft.Web.Administration, which can be found here: C:\Windows\System32\inetsrv and is required to add the protocols.

My Custom Action looks like this:

using System;
using System.Linq;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Web.Administration;

namespace Setup.CustomAction.EnableProtocols
{
    public class CustomActions
    {
        [CustomAction]
        public static ActionResult EnableProtocols(Session session)
        {
            session.Log("Begin EnableProtocols");

            var siteName = session["SITE"];
            if (string.IsNullOrEmpty(siteName))
            {
                session.Log("Property [SITE] missing");
                return ActionResult.NotExecuted;
            }

            var alias = session["VIRTUALDIRECTORYALIAS"];
            if (string.IsNullOrEmpty(alias))
            {
                session.Log("Property [VIRTUALDIRECTORYALIAS] missing");
                return ActionResult.NotExecuted;
            }

            var protocols = session["PROTOCOLS"];
            if (string.IsNullOrEmpty(protocols))
            {
                session.Log("Property [PROTOCOLS] missing");
                return ActionResult.NotExecuted;
            }

            try
            {
                var manager = new ServerManager();

                var site = manager.Sites.FirstOrDefault(x => x.Name.ToUpper() == siteName.ToUpper());
                if (site == null)
                {
                    session.Log("Site with name {0} not found", siteName);
                    return ActionResult.NotExecuted;
                }

                var application = site.Applications.FirstOrDefault(x => x.Path.ToUpper().Contains(alias.ToUpper()));
                if (application == null)
                {
                    session.Log("Application with path containing {0} not found", alias);
                    return ActionResult.NotExecuted;
                }

                application.EnabledProtocols = protocols;
                manager.CommitChanges();
                return ActionResult.Success;
            }
            catch (Exception exception)
            {
                session.Log("Error setting enabled protocols: {0}", exception.ToString());
                return ActionResult.Failure;
            }
        }
    }
}

Please note that I am assuming three properties here: SITE, VIRTUALDIRECTORYALIAS & PROTOCOLS

Build the solution now. In the background, WiX creates two assemblies %Project%.dll and %Project%.CA.dll. The CA.dll includes the depending Microsoft.Web.Administration automatically.

Then in your WiX Setup Project include a reference to the new Custom Action Project. The reference is required for referencing the %Projet%.CA.dll.

Edit the product.wxs

First add the properties somewhere inside the product element:

<!-- Properties -->
<Property Id="SITE" Value="MySite" />
<Property Id="VIRTUALDIRECTORYALIAS" Value="MyVirtDirectoryAlias" />
<Property Id="PROTOCOLS" Value="http,net.tcp" />

Below add the binary element:

<!-- Binaries -->
<Binary Id="CustomAction.EnableProtocols" SourceFile="$(var.Setup.CustomAction.EnableProtocols.TargetDir)Setup.CustomAction.EnableProtocols.CA.dll" />

Note that you have to add the CA.dll.

Below add the Custom Action:

<!-- Custom Actions -->
<CustomAction Id="EnableProtocols" BinaryKey="CustomAction.EnableProtocols" DllEntry="EnableProtocols" Execute="immediate" Return="check" />

And finally the Installation Sequence where you want the execution to take place.

<!-- Installation Sequence -->
<InstallExecuteSequence>
  <Custom Action="EnableProtocols" After="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>

that's all. Should work. Thanks to Darin Dimitrov for providing the links above.

like image 116
ms007 Avatar answered Sep 22 '22 21:09

ms007


Here is the right way to do this in WIX (assuming you are installing on a 64-bit operating system - if not at a guess I'd say change CAQuietExec64 to CAQuietExec although this is untested):

Get a reference to appcmd.exe:

<Property Id="APPCMD">
  <DirectorySearch Id="FindAppCmd" Depth="1" Path="[WindowsFolder]\system32\inetsrv\">
    <FileSearch Name="appcmd.exe"/>
  </DirectorySearch>
</Property>

Define the following custom actions (the properties [WEB_SITE_NAME] and [WEB_APP_NAME] can be populated elsewhere in your installer; or to test you can hard-code them):

<CustomAction
  Id="SetEnableNetTCPCommmand"
  Property="EnableNetTCP"
  Value="&quot;[APPCMD]&quot; set app &quot;[WEB_SITE_NAME]/[WEB_APP_NAME]&quot; /enabledProtocols:http,net.tcp"/>

<CustomAction 
  Id="EnableNetTCP"
  BinaryKey="WixCA"
  DllEntry="CAQuietExec64"
  Execute="deferred"
  Return="ignore"
  Impersonate="no" />

Now in the InstallExecuteSequence add

<InstallExecuteSequence>
  ...
  <Custom Action="SetEnableNetTCPCommmand" After="InstallExecute">APPCMD AND NOT Installed</Custom>
  <Custom Action="EnableNetTCP" After="SetEnableNetTCPCommmand">APPCMD AND NOT Installed</Custom>
  ...
</InstallExecuteSequence>

And if all is well in the world that will now update the protocols.

like image 20
satnhak Avatar answered Sep 19 '22 21:09

satnhak


You may take a look at this article on MSDN. There's a section at the end which illustrates how to use the managed API to achieve configure a WAS enabled service. I am not familiar with Wix but you could probably use and plug this code into some custom deployment step.

like image 33
Darin Dimitrov Avatar answered Sep 19 '22 21:09

Darin Dimitrov