Установка веб-приложения с начальными параметрами IIS; используя WiX, необходимо обновить файлы, не изменяя параметры IIS

У меня есть проект установки WiX, который включает настройки IIS для виртуального каталога и параметров приложения с пулом приложений. После первоначальной установки клиент изменит идентификатор пула приложений из сетевой службы по умолчанию, установленной в wxs.

Как создать установщик обновлений, который может обновлять веб-файлы, но не изменять параметры IIS, идентификатор пула приложений обратно в сетевую службу?

ComponentGroupRef Id= "WebPublishCmp" - начальное тепло вывод веб-файлов для публикации.

Я попытался создать небольшое обновление с помощью Факел и Пиро, но у меня возникли проблемы с Факелом 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

1 ответов


заранее прошу прощения за длинный ответ:

Я рекомендую сохранить ваш сайт и контент в двух отдельных функциях, а затем предоставить им возможность предоставления любых переменных, необходимых для установки через UI или параметры командной строки. Если вы используете шаблон"запомнить свойство", затем вы можете вспомнить переменные, используемые при изменении или обновлении установки (прочитайте все последние комментарии, есть немного более простой способ сделать он.)

это позволяет человеку, устанавливающему продукт, настроить все с заданными переменными или настроить веб-сайт IIS самостоятельно и установить только содержимое веб-сайта.

это jives с MajorUpgrades. В настоящее время я не вижу информации об обновлении в предоставленном вами коде, поэтому вам следует заглянуть в MajorUpgrades против патчей (основные обновления намного проще)

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

помните, переменные доступны $(ВАР.имя) используются в MSI время компиляции, тогда как открытые переменные, доступные через скобки [MY_VARIABLE], используются во время установки. Открытые переменные могут быть предоставлены через интерфейс MSI или предоставлены msiexec через командную строку (я использую это для автоматической установки и/или указания файла журнала)

вот краткое изложение примеров, приведенных ниже:

  • конфигурации.wxi по - этот файл реализует свойства "запомнил"
  • продукта.wxs - в основном как и ваш, но также включает в себя MajorUpgrades, отдельные функции для веб-сайта и контента, а также включение UiFlow
  • IISConfiguration.wxs - фрагмент, содержащий веб-сайт IIS, AppPool и пользователь AppPool с использованием переменных, предоставленных во время установки
  • UIFlow.wxs - определение потока пользовательского интерфейса для использования, он использует плагин Wixui FeatureTree, вам может потребоваться что-то еще для вашего UI
  • UIDialogs.wxs - здесь переменные, используемые в установке, подвергаются воздействию UI

конфигурации.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="&amp;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="&amp;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="&amp;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="&amp;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="&amp;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="&amp;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="&amp;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="&amp;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="&amp;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>