11

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?

4

4 回答 4

7

将新项目添加到您的安装解决方案(Windows Installer XML -> C# 自定义操作项目)

在此项目中添加对程序集 Microsoft.Web.Administration 的引用,该引用可在此处找到:C:\Windows\System32\inetsrv 并且是添加协议所必需的。

我的自定义操作如下所示:

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;
            }
        }
    }
}

请注意,我在这里假设三个属性:SITE、VIRTUALDIRECTORYALIAS & PROTOCOLS

立即构建解决方案。在后台,WiX 创建了两个程序集 %Project%.dll 和 %Project%.CA.dll。CA.dll 自动包含依赖的 Microsoft.Web.Administration。

然后在您的 WiX 设置项目中包含对新自定义操作项目的引用。引用 %Projet%.CA.dll 需要该引用。

编辑 product.wxs

首先在产品元素内的某处添加属性:

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

下面添加二进制元素:

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

请注意,您必须添加 CA.dll。

下面添加自定义操作:

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

最后是您希望执行的安装顺序。

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

就这样。应该管用。感谢 Darin Dimitrov 提供上述链接。

于 2012-06-21T14:52:53.787 回答
5

这是在 WIX 中执行此操作的正确方法(假设您在 64 位操作系统上安装 - 如果不是猜测,我会说更改CAQuietExec64为,CAQuietExec尽管这未经测试):

获取对 appcmd.exe 的引用:

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

定义以下自定义操作(属性[WEB_SITE_NAME][WEB_APP_NAME]可以在安装程序的其他位置填充;或者为了测试您可以对它们进行硬编码):

<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" />

现在在InstallExecuteSequence添加

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

如果世界上一切都好,那么现在将更新协议。

于 2013-12-05T09:49:15.610 回答
1

据我所知,这不能使用标准WiXIIExtension来完成。因此,您唯一的选择是自定义操作。

您还可以发现这个线程很有趣 - 它提示了如何在 MSBuild 脚本中实现类似的事情,但您应该能够轻松地将其转换为自定义操作。

祝你好运!

于 2010-11-25T12:12:22.690 回答
1

您可以查看 MSDN 上的这篇文章。最后有一节说明了如何使用托管 API来实现配置启用 WAS 的服务。我不熟悉 Wix,但您可能可以使用此代码并将其插入到一些自定义部署步骤中。

于 2010-11-22T12:27:37.553 回答