WiX3 - util:当新用户首次使用每台计算机安装时,XmlFile元素再次执行

时间:2010-11-06 17:21:48

标签: wix wix3 wix-extension

我创建了WiX安装程序项目,用于在客户机器上部署我的.net winform应用程序。该应用程序仅扫描文档并将图像保存到服务器上的数据库。扫描仪是非常具体的,只有一个在公司,但有约。四个可以偶尔使用它的用户=>应用程序将安装在专用于扫描的单个工作站上 - 大部分时间它将是免费的,任何这些用户都可以来,扫描文档并继续他的工作。

=>我正在进行每台机器安装:ALLUSERS硬编码为1。

由于生产中的数据库服务器不受我控制,而且我真的不知道数据库将存储在何处,因此我无法将正确的ConnectionStrings.config文件打包到MSI存档。而不是它,安装程序根据用户在安装期间提供的参数值修改此配置。为了更新连接字符串,我使用util:XmlFile元素。 connectionstrings.config文件与app二进制文件一起存储在安装目录中。

在我使用每台机器安装模拟两个用户之前,一切似乎都运行良好。我已经在我自己的帐户下执行了我的wix安装项目,XML配置文件已经正确更新,然后我启动了应用程序并测试了连接字符串是否正常。一切都很好。

然后我切换到另一个用户帐户。该快捷方式已经存在于程序菜单中 - 就像我预期的那样,因为安装是按机器进行的。所以我点击了快捷方式,然后(意外地对我来说)进度条窗口“等到产品XY的配置完成。”出现了。 (请注意,我的机器语言环境不是英语,英语语言环境工作站上的消息可能略有不同)。几秒钟后,窗口消失,我的应用程序启动。遗憾的是它无法连接到数据库,因为connectionStrings.config文件已被重写 - 连接字符串已使用默认(=不正确)属性值进行更新。

我一直在研究为什么每当新用户帐户尝试使用它时设置再次启动。这是因为快捷方式元素(快捷方式被放置到'ProgramMenuFolder'。有一个卸载操作请求,AFAIK需要父组件,而此组件需要一个KeyPath,它必须是HKCU下的注册表项。)。当我从WXS中删除所有Program-Menu-Shortcut-stuff时,在切换用户上下文后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>

<?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)我试过在这些组件下添加一个NOT NOT安装 3)我在安装过程中尝试将注册表值写入HKLM。我已为该注册表值添加了RegistrySearch和Property,然后将该值用作条件(实际上只是替换了之前的“NOT Installed”)

任何人都可以帮忙吗?我做错了什么?

感谢您的建议

马立克

1 个答案:

答案 0 :(得分:0)

将您的注册表项置于HKMUSee reference)下。这将根据ALLUSERS属性的值正确地在HKLM或HKCU中根据您的注册表项。