WiX3 - util: элемент XmlFile снова запускается, когда новый пользователь впервые использует установку для каждой машины

Я создал проект установщика WiX для развертывания моего приложения.net winform на клиентском компьютере. Приложение только сканирует документы и сохраняет изображения в базу данных на сервере. Сканер достаточно специфичен и только один в компании, но есть ок. четыре пользователя, которые могут время от времени его использовать =>, приложение будет установлено только на одной рабочей станции, предназначенной только для сканирования - большую часть времени оно будет бесплатным, и любой из этих пользователей может прийти, отсканировать документы и продолжить работу.

=> Я делаю установку для каждой машины: ALLUSERS жестко запрограммирован на 1.

Поскольку серверы баз данных в производстве не контролируются мной, и я не знаю, где будет храниться база данных, я не могу упаковать правильный файл ConnectionStrings.config в архив MSI. Вместо этого программа установки изменяет эту конфигурацию в соответствии со значениями параметров, предоставленными пользователем во время установки. Для обновления строк подключения я использую элемент util:XmlFile. Файл connectionstrings.config хранится в каталоге установки вместе с двоичными файлами приложения.

Казалось, все работает нормально, пока я не смоделировал двух пользователей, использующих эту установку для каждой машины. Я выполнил мой проект установки wix под своей учетной записью, файл конфигурации XML был правильно обновлен, а затем я запустил приложение и проверил, что строки подключения в порядке. Все было отлично.

Затем я переключился на другую учетную запись пользователя. Ярлык уже присутствовал в меню программы - так же, как я и ожидал, так как установка выполняется для каждой машины. Поэтому я нажал на ярлык, а затем (неожиданно для меня) окно индикатора выполнения "Дождаться окончания настройки продукта XY". появился. (Обратите внимание, что мой машинный языковой стандарт не является английским, сообщение, вероятно, будет немного отличаться на рабочей станции английского языкового стандарта). Через несколько секунд окно исчезло, и мое приложение запустилось. К сожалению, он не смог подключиться к базе данных, так как файл connectionStrings.config был переписан - строки подключения были обновлены с использованием значений свойств по умолчанию (= неверно).

Я изучал, почему установка запускается снова всякий раз, когда новая учетная запись пользователя пытается использовать ее. Это из-за элемента ярлыка (Ярлык помещается в "ProgramMenuFolder". Существует запрос на действие удаления, для которого AFAIK требуется родительский компонент, а этому компоненту нужен KeyPath, который должен быть ключом реестра в HKCU.). Когда я удаляю все программные меню-ярлыки из WXS, MSI не запускается снова после переключения пользовательского контекста.

В результате у меня есть программа установки, которая может настроить соединение с базой данных в соответствии с входными параметрами. Но любая более поздняя попытка использовать приложение из второй учетной записи пользователя просто отправляет эту конфигурацию в туалет. В производственной среде это означает, что администратор должен приходить и вручную изменять строки подключения каждый раз, когда новый пользователь пытается использовать приложение, что, конечно, является недопустимым поведением.

Это упрощенная версия моего источника WiX:

    <?define ProductID = "11111111-1111-1111-1111-111111111111" ?>
    <?define ProductName = "MyProduct" ?>
    <?define ProductLocalName = "MyLocalLanguageProductName" ?>

    <!-- application's root registry path, where it stores its settings -->
    <?define ApplicationRootRegistryKey = "Software\MyCompany\MyProject\MyBuildConfiguration" ?>

    <Product Id="$(var.ProductID)" UpgradeCode="{11111111-1111-1111-1111-111111111112}"
             Name="$(var.ProductName)" Version="1.10.1103" 
             Manufacturer="MyCompany"Language="1029" Codepage="1250">

    <Package Id="*" InstallerVersion="200" Compressed="yes"
             Description="$(var.ProductName) Installer" Languages="1029" 
             SummaryCodepage="1250" />

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

        <!-- always install the app for all users -->
        <Property Id="ALLUSERS" Value="1"/>

        <!-- initialize properties used for adjusting connection strings.
             The user will provide valid property values through command-line -->
        <Property Id="DB_SERVER_NAME" Value="please-specify-db-server-name"/>
        <Property Id="DB_NAME" Value="please-specify-db-name"/>

        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="CompanyProgramFilesFolder" Name="CompanyName" >
                    <Directory Id="INSTALLDIR" Name="ProjectName">
                        <Directory Id="InstallDirApp" Name="Bin" />
                    </Directory>
                </Directory>
            </Directory>
            <Directory Id="ProgramMenuFolder" Name="Programs">
                <Directory Id="AppProgramMenuDir" Name="$(var.ProductLocalName)">
                    <Component Id="ProgramMenuDir" Guid="*">
                        <RemoveFolder Id='AppProgramMenuDir' On='uninstall'/>
                        <RegistryValue Root='HKCU' Key='$(var.ApplicationRootRegistryKey)' Type='string' Value='' KeyPath='yes' />
                    </Component>
                </Directory>
            </Directory>
        </Directory>

        <DirectoryRef Id="InstallDirApp">
            <Component Id="Executable" Guid="*">
                <File KeyPath="yes" Source="$(var.MyProject.TargetPath)">
                    <Shortcut Id="ProgramMenuShortcut" Name="$(var.ProductLocalName)"
                              Directory="AppProgramMenuDir" Advertise="yes"
                              WorkingDirectory="InstallDirApp" Icon="AppIcon.ico" IconIndex="0"/>
                </File>
            </Component>

            <!-- ConnectionStrings config file deployment and settings adjustment -->
            <Component Id="ConnectionStrings.config" Guid="*">
                <File KeyPath="yes" Source="$(var.Csob.ChequesScanning.SmartShell.TargetDir)ConnectionStrings.config" />
            <!--</Component>

            <Component Id="xml01" Guid="*">-->
                <!--<Condition><![CDATA[NOT Installed]]></Condition>-->

                <!-- this sets the connection strings according to provided parameters -->
                <util:XmlFile Id="SetConnectionString" Action="bulkSetValue"
                              File="[#ConnectionStrings.config]"
                              ElementPath="//add" Name="connectionString"
                              Value="Data Source=[DB_SERVER_NAME];Initial Catalog=[DB_NAME];Integrated Security=True;Pooling=True"
                              Permanent="yes" />
            </Component>
        </DirectoryRef>

        <Icon Id="AppIcon.ico" SourceFile="$(var.MyProject.ProjectDir)Resources\AppIcon.ico" />


        <Feature Id="ProductFeature" Title="MyProjectName" Level="1">
            <ComponentRef Id="Executable" />
            <ComponentRef Id="ConnectionStrings.config"/>
            <ComponentRef Id="ProgramMenuDir" />
        </Feature>

    </Product>
</Wix>

Я попытался эти шаги, чтобы решить проблему, но ничто не помогло мне:
1) Я разделил и независимые компоненты.
2) Я пытался добавить НЕ установленный под этими компонентами.
3) Я попытался записать значение реестра в HKLM во время установки. Я добавил RegistrySearch и Property для этого значения реестра, а затем использовал это значение в качестве условия (на самом деле это просто замена "NOT Installed" из предыдущего)

Может кто-нибудь помочь с этим? Что я делаю неправильно?

Спасибо за совет

Marek

1 ответ

Решение

Корень вашего реестра в разделе HKMU ( См. Ссылку). Это приведет к правильному корневому разделу реестра в HKLM или HKCU, в зависимости от значения свойства ALLUSERS.

Другие вопросы по тегам