Create a .config folder in the user folder

2019-01-20 17:40发布

问题:

When installing my program, I'd like to create a .config folder into the user's folder. For example :

C:\Users\MyUser\.config

This is what I tried but it doesn't work :

<Directory Id="USERPROFILEFOLDER" Name="[%USERPROFILE]">
 <Directory Id="ConfigUserFolder" Name=".config">
   <Directory Id="UserConfig" Name="Config" >
     <Component Id="ConfigFolder" Guid="GUID">
       <RemoveFolder Id='RemoveConfig' Directory='UserConfig' On='uninstall' />
       <RemoveFolder Id='RemoveConfigUserFolder' Directory='ConfigUserFolder' On='uninstall' />
       <RegistryValue Root='HKCU' Key='Software\MySoftware' Type='string' Value='' KeyPath='yes' />
     </Component>
  </Directory>
 </Directory>
</Directory>

<Property Id="USERPROFILEFOLDER" />

Any idea what I'm missing/doing wrong ?

回答1:

Is this application a regular executable? Or some sort of Web-App or Plug-In? In other words: does it have its own launch sequence?

I sound like a broken record with this advice, but: folders and files in the user profile folder (and HKCU settings) are better created on application launch than during installation.

Just leave this construct out of your setup and make your application smarter and capable of creating this folder on launch for every user - and to be able to copy any data files into the folder from their template locations in your main read-only %ProgramFiles% installation folder.

I previously wrote a whole rant about the problem of user-specific files and settings deployment: Create folder and file on Current user profile, from Admin Profile. I describe options such as MSI self-repair and Active Setup - and list some details on why they are unreliable (and suggest some potentially better approaches).

I'd say: kill complexity and error sources and stay in familiar territory whenever you can. Avoid advanced setup features due to their hard-to-debug nature and unusual and unfamiliar complexity. And what is relevant for your question: avoid per-user deployment done via the installer.


The above is basically all there is to say, but fleshing it out here are the main reasons to use your application launch sequence instead of your setup for per-user stuff:

  1. Predictability & Reliability: this approach reliably creates the folder for any user who launches your application - without relying on Windows Installer to put per-user files and folders in place.

    • Windows Installer self-repair can be prevented from running by policy on certain machines (for example terminal servers) and your folder will then never be created at all for users who did not run the original install.

    • If you also want to install user-specific files (not just a folder), then MSI deployment of user-specified files and settings is unreliable at best, and prone to accidental file and settings overwrite (REINSTALLMODE = amus - force overwrite) and user settings and data loss from unexpected uninstall of settings files intended to be permanent, but not marked as such (by accident). A lot of problems can result from this.

    • Very technical, but MSI's component GUID concept sort of breaks down conceptually when used to reference count files potentially installed multiple times.

  2. Implementation & Debugging: the application launch sequence is "just regular code" whilst Windows Installer and deployment may be unfamiliar territory for many developers. You hence avoid the unexpected problems that results from the complexity of deployment (a blurb on deployment complexity written in the context of the history of WiX).

    • This is especially true if you move into custom actions with their complex sequencing, impersonation and conditioning aspects featuring very "conspiratory complexity" (problems that are not immediately obvious, but that will surface when least convenient).

    • Your application launch sequence has predictable user context, full access to the user's environment and interactivity is available with error- and warning messages. Problems can be debugged easily by simply re-launching the application as opposed to compiling and running a setup (and attaching the debugger in the case of custom actions - well beyond the scope of your question).

    • You avoid an installer's "one shot" nature and difficulty of debugging due to the hard-to-reproduce nature of deployment errors overall (no access to the problem system, generally missing logging, difficulty of cleaning up prior mistakes). For the launch sequence you just have users re-launch the application and report the error seen - or check the event log or whatever other logging is available.

    • In my experience QA personnel will generally have more experience testing application launch sequences than deployment features.

    • And I might be making application debugging sound "too rosy" for what it is in the real world, but trust me it is indeed easier than deployment debugging.

  3. Settings Management: your application's launch sequence can (much more) reliably perform any form of "maintenance" on your data and settings files that is impossible to accomplish reliably from a setup.

    • These are often "resource files" and not data files - in other words templates and settings used during program operation - not just content created by the user (which sometimes also requires "cleaning" - but you can do that on file open instead of application launch).

    • You want to fix something in files duplicated for each user

      • Leaking meta-files pictures
      • Data file errors and glitches
      • Just bugs caused by per-user settings really...
    • Enforce new mandatory settings
      • Move files to a new location or back them up
      • Remove settings that are no longer valid (or erroneously unencrypted)
      • Delete binary streams from HKCU that make your application crash
    • A description of how a setup can "flag" the system to activate an application's "launch sequence maintenance functions": http://forum.installsite.net/index.php?showtopic=21552

A setup should essentially do anything that requires elevated rights, most other things - do it in your application - and certain elevated things can actually be done over time running as a service - which features no sequencing, conditioning or impersonation variables that plague deployment.



回答2:

To do this with WiX you need to use the CreateFolder element under the parent component. It's much the same question as this:

how to create folder in Wix?

As a better practice in my opinion, you should use the standard Windows Installer folder properties as locations. The full list is here:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa370905(v=vs.85).aspx#system_folder_properties

for example ProgramFiles64Folder, AppDataFolder (which might be the best location for your directory), CommonAppDataFolder and so on.