使用初始 IIS 设置安装 Web 应用程序;使用 WiX,需要升级文件,而不是更改 IIS 设置

发布于 2025-01-01 07:15:18 字数 2668 浏览 1 评论 0原文

我有一个 WiX 安装项目,其中包括虚拟目录的 IIS 设置和带有应用程序池的应用程序设置。初始安装后,客户将从 wxs.conf 中设置的默认网络服务中更改应用程序池标识。

如何构建可以更新 Web 文件但不更改 IIS 设置、应用程序池标识回网络服务的更新安装程序?

ComponentGroupRef Id="WebPublishCmp" 是要发布的 Web 文件的初始热输出。

我尝试使用 TorchPyro,但我遇到了 Torch diff 未检测到更改的问题(这是另一个堆栈溢出问题的另一个问题)。

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">

  <?include Config.wxi ?>

  <Product
    Id="E3105F82-0460-4C3C-8F6C-778405E81F61"
    Name="Website"
    Language="1033"
    Version="1.0.0.1"
    Manufacturer="Website"
    UpgradeCode="E3105F82-0460-4C3C-8F6C-778405E81F61">

    <Package
      InstallerVersion="200" Compressed="yes" />

    <Media
      Id="1"
      Cabinet="media1.cab"
      EmbedCab="yes" />

    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
    <UIRef Id="CustomWixUI_InstallDir"/>

    <FeatureRef Id="InitialFeature"/>

  </Product>

  <Fragment>
    <Feature Id="InitialFeature" Title="Initial (Full)" Level="1">
      <ComponentGroupRef Id="WebPublishCmp"/>
      <ComponentRef Id="IIS.Component"/>
    </Feature>

    <Feature Id="WebFilesFeature" Title="Website (Files)" Level="1">
      <ComponentGroupRef Id="WebPublishCmp"/>
    </Feature>


  </Fragment>

  <Fragment>
    <Component Id="IIS.Component" Guid="6FAD9EC7-D2B0-4471-A657-C8AF5F6F707F" KeyPath="yes" Directory="INSTALLLOCATION">
      <iis:WebSite Id="DefaultWebSite" Description="$(var.WebSiteName)" Directory="INSTALLLOCATION" >
        <iis:WebAddress Id="AllUnassigned" Port="80"/>
      </iis:WebSite>
      <iis:WebAppPool Id="WebsiteAppPool" Name="App" Identity="networkService" />
      <iis:WebVirtualDir Id="My.VirtualDir" Alias="App" Directory="INSTALLLOCATION" WebSite="DefaultWebSite">
        <iis:WebApplication Id="Application" Name="App" WebAppPool="WebsiteAppPool"/>
      </iis:WebVirtualDir>
    </Component>
  </Fragment>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLLOCATION" Name="Website">
        </Directory>
      </Directory>
    </Directory>
  </Fragment>
</Wix>

我正在使用:

  • WiX 3.5、3.6
  • Visual Studio 2010

I have a WiX install project that includes IIS setings for virtual directory and application settings with an application pool. After initial install, the customer will change the application pool identity from default network service set in wxs.

How can I build an update installer that can update web files, but not change the IIS settings, application pool identity back to network service?

ComponentGroupRef Id="WebPublishCmp" is the initial heat output of the web files to publish.

I have tried to build a minor upgrade using Torch and Pyro, but I am having issues with Torch diff not detecting changes (this is another issue for another Stack Overflow question).

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">

  <?include Config.wxi ?>

  <Product
    Id="E3105F82-0460-4C3C-8F6C-778405E81F61"
    Name="Website"
    Language="1033"
    Version="1.0.0.1"
    Manufacturer="Website"
    UpgradeCode="E3105F82-0460-4C3C-8F6C-778405E81F61">

    <Package
      InstallerVersion="200" Compressed="yes" />

    <Media
      Id="1"
      Cabinet="media1.cab"
      EmbedCab="yes" />

    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
    <UIRef Id="CustomWixUI_InstallDir"/>

    <FeatureRef Id="InitialFeature"/>

  </Product>

  <Fragment>
    <Feature Id="InitialFeature" Title="Initial (Full)" Level="1">
      <ComponentGroupRef Id="WebPublishCmp"/>
      <ComponentRef Id="IIS.Component"/>
    </Feature>

    <Feature Id="WebFilesFeature" Title="Website (Files)" Level="1">
      <ComponentGroupRef Id="WebPublishCmp"/>
    </Feature>


  </Fragment>

  <Fragment>
    <Component Id="IIS.Component" Guid="6FAD9EC7-D2B0-4471-A657-C8AF5F6F707F" KeyPath="yes" Directory="INSTALLLOCATION">
      <iis:WebSite Id="DefaultWebSite" Description="$(var.WebSiteName)" Directory="INSTALLLOCATION" >
        <iis:WebAddress Id="AllUnassigned" Port="80"/>
      </iis:WebSite>
      <iis:WebAppPool Id="WebsiteAppPool" Name="App" Identity="networkService" />
      <iis:WebVirtualDir Id="My.VirtualDir" Alias="App" Directory="INSTALLLOCATION" WebSite="DefaultWebSite">
        <iis:WebApplication Id="Application" Name="App" WebAppPool="WebsiteAppPool"/>
      </iis:WebVirtualDir>
    </Component>
  </Fragment>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLLOCATION" Name="Website">
        </Directory>
      </Directory>
    </Directory>
  </Fragment>
</Wix>

I am using:

  • WiX 3.5, 3.6
  • Visual Studio 2010

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红ご颜醉 2025-01-08 07:15:18

我提前为冗长的答案表示歉意:

我建议将您的网站和内容保留在两个单独的功能中,然后让他们选择通过 UI 或命令行参数提供安装所需的任何变量。如果您使用 "记住属性"模式,那么您可以回忆起更改或升级安装时使用的变量(一路阅读通过最后的评论,有一种稍微简单的方法)。

这允许安装产品的人员使用给定变量设置所有内容,或自行设置 IIS 网站并仅安装网站内容。

这也与 MajorUpgrades 配合得很好。我目前在您提供的代码中看不到升级信息,因此您应该查看 MajorUpgrades 与补丁(主要升级更容易)

<MajorUpgrade AllowDowngrades="no" AllowSameVersionUpgrades="yes" Schedule="afterInstallInitialize" DowngradeErrorMessage="A later version of of this product is already installed. Setup will now exit."/>

记住,通过 $(var.name) 访问的变量在 MSI 编译时使用,而通过括号访问的公共变量[MY_VARIABLE] 在安装时使用。公共变量可以通过 MSI UI 公开,或通过命令行提供给 msiexec(我将其用于静默安装和/或指定日志文件)

以下是下面示例的摘要:

  • Configuration.wxi - 此文件实现“记住”属性
  • Product.wxs - 大部分与您的类似,但还包括 MajorUpgrades、网站和内容的单独功能以及 UiFlow 的包含
  • IISConfiguration.wxs - 包含 IIS 网站、AppPool 和 AppPool 用户的片段,使用安装时提供的变量
  • UIFlow.wxs - 定义要使用的 UI 流程,它是使用 WixUI FeatureTree 插件,您的 UI 可能需要其他东西
  • UIDialogs.wxs - 这是安装中使用的变量暴露给 UI

Configuration.wxi 的地方:

<?xml version="1.0" encoding="utf-8" ?>
<Include xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
    
    <!-- The RegistrySearch elements will populate these properties with values from the registry IF they exist there, otherwise the default values will be used -->
    <Property Id="REG_WEBSITE_NAME" Value="WebsiteName" >
        <RegistrySearch Id="WEB_WEBSITE_NAME_Remembered" Root="HKLM" Key="SOFTWARE\PRODUCT_NAME" Name="Website_Name" Type="raw" />
    </Property>
    <Property Id="REG_WEB_APP_POOL_NAME" Value="PoolName" >
        <RegistrySearch Id="WEB_APP_POOL_NAME_Remembered" Root="HKLM" Key="SOFTWARE\PRODUCT_NAME" Name="WebApp_PoolName" Type="raw" />
    </Property>
    <Property Id="REG_WEB_APP_POOL_IDENTITY_DOMAIN">
        <RegistrySearch Id="WEB_APP_POOL_IDENTITY_DOMAIN_Remembered" Root="HKLM" Key="SOFTWARE\PRODUCT_NAME" Name="WebApp_PoolIdentityDomain" Type="raw" />
    </Property>
    <Property Id="REG_WEB_APP_POOL_IDENTITY_USERNAME" Value="NetworkService" >
        <RegistrySearch Id="WEB_APP_POOL_IDENTITY_USERNAME_Remembered" Root="HKLM" Key="SOFTWARE\PRODUCT_NAME" Name="WebApp_PoolIdentityUsername" Type="raw" />
    </Property>
    <!-- Notice that the password is NOT stored in the registry and is hidden so it's not shown in logs -->
    <Property Id="WEB_APP_POOL_IDENTITY_PWD" Hidden="yes" />

    <!-- This is the compnent that actually writes the values to the registry on install -->
    <Component Id="C_RegistryEntries" Directory="INSTALLLOCATION">
        <RegistryValue Root="HKLM" Key="SOFTWARE\ProviderWebsites" Name="Website_Name"                  Type="string" Value="[WEBSITE_NAME]"/>
        <RegistryValue Root="HKLM" Key="SOFTWARE\ProviderWebsites" Name="WebApp_PoolName"               Type="string" Value="[WEB_APP_POOL_NAME]"/>
        <RegistryValue Root="HKLM" Key="SOFTWARE\ProviderWebsites" Name="WebApp_PoolIdentityDomain"     Type="string" Value="[WEB_APP_POOL_IDENTITY_DOMAIN]"/>
        <RegistryValue Root="HKLM" Key="SOFTWARE\ProviderWebsites" Name="WebApp_PoolIdentityUsername"   Type="string" Value="[WEB_APP_POOL_IDENTITY_USERNAME]"/>
    </Component>

    <!-- These CustomActions set the property that are used for the install from the registry values (These actions are only run under the conditions in the sequences below) -->
    <CustomAction Id='SetWebAppName'                    Property='WEBSITE_NAME'                     Value='[REG_WEBSITE_NAME]'/>
    <CustomAction Id='SetWebAppPoolName'                Property='WEB_APP_POOL_NAME'                Value='[REG_WEB_APP_POOL_NAME]'/>
    <CustomAction Id='SetWebAppPoolIdentityDomain'      Property='WEB_APP_POOL_IDENTITY_DOMAIN'     Value='[REG_WEB_APP_POOL_IDENTITY_DOMAIN]'/>
    <CustomAction Id='SetWebAppPoolIdentityUsername'    Property='WEB_APP_POOL_IDENTITY_USERNAME'   Value='[REG_WEB_APP_POOL_IDENTITY_USERNAME]'/>
    
    <!-- The CustomActions above that set the variables used in the installation are only run if they were not supplied by the command line -->
    <InstallUISequence>
        <Custom Action='SetWebAppName'                  After='AppSearch'>REG_WEBSITE_NAME                      AND (NOT WEBSITE_NAME)</Custom>
        <Custom Action='SetWebAppPoolName'              After='AppSearch'>REG_WEB_APP_POOL_NAME                 AND (NOT WEB_APP_POOL_NAME)</Custom>
        <Custom Action='SetWebAppPoolIdentityDomain'    After='AppSearch'>REG_WEB_APP_POOL_IDENTITY_DOMAIN      AND (NOT WEB_APP_POOL_IDENTITY_DOMAIN)</Custom>
        <Custom Action='SetWebAppPoolIdentityUsername'  After='AppSearch'>REG_WEB_APP_POOL_IDENTITY_USERNAME    AND (NOT WEB_APP_POOL_IDENTITY_USERNAME)</Custom>
    </InstallUISequence>
    <InstallExecuteSequence>
        <!-- After='RemoveExistingProducts' is used under this sequence because of the use of MajorUpgrades -->
        <Custom Action='SetWebAppName'                  After='RemoveExistingProducts'>REG_WEBSITE_NAME                     AND (NOT WEBSITE_NAME)</Custom>
        <Custom Action='SetWebAppPoolName'              After='RemoveExistingProducts'>REG_WEB_APP_POOL_NAME                    AND (NOT WEB_APP_POOL_NAME)</Custom>
        <Custom Action='SetWebAppPoolIdentityDomain'    After='RemoveExistingProducts'>REG_WEB_APP_POOL_IDENTITY_DOMAIN     AND (NOT WEB_APP_POOL_IDENTITY_DOMAIN)</Custom>
        <Custom Action='SetWebAppPoolIdentityUsername'  After='RemoveExistingProducts'>REG_WEB_APP_POOL_IDENTITY_USERNAME   AND (NOT WEB_APP_POOL_IDENTITY_USERNAME)</Custom>
    </InstallExecuteSequence>

</Include>

产品.wxs:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">

    <!--NEVER EVER EVER EVER CHANGE THE UPGRADE CODE!!!!!!!!!!!!!!! -->
    <?define UpgradeCode="PUT-GUID-HERE" ?>

    <Product Id="*" Name="ProductName" Language="1033" Version="X.X.X.X" Manufacturer="XYZ" UpgradeCode="$(var.UpgradeCode)">
        <Package InstallerVersion="200" Compressed="yes" />

        <!-- This includes our properties that implement the "Remember Property" pattern -->
        <?include Configuration.wxi ?>

        <Media Id="1" Cabinet="media.cab" EmbedCab="yes" />

        <MajorUpgrade AllowDowngrades="no" AllowSameVersionUpgrades="yes" Schedule="afterInstallInitialize"
                      DowngradeErrorMessage="A later version of this product is already installed. Setup will now exit."/>

        <!-- Creating default directory structure (INSTALLLOCATION be override by user, but it starts in Program Files) -->
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id='ProgramFilesFolder' Name='PFiles'>
                <Directory Id="INSTALLLOCATION" Name="TheDefaultInstallFolderName">

                </Directory>
            </Directory>
        </Directory>

        <Feature Id="F_Content" Title="Content" Level="1" Description="The website content" ConfigurableDirectory="INSTALLLOCATION">
            <ComponentRef Id="C_RegistryEntries"/>
            <!-- The C_WebAppContent can either be generated by the WiX tool "heat", or a hand-crafted set of content, this component is not included in this example -->
            <ComponentGroupRef Id="C_WebAppContent" />
        </Feature>

        <Feature Id="F_IISWebsite" Title="IIS Website" Description="The IIS website and application pool" Level="1">
            <ComponentRef Id="C_IISWebsite" />
        </Feature>

        <InstallExecuteSequence>
        </InstallExecuteSequence>

        <!-- Specify UI -->
        <UIRef Id="UIFlow" />
    </Product>
</Wix>

IISConfiguration.wxs:

<?xml version="1.0" encoding="utf-8" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

    <Fragment>      
        <DirectoryRef Id="INSTALLLOCATION">
            <Component Id="C_IISWebsite" Guid="{PUT-GUID-HERE}" KeyPath="yes">
                <!-- This does not create a user, it's just an object that's referenced by the WebAppPool component -->
                <util:User Id="WebAppPoolUser" CreateUser="no" Name="[WEB_APP_POOL_IDENTITY_USERNAME]" 
                           Password="[WEB_APP_POOL_IDENTITY_PWD]" Domain="[WEB_APP_POOL_IDENTITY_DOMAIN]"/>

                <!-- The "Identity" attritbute below needs to be set to "other" to use the util:User defined above -->
                <iis:WebAppPool Id="WebAppPool" Name="[WEB_APP_POOL_NAME]" Identity="other" User="WebAppPoolUser"/>
                
                <iis:WebSite Id="DefaultWebSite" Description="[WEBSITE_NAME]" Directory="INSTALLLOCATION" >
                    <iis:WebAddress Id="AllUnassigned" Port="80"/>
                </iis:WebSite>
                
                <iis:WebVirtualDir Id="My.VirtualDir" Alias="App" Directory="INSTALLLOCATION" WebSite="DefaultWebSite">
                    <iis:WebApplication Id="Application" Name="App" WebAppPool="WebAppPool"/>
                </iis:WebVirtualDir>
            </Component>
        </DirectoryRef>
    </Fragment>
</Wix>

UIFlow.wxs:

<?xml version="1.0" encoding="utf-8" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <UI Id="UIFlow">
            <!-- This uses the WixUI plugin -->
            <UIRef Id="WixUI_FeatureTree" />
            <UIRef Id="WixUI_ErrorProgressText" />

            <!-- Injection of custom UI. -->
            <DialogRef Id="IisSetupDlg" />
            
            <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="IisSetupDlg" Order="3">LicenseAccepted = "1"</Publish>
            <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="PoolSettingsDlg">1</Publish>
        </UI>
    </Fragment>
</Wix>

UIDialogs.wxs:

<?xml version="1.0" encoding="utf-8" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <UI>
            <Dialog Id="IisSetupDlg" Width="370" Height="270" Title="IIS Settings - [ProductName]" NoMinimize="yes">                
                <!-- Web App details prompt -->
                <Control Id="WebsiteNameLabel" Type="Text" X="45" Y="53" Width="100" Height="15" TabSkip="no" Text="&Website Name:" />
                <Control Id="WebsiteNameEdit" Type="Edit" X="45" Y="65" Width="220" Height="18" Property="WEBSITE_NAME" Text="{80}" />
                
                <!-- Back button -->
                <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&Back">
                    <Publish Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
                </Control>
                
                <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&Next">
                    <Publish Event="NewDialog" Value="PoolSettingsDlg">
                        <!--if settings are correct, allow next dialog-->
                        <![CDATA[WEBSITE_NAME <> ""]]>
                    </Publish>
                </Control>
                
                <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
                    <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
                </Control>
                
                <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
                <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
                    <Text>Please enter IIS Configuration</Text>
                </Control>
                
                <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
                <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
                    <Text>{\WixUI_Font_Title}IIS Settings</Text>
                </Control>
                
                <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
            </Dialog>

            <Dialog Id="PoolSettingsDlg" Width="370" Height="300" Title="Application Pool Settings - [ProductName]" NoMinimize="yes">
                <!-- name of the application pool -->
                <Control Id="PoolNameLabel" Type="Text" X="45" Y="53" Width="100" Height="15" TabSkip="no" Text="&Pool name:" />
                <Control Id="PoolNameEdit" Type="Edit" X="45" Y="65" Width="220" Height="18" Property="WEB_APP_POOL_NAME" Text="{80}" />
                
                <!-- domain -->
                <Control Id="DomainPoolLabel" Type="Text" X="45" Y="85" Width="100" Height="15" TabSkip="no" Text="&Domain for AppPool:" />
                <Control Id="DomainPoolEdit" Type="Edit" X="45" Y="97" Width="220" Height="18" Property="WEB_APP_POOL_IDENTITY_DOMAIN" Text="{80}" />
                
                <!-- Login -->
                <Control Id="LoginPoolLabel" Type="Text" X="45" Y="117" Width="100" Height="15" TabSkip="no" Text="&Login for AppPool:" />
                <Control Id="LoginPoolEdit" Type="Edit" X="45" Y="129" Width="220" Height="18" Property="WEB_APP_POOL_IDENTITY_USERNAME" Text="{80}" />
                
                <!-- Password -->
                <Control Id="PasswordPoolLabel" Type="Text" X="45" Y="149" Width="100" Height="15" TabSkip="no" Text="&Password for AppPool:" />
                <Control Id="PasswordPoolEdit" Type="Edit" X="45" Y="161" Width="220" Height="18" Property="WEB_APP_POOL_IDENTITY_PWD" Text="{80}" Password="yes" />
                
                <!-- Back button -->
                <Control Id="Back" Type="PushButton" X="180" Y="264" Width="56" Height="17" Text="&Back">
                    <Publish Event="NewDialog" Value="IisSetupDlg">1</Publish>
                </Control>
                <Control Id="Next" Type="PushButton" X="236" Y="264" Width="56" Height="17" Default="yes" Text="&Next">
                    <Publish Event="NewDialog" Value="CustomizeDlg">
                        <!--if settings are correct, allow next dialog-->
                        <![CDATA[WEB_APP_POOL_NAME <> "" 
                                 or WEB_APP_POOL_IDENTITY_DOMAIN <> "" 
                                 or WEB_APP_POOL_IDENTITY_USERNAME <> "" 
                                 or WEB_APP_POOL_IDENTITY_PWD <> ""]]>
                    </Publish>
                </Control>
                
                <Control Id="Cancel" Type="PushButton" X="304" Y="264" Width="56" Height="17" Cancel="yes" Text="Cancel">
                    <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
                </Control>
                
                <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
                <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
                    <Text>Please enter AppPool Configuration for IIS</Text>
                </Control>
                
                <Control Id="BottomLine" Type="Line" X="0" Y="255" Width="370" Height="0" />
                <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
                    <Text>{\WixUI_Font_Title}Application Pool Settings</Text>
                </Control>
                
                <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
            </Dialog>
        </UI>
    </Fragment>
</Wix>

I apologize ahead of time for the long answer:

I recommend keeping your Website and Content in two separate features and then giving them the option of supplying any variables needed for installation via UI or command line parameters. If you use the "Remember Property" pattern, then you can recall the variables used when changing or upgrading an installation (read all the way through the last comments, there is a slightly simpler way of doing it).

This allows the person installing the product to set up everything with the given variables or set up the IIS website on their own and install only website content.

This also jives well with MajorUpgrades. I don't currently see upgrade information in code you provided, so you should look into MajorUpgrades vs patches (major upgrades are much easier)

<MajorUpgrade AllowDowngrades="no" AllowSameVersionUpgrades="yes" Schedule="afterInstallInitialize" DowngradeErrorMessage="A later version of of this product is already installed. Setup will now exit."/>

Remember, variables accessed by $(var.name) are used at MSI compile time, whereas public variables accessed via brackets [MY_VARIABLE] are used at install time. Public variables can be exposed through the MSI UI, or provided to msiexec via command line (I use this for silent installs and/or specifying a log file)

Here is a summary of the examples included below:

  • Configuration.wxi - This file implements the "remembered" properties
  • Product.wxs - Mostly like yours, but also includes MajorUpgrades, separate features for the website and content, and an inclusion of the UiFlow
  • IISConfiguration.wxs - A fragment containing the IIS Website, AppPool, and AppPool User using variables supplied at install time
  • UIFlow.wxs - Defining the flow of the UI to use, it's using the WixUI FeatureTree plugin, you may require something else for your UI
  • UIDialogs.wxs - This is where the variables used in installation are exposed to the UI

Configuration.wxi:

<?xml version="1.0" encoding="utf-8" ?>
<Include xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
    
    <!-- The RegistrySearch elements will populate these properties with values from the registry IF they exist there, otherwise the default values will be used -->
    <Property Id="REG_WEBSITE_NAME" Value="WebsiteName" >
        <RegistrySearch Id="WEB_WEBSITE_NAME_Remembered" Root="HKLM" Key="SOFTWARE\PRODUCT_NAME" Name="Website_Name" Type="raw" />
    </Property>
    <Property Id="REG_WEB_APP_POOL_NAME" Value="PoolName" >
        <RegistrySearch Id="WEB_APP_POOL_NAME_Remembered" Root="HKLM" Key="SOFTWARE\PRODUCT_NAME" Name="WebApp_PoolName" Type="raw" />
    </Property>
    <Property Id="REG_WEB_APP_POOL_IDENTITY_DOMAIN">
        <RegistrySearch Id="WEB_APP_POOL_IDENTITY_DOMAIN_Remembered" Root="HKLM" Key="SOFTWARE\PRODUCT_NAME" Name="WebApp_PoolIdentityDomain" Type="raw" />
    </Property>
    <Property Id="REG_WEB_APP_POOL_IDENTITY_USERNAME" Value="NetworkService" >
        <RegistrySearch Id="WEB_APP_POOL_IDENTITY_USERNAME_Remembered" Root="HKLM" Key="SOFTWARE\PRODUCT_NAME" Name="WebApp_PoolIdentityUsername" Type="raw" />
    </Property>
    <!-- Notice that the password is NOT stored in the registry and is hidden so it's not shown in logs -->
    <Property Id="WEB_APP_POOL_IDENTITY_PWD" Hidden="yes" />

    <!-- This is the compnent that actually writes the values to the registry on install -->
    <Component Id="C_RegistryEntries" Directory="INSTALLLOCATION">
        <RegistryValue Root="HKLM" Key="SOFTWARE\ProviderWebsites" Name="Website_Name"                  Type="string" Value="[WEBSITE_NAME]"/>
        <RegistryValue Root="HKLM" Key="SOFTWARE\ProviderWebsites" Name="WebApp_PoolName"               Type="string" Value="[WEB_APP_POOL_NAME]"/>
        <RegistryValue Root="HKLM" Key="SOFTWARE\ProviderWebsites" Name="WebApp_PoolIdentityDomain"     Type="string" Value="[WEB_APP_POOL_IDENTITY_DOMAIN]"/>
        <RegistryValue Root="HKLM" Key="SOFTWARE\ProviderWebsites" Name="WebApp_PoolIdentityUsername"   Type="string" Value="[WEB_APP_POOL_IDENTITY_USERNAME]"/>
    </Component>

    <!-- These CustomActions set the property that are used for the install from the registry values (These actions are only run under the conditions in the sequences below) -->
    <CustomAction Id='SetWebAppName'                    Property='WEBSITE_NAME'                     Value='[REG_WEBSITE_NAME]'/>
    <CustomAction Id='SetWebAppPoolName'                Property='WEB_APP_POOL_NAME'                Value='[REG_WEB_APP_POOL_NAME]'/>
    <CustomAction Id='SetWebAppPoolIdentityDomain'      Property='WEB_APP_POOL_IDENTITY_DOMAIN'     Value='[REG_WEB_APP_POOL_IDENTITY_DOMAIN]'/>
    <CustomAction Id='SetWebAppPoolIdentityUsername'    Property='WEB_APP_POOL_IDENTITY_USERNAME'   Value='[REG_WEB_APP_POOL_IDENTITY_USERNAME]'/>
    
    <!-- The CustomActions above that set the variables used in the installation are only run if they were not supplied by the command line -->
    <InstallUISequence>
        <Custom Action='SetWebAppName'                  After='AppSearch'>REG_WEBSITE_NAME                      AND (NOT WEBSITE_NAME)</Custom>
        <Custom Action='SetWebAppPoolName'              After='AppSearch'>REG_WEB_APP_POOL_NAME                 AND (NOT WEB_APP_POOL_NAME)</Custom>
        <Custom Action='SetWebAppPoolIdentityDomain'    After='AppSearch'>REG_WEB_APP_POOL_IDENTITY_DOMAIN      AND (NOT WEB_APP_POOL_IDENTITY_DOMAIN)</Custom>
        <Custom Action='SetWebAppPoolIdentityUsername'  After='AppSearch'>REG_WEB_APP_POOL_IDENTITY_USERNAME    AND (NOT WEB_APP_POOL_IDENTITY_USERNAME)</Custom>
    </InstallUISequence>
    <InstallExecuteSequence>
        <!-- After='RemoveExistingProducts' is used under this sequence because of the use of MajorUpgrades -->
        <Custom Action='SetWebAppName'                  After='RemoveExistingProducts'>REG_WEBSITE_NAME                     AND (NOT WEBSITE_NAME)</Custom>
        <Custom Action='SetWebAppPoolName'              After='RemoveExistingProducts'>REG_WEB_APP_POOL_NAME                    AND (NOT WEB_APP_POOL_NAME)</Custom>
        <Custom Action='SetWebAppPoolIdentityDomain'    After='RemoveExistingProducts'>REG_WEB_APP_POOL_IDENTITY_DOMAIN     AND (NOT WEB_APP_POOL_IDENTITY_DOMAIN)</Custom>
        <Custom Action='SetWebAppPoolIdentityUsername'  After='RemoveExistingProducts'>REG_WEB_APP_POOL_IDENTITY_USERNAME   AND (NOT WEB_APP_POOL_IDENTITY_USERNAME)</Custom>
    </InstallExecuteSequence>

</Include>

Product.wxs:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">

    <!--NEVER EVER EVER EVER CHANGE THE UPGRADE CODE!!!!!!!!!!!!!!! -->
    <?define UpgradeCode="PUT-GUID-HERE" ?>

    <Product Id="*" Name="ProductName" Language="1033" Version="X.X.X.X" Manufacturer="XYZ" UpgradeCode="$(var.UpgradeCode)">
        <Package InstallerVersion="200" Compressed="yes" />

        <!-- This includes our properties that implement the "Remember Property" pattern -->
        <?include Configuration.wxi ?>

        <Media Id="1" Cabinet="media.cab" EmbedCab="yes" />

        <MajorUpgrade AllowDowngrades="no" AllowSameVersionUpgrades="yes" Schedule="afterInstallInitialize"
                      DowngradeErrorMessage="A later version of this product is already installed. Setup will now exit."/>

        <!-- Creating default directory structure (INSTALLLOCATION be override by user, but it starts in Program Files) -->
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id='ProgramFilesFolder' Name='PFiles'>
                <Directory Id="INSTALLLOCATION" Name="TheDefaultInstallFolderName">

                </Directory>
            </Directory>
        </Directory>

        <Feature Id="F_Content" Title="Content" Level="1" Description="The website content" ConfigurableDirectory="INSTALLLOCATION">
            <ComponentRef Id="C_RegistryEntries"/>
            <!-- The C_WebAppContent can either be generated by the WiX tool "heat", or a hand-crafted set of content, this component is not included in this example -->
            <ComponentGroupRef Id="C_WebAppContent" />
        </Feature>

        <Feature Id="F_IISWebsite" Title="IIS Website" Description="The IIS website and application pool" Level="1">
            <ComponentRef Id="C_IISWebsite" />
        </Feature>

        <InstallExecuteSequence>
        </InstallExecuteSequence>

        <!-- Specify UI -->
        <UIRef Id="UIFlow" />
    </Product>
</Wix>

IISConfiguration.wxs:

<?xml version="1.0" encoding="utf-8" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

    <Fragment>      
        <DirectoryRef Id="INSTALLLOCATION">
            <Component Id="C_IISWebsite" Guid="{PUT-GUID-HERE}" KeyPath="yes">
                <!-- This does not create a user, it's just an object that's referenced by the WebAppPool component -->
                <util:User Id="WebAppPoolUser" CreateUser="no" Name="[WEB_APP_POOL_IDENTITY_USERNAME]" 
                           Password="[WEB_APP_POOL_IDENTITY_PWD]" Domain="[WEB_APP_POOL_IDENTITY_DOMAIN]"/>

                <!-- The "Identity" attritbute below needs to be set to "other" to use the util:User defined above -->
                <iis:WebAppPool Id="WebAppPool" Name="[WEB_APP_POOL_NAME]" Identity="other" User="WebAppPoolUser"/>
                
                <iis:WebSite Id="DefaultWebSite" Description="[WEBSITE_NAME]" Directory="INSTALLLOCATION" >
                    <iis:WebAddress Id="AllUnassigned" Port="80"/>
                </iis:WebSite>
                
                <iis:WebVirtualDir Id="My.VirtualDir" Alias="App" Directory="INSTALLLOCATION" WebSite="DefaultWebSite">
                    <iis:WebApplication Id="Application" Name="App" WebAppPool="WebAppPool"/>
                </iis:WebVirtualDir>
            </Component>
        </DirectoryRef>
    </Fragment>
</Wix>

UIFlow.wxs:

<?xml version="1.0" encoding="utf-8" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <UI Id="UIFlow">
            <!-- This uses the WixUI plugin -->
            <UIRef Id="WixUI_FeatureTree" />
            <UIRef Id="WixUI_ErrorProgressText" />

            <!-- Injection of custom UI. -->
            <DialogRef Id="IisSetupDlg" />
            
            <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="IisSetupDlg" Order="3">LicenseAccepted = "1"</Publish>
            <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="PoolSettingsDlg">1</Publish>
        </UI>
    </Fragment>
</Wix>

UIDialogs.wxs:

<?xml version="1.0" encoding="utf-8" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <UI>
            <Dialog Id="IisSetupDlg" Width="370" Height="270" Title="IIS Settings - [ProductName]" NoMinimize="yes">                
                <!-- Web App details prompt -->
                <Control Id="WebsiteNameLabel" Type="Text" X="45" Y="53" Width="100" Height="15" TabSkip="no" Text="&Website Name:" />
                <Control Id="WebsiteNameEdit" Type="Edit" X="45" Y="65" Width="220" Height="18" Property="WEBSITE_NAME" Text="{80}" />
                
                <!-- Back button -->
                <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&Back">
                    <Publish Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
                </Control>
                
                <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&Next">
                    <Publish Event="NewDialog" Value="PoolSettingsDlg">
                        <!--if settings are correct, allow next dialog-->
                        <![CDATA[WEBSITE_NAME <> ""]]>
                    </Publish>
                </Control>
                
                <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
                    <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
                </Control>
                
                <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
                <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
                    <Text>Please enter IIS Configuration</Text>
                </Control>
                
                <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
                <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
                    <Text>{\WixUI_Font_Title}IIS Settings</Text>
                </Control>
                
                <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
            </Dialog>

            <Dialog Id="PoolSettingsDlg" Width="370" Height="300" Title="Application Pool Settings - [ProductName]" NoMinimize="yes">
                <!-- name of the application pool -->
                <Control Id="PoolNameLabel" Type="Text" X="45" Y="53" Width="100" Height="15" TabSkip="no" Text="&Pool name:" />
                <Control Id="PoolNameEdit" Type="Edit" X="45" Y="65" Width="220" Height="18" Property="WEB_APP_POOL_NAME" Text="{80}" />
                
                <!-- domain -->
                <Control Id="DomainPoolLabel" Type="Text" X="45" Y="85" Width="100" Height="15" TabSkip="no" Text="&Domain for AppPool:" />
                <Control Id="DomainPoolEdit" Type="Edit" X="45" Y="97" Width="220" Height="18" Property="WEB_APP_POOL_IDENTITY_DOMAIN" Text="{80}" />
                
                <!-- Login -->
                <Control Id="LoginPoolLabel" Type="Text" X="45" Y="117" Width="100" Height="15" TabSkip="no" Text="&Login for AppPool:" />
                <Control Id="LoginPoolEdit" Type="Edit" X="45" Y="129" Width="220" Height="18" Property="WEB_APP_POOL_IDENTITY_USERNAME" Text="{80}" />
                
                <!-- Password -->
                <Control Id="PasswordPoolLabel" Type="Text" X="45" Y="149" Width="100" Height="15" TabSkip="no" Text="&Password for AppPool:" />
                <Control Id="PasswordPoolEdit" Type="Edit" X="45" Y="161" Width="220" Height="18" Property="WEB_APP_POOL_IDENTITY_PWD" Text="{80}" Password="yes" />
                
                <!-- Back button -->
                <Control Id="Back" Type="PushButton" X="180" Y="264" Width="56" Height="17" Text="&Back">
                    <Publish Event="NewDialog" Value="IisSetupDlg">1</Publish>
                </Control>
                <Control Id="Next" Type="PushButton" X="236" Y="264" Width="56" Height="17" Default="yes" Text="&Next">
                    <Publish Event="NewDialog" Value="CustomizeDlg">
                        <!--if settings are correct, allow next dialog-->
                        <![CDATA[WEB_APP_POOL_NAME <> "" 
                                 or WEB_APP_POOL_IDENTITY_DOMAIN <> "" 
                                 or WEB_APP_POOL_IDENTITY_USERNAME <> "" 
                                 or WEB_APP_POOL_IDENTITY_PWD <> ""]]>
                    </Publish>
                </Control>
                
                <Control Id="Cancel" Type="PushButton" X="304" Y="264" Width="56" Height="17" Cancel="yes" Text="Cancel">
                    <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
                </Control>
                
                <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
                <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
                    <Text>Please enter AppPool Configuration for IIS</Text>
                </Control>
                
                <Control Id="BottomLine" Type="Line" X="0" Y="255" Width="370" Height="0" />
                <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
                    <Text>{\WixUI_Font_Title}Application Pool Settings</Text>
                </Control>
                
                <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
            </Dialog>
        </UI>
    </Fragment>
</Wix>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文