1

Glytzhkof: This question relates to a common problem for new MSI users, the belief that one needs a custom action for something MSI supports natively by a feature they are unaware of.

In this case the IniFile table in MSI that allows merging, rollback and updating of shared Ini files on the system. All updates to Ini files should be performed via this table since you get a lot of features for free and you will be in line with all MSI guidelines.

Always avoid custom actions if there is a way to achive the same effect by native features.


I have a c# customaction on my WIX msi.

When msi start require admin account and all works fine excepted for my customaction, it can't write inside programdata folder.

I have set impersonate="no" according to wix reference:

This attribute specifies whether the Windows Installer, which executes as LocalSystem, should impersonate the user context of the installing user when executing this custom action. Typically the value should be 'yes', except when the custom action needs elevated privileges to apply changes to the machine.

But does not works.

This is my custom action configuration:

<CustomAction 
Id="MyCustomActionCA" 
BinaryKey="mycustomactionDLL" 
DllEntry="MyCustomAction" 
Execute="immediate" Return="check" Impersonate="no" />

<InstallUISequence>
  <Custom Action="MyCustomActionCA" After="CustomDialog1">NOT Installed</Custom>
</InstallUISequence>

MyCustomAction is launched after CustomDialog1 is closed, and this is OK, my code run fine but in MyCustomAction i have a line of code like this:

File.WriteAllText(mypath, mycontent);

mypath refers to ProgramData folder and throw an exception becouse user can't write inside it.

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
workat
  • 63
  • 2
  • 10
  • You need to give more information. What specific error(s) are you getting? Have you validated your custom action code to make sure the problem is not there as opposed to your Wix configuration? Post code and/or the appropriate sections of your .wxs file so we can actually help you. – Daniel Simpkins Feb 27 '14 at 16:48
  • The error is that user can't write on programdata folder at row File.WriteAllText(myini, myiniContent). I'm debugging my customaction using System.Diagnostics.Debugger.Launch() on top of my method. – workat Feb 27 '14 at 17:01
  • So you've verified that your CA code is definitely being called? Once again, please edit your post to include the appropriate code/config so we can be of more help to you. – Daniel Simpkins Feb 27 '14 at 17:15
  • Yes, it is. Ok i add more infos, thank you. – workat Feb 27 '14 at 17:32
  • Maybe the problem is that mycustomaction must be "deferred"? – workat Feb 27 '14 at 17:49
  • @workat: I have updated your question with a hint to other users with the same problem that they should avoid custom actions whenever possible - many users face this problem for similar issues. Please upvote supporting answers and thanks for setting the accepted answer tag. This makes it easier for other users to understand the discussion later. Welcome to the community, glad we could help. – Stein Åsmul Feb 28 '14 at 09:36
  • Similar issue: [How to check if ini file exists with Wix Toolset](http://stackoverflow.com/questions/25023457/how-to-check-if-ini-file-exists-with-wix-toolset) – Stein Åsmul Aug 03 '14 at 12:04

3 Answers3

2

There seems to be two problems here as far as I can tell:

  1. The first is that the CA needs to be deferred if it's impersonate="no", and it's not clear that you've done that.

  2. The second problem is that ProgramData is a user profile notion. For example it's in C:\Users\ on my system. If you run with impersonate="no" you're running with the system account, so it's going to try to write to some weird (non existent) C:\Users\System folder.

You might have a design issue here in that you say you need elevated user privileges to write to that folder, but you can't elevate unless you are deferred with system account privilege. You may need to describe the exact problem you're trying to solve to see if there is another way.

PhilDW
  • 20,260
  • 1
  • 18
  • 28
  • Agree. Problem 1 is a technical detail, problem 2 is a design flaw. I would rather redesign the application than work to fix the technical deployment detail. See my answer below - a bit rushed, but you get the idea. – Stein Åsmul Feb 27 '14 at 18:00
  • I need to write mysql ini file in "C:\ProgramData\MySQL\data". – workat Feb 27 '14 at 18:29
  • You use the IniFile table of an MSI file to achieve this. Complete with rollback support and merging into existing values. – Stein Åsmul Feb 27 '14 at 18:34
0

Best option: redesign your application to write this ini file as a per-user file (any user can write to his own user profile) on application launch from internal defaults in the exe itself. Solves the deployment problem too.

As to what is happening in your deployment context: Windows installer runs only part of the installation as LocalSystem - what is referred to as the installation transaction. The rest of the setup is run as the user who launches the MSI - and this includes the entire user interface sequence which is where you have added your custom action.

Try setting the action deferred, schedule it prior to InstallFinalize and set impersonation to no.

With regards to per-user data management, see this post on a slightly different topic for a way to handle per-user data that needs management between deployed versions of the application: http://forum.installsite.net/index.php?showtopic=21552

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • I need to write mysql ini file in "C:\ProgramData\MySQL\data". – workat Feb 27 '14 at 18:29
  • In this case you can not write the ini file per user, and the better option would be to use MSI's IniFile feature as described in my other answer. – Stein Åsmul Feb 28 '14 at 09:23
0

Check this thread for information on how to use MSI's built-in support for writing to INI files: Wix modify an existing ini file

Some further reference: http://wixtoolset.org/documentation/manual/v3/xsd/wix/inifile.html

Community
  • 1
  • 1
Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • If you would overwrite a shared database ini file you risk wiping other database settings. The same happens if you try to overwrite the whole file. IniFile takes care of all merging, but make sure you test well. In particular you must test uninstall. – Stein Åsmul Feb 28 '14 at 09:41