Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
704 views
in Technique[技术] by (71.8m points)

user interface - WIX UI for multiple target directories

I need the User to be able to set multiple different target directories for my installation.

I have this directory structure:

<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="ProgramFilesFolder">
    <Directory Id="DCOMPANY" Name="MyCompany" >
      <Directory Id="DMAIN" Name="MainDir">
        <Directory Id="DPART1" Name="Part1"/>
        <Directory Id="DPART2" Name="Part2"/>
      </Directory>
    </Directory>
  </Directory>
</Directory>

I also have these Properties here

<Property Id="WIXUI_INSTALLPATH" Hidden="yes" /> 
<Property Id="VARIABLE_PATH_DPART1" Value="DPART1" />
<Property Id="VARIABLE_PATH_DPART2" Value="DPART2" />

To override the Single InstallDirDialog, I've copied the files WIXUI_InstallDir.wxs and InstallDirDlg.wxs. I duplicated InstallDirDlg.wxs and added the numbers 1 and 2 to the end of the files, prefixed all of the three with custom_ and changed their UI-Tags correspondingly:

Now, in the custom_WIXUI_InstallDir.wxs, theres this block that I changed a little so I would expect MY Properties are being set by the Actions:

  <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="custom_InstallDirDlg1">LicenseAccepted = "1"</Publish>


  <Publish Dialog="custom_InstallDirDlg1" Control="Back" Event="NewDialog"
  Value="LicenseAgreementDlg">1</Publish>
  <Publish Dialog="custom_InstallDirDlg1" Control="Next"    
  Event="SetTargetPath" Value="[VARIABLE_PATH_DPART1]" Order="1">1</Publish>
  <Publish Dialog="custom_InstallDirDlg1" Control="Next" Event="DoAction"
  Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
  <Publish Dialog="custom_InstallDirDlg1" Control="Next" Event="SpawnDialog"
  Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND
  WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
  <Publish Dialog="custom_InstallDirDlg1" Control="Next" Event="DoAction"
  Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND
  WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
  <Publish Dialog="custom_InstallDirDlg1" Control="Next" Event="NewDialog"
  Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR
  WIXUI_INSTALLDIR_VALID="1"</Publish>
  <Publish Dialog="custom_InstallDirDlg1" Control="ChangeFolder"
  Property="_BrowseProperty" Value="[VARIABLE_PATH_DPART1]"
  Order="1">1</Publish>
  <Publish Dialog="custom_InstallDirDlg1" Control="ChangeFolder"
  Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>

  <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog"
  Value="custom_InstallDirDlg1" Order="1">NOT Installed</Publish>

In custom_InstallDirDlg1.wxs I also changed this line to my path variable:

    <Control Id="Folder" Type="PathEdit" X="20" Y="100" Width="320"
  Height="18" Property="VARIABLE_PATH_DPART1" Indirect="yes" />

When I compile now, everything gets created and when I run the Installer, when I click on the "Change..." Button or the "Next..." button the Installer freezes for approximately 30 seconds and then Says "The specified Path DPART1 is unavailable."

When I look at the sources of the custom actions that are being called in all those CDATA blocks I see that those only ever care for the WIXUI_INSTALLPATH and don't accept anything given to them. So it's pretty much using indirection for that.

I've also read somewhere that this dialog can be reused to have the User enter multiple target paths but I can't figure out how.

Please help :)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Maybe I will add it as an answer so you can accept it like you say - and maybe upvote. Then just let the bounty run out - I don't think it will work since you don't have the reputation yet.

I don't have time to read this in detail at the moment, but please have a look at this answer: WiX-installer With Configurable Feature Directory (towards the middle, and also the rest of the answer if it looks relevant). These are "feature directories" that can be linked to an actual directory property as described in the link.

The sample above uses the WiX Mondo dialog set. I describe setting up a minimal WiX compile with the Mondo dialog set here. Essentially a "Hello WiX" project, but you have this down already. Just adding it in case someone else may find it helpful.


UPDATE: My brief testing seems to show that such feature directories are persisted by the system for most installation modes, but not for major upgrades. To read the previous settings for these custom folders, you need either an AppSearch or a custom action I'd say, and you should make your setup persist the directory properties in the registry.

Some pointers

These are just some suggestions from quick testing. Please, as always, test thoroughly yourself. There is a lot of what I call "conspiratory complexity" in Windows Installer - problems surface unexpectedly - for example when you try to deliver an upgrade.

Persisting your properties in the registry during install (your feature directory properties):

<!--Put this inside a component-->
<RegistryKey Root="HKLM" Key="SoftwareMyCompanyMyApp" ForceCreateOnInstall="yes">
  <RegistryValue Type="string" Name="MYCUSTOMDIR" Value="[MYCUSTOMDIR]" KeyPath="yes"/>
</RegistryKey>

<!--Put this inside a component-->
<RegistryKey Root="HKLM" Key="SoftwareMyCompanyMyApp" ForceCreateOnInstall="yes">
  <RegistryValue Type="string" Name="MYCUSTOMDIRTWO" Value="[MYCUSTOMDIRTWO]" KeyPath="yes"/>
</RegistryKey>

And important!: this will write to HKLMSOFTWAREWOW6432NodeMyCompanyMyApp - the 32-bit section of the registry on a 64-bit OS. You may need to write and read from the 64-bit section. If so, just add the Win64="yes" attribute to the Components and the RegistrySearch elements.

A link: http://robmensching.com/blog/posts/2010/5/2/the-wix-toolsets-remember-property-pattern/

Next read them back with a registry search:

<Property Id="MYCUSTOMDIR">
  <RegistrySearch Id='MYCUSTOMDIR' Root='HKLM' Key='SoftwareMyCompanyMyApp' Name='MYCUSTOMDIR' Type='raw' />
</Property>

<Property Id="MYCUSTOMDIRTWO">
  <RegistrySearch Id='MYCUSTOMDIRTWO' Root='HKLM' Key='SoftwareMyCompanyMyApp' Name='MYCUSTOMDIRTWO' Type='raw' />
</Property>    

In an ideal world this should suffice for your purpose. I did not have time to test what happens when these properties are set at the command line for an upgrade (which could happen).

To create a major upgrade for testing you can basically just bump up one of the first three digits of your version number and compile a new MSI (rename the old MSI in the output folder to preserve it) - and generate a new product GUID (unless you have it set to auto-generate, in which case the version bump is enough). An MSI version number should incidentally have only 3 digits to be compliant to MSI standards.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...