Reputation: 29
I have a Wix project which should install my c# Application. File Copy and Firewall exceptions are already working. Now I want to modify json config files with a custom action. I want to read all json files, change some values and write them back to program files. Here is my CA definition:
<CustomAction Id="PrepareConfigurationFilesCustomAction" BinaryKey="InstallerCA" DllEntry="PrepareConfigurationFilesCustomAction" Execute="immediate" Impersonate="no" Return="check" />
<CustomAction Id="CreateConfigurationFiles" BinaryKey="InstallerCA" DllEntry="CreateConfigurationFiles" Execute="deferred" Impersonate="no" Return="check" />
<Custom Action="PrepareConfigurationFilesCustomAction" Before="CreateConfigurationFiles">NOT Installed AND NOT REMOVE</Custom>
<Custom Action="CreateConfigurationFiles" Before="InstallFinalize">NOT Installed AND NOT REMOVE</Custom>
If I open the .msi wirth Orca the order of the Actios seems to be right.
InstallFiles 4000
PrepareConfigurationFilesCustomAction NOT Installed AND NOT REMOVE 6598
CreateConfigurationFiles NOT Installed AND NOT REMOVE 6599
But when I run the .msi I get the exception
Excetion TrownSystem.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Program Files\Vendor\Product\etc\Configurations'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileSystemEnumerableIterator`1.CommonInit()
at System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
at System.IO.Directory.GetFiles(String path)
at Vendor.Application.Product.Setup.Actions.CustomActionData.ConfigurationFilesCustomActionData.CreateSessionCustomActionData(Session session) in C:\work\\Projects\Installation\Packages\Product.Workstation\Setup.Actions\CustomActionData\ConfigurationFilesCustomActionData.cs:line 99
When I attach the debugger I can see in the code, and in the file system, that the files are not present.
If I change the first Ca (PrepareConfigurationFilesCustomAction) to Execute="deferred", the files are written but I can't access session values...
Any Ideas or solutions for me?
Thanks!
Upvotes: 2
Views: 1205
Reputation: 42246
Solution?: The best solution is to install the JSON files to a read-only location and then use your application to copy them to the user profile and update them according to what you need. This is not always possible - such as when there is no application binary to lauch.
Access Denied: You can not write to locations under program files as a normal user. Here is a piece on that issue: System.UnauthorizedAccessException while running .exe under program files
Technical: The reason for the behavior you see is that the InstallExecuteSequence is processed twice. First in "immediate mode" which runs immediate mode custom actions and builds a transaction script for execution. When you reach InstallFinalize the sequence runs again from InstallInitialize and at this point the system is updated with file installation, registry changes, etc... Custom actions in this mode are deferred. They can not directly access properties. The property values have to be "sent" to them via a mecanism called CustomActionData. Quite clunky. Not needed if you use the application to do the work?
The CustomActionData concept has been so well explained before by others, that I just link to the information you can access elsewhere:
Upvotes: 1