代码之家  ›  专栏  ›  技术社区  ›  Marzena

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

  •  1
  • Marzena  · 技术社区  · 14 年前

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

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

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

    我一直在调查为什么每当新用户帐户尝试使用它时,安装程序会再次启动。这是因为shortcut元素(shortcut被放置到'ProgramMenuFolder'。有一个卸载操作请求,AFAIK需要父组件,而此组件需要一个KeyPath,它必须是HKCU.下的注册表项。当我从WXS中删除所有程序菜单快捷方式内容时,在切换用户上下文后,MSI不会再次启动。

    结果是我有一个安装程序,它能够根据输入参数配置到数据库的连接。但以后任何试图从第二个用户帐户使用该应用程序的尝试都会将此配置发送到toilette。在生产环境中,这意味着每次新用户尝试使用应用程序时,管理员都必须来手动更改连接字符串,这当然是不可接受的行为。

    这是我的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) 我已经分离了和to独立的组件。
    2) 我已尝试在这些组件下添加未安装的。
    3) 我已尝试在安装期间将注册表值写入HKLM。我已为该注册表值添加了RegistrySearch和属性,然后将该值用作条件(实际上,只是替换以前的“未安装”)

    谢谢你的建议

    马雷克

    1 回复  |  直到 14 年前
        1
  •  0
  •   heavyd    14 年前

    将注册表项根放到 HKMU ( See reference ). 根据ALLUSERS属性的值,这将正确地在HKLM或HKCU中创建注册表项的根目录。