I have an WiX installer configured like this:
<Property Id="MY_PROPERTY">
...
<Registry Name="MyValue" Type="multiString" Value="[MY_PROPERTY]" />
Now I want to pass this property value at the command line as a list:
MsiExec.exe /i MyInstaller.msi /qb MY_PROPERTY="One[~]Two[~]Three"
However, the installer does not split the values into a list and the literal value is written instead.
If I hard code the element it works properly:
<Registry Name="MyValue" Type="multiString" Value="One[~]Two[~]Three" />
Does anyone know how to specify a list of values at the command-line for a multiString registry value? Thanks in advance
Better late than never!
This can be achieved using a Custom Action.
Follow this MS document carefully: https://learn.microsoft.com/en-us/windows/win32/msi/registry-table
In your custom action, insert the registry value into MSI table from your property as follows,
Set db = Session.Database
set oView = db.OpenView("INSERT INTO `Registry` (`Registry`,`Root`,`Key`,`Name`,`Value`,`Component_`) VALUES ('reg_MY_PROPERTY', -1,'Software\Company\Product','MyValue','" & _
Session.Property("MY_PROPERTY") & "','CM_CP_BlahBlah') TEMPORARY")
oView.Execute
oView.Close
CM_CP_BlahBlah is your WIX component Registry values are attached to.
Please note "custom action must come before the RemoveRegistryValues and WriteRegistryValues actions in the action sequence"
<InstallExecuteSequence>
<Custom Action="SetMyPropertyCustomAction" Before="RemoveRegistryValues">NOT REMOVE</Custom>
</InstallExecuteSequence>
REG_MULTI_SZ
A sequence of null-terminated strings, terminated by an empty string (\0).
The following is an example:
String1\0String2\0String3\0LastString\0\0
The first \0 terminates the first string, the second to the last \0 terminates the last string, and the final \0 terminates the sequence. Note that the final terminator must be factored into the length of the string.
So as per this LINK you should be doing this:
MY_PROPERTY="One\0Two\0Three\0"
For MULTISTRINGValues check this element: MULTISTRINGVALUE
Related
using Wix 3.11, project built using msbuild 14.0.25420.1
I've come across a situation where a string I define in a proprocessor variable is having the enclosing quotes included within the variable value.
I would appreciate if someone could tell me:
why this behaviour occurs ( am I doing something wrong ? )
how I would quote a string value with spaces
The project has a main .wxs file, plus a number of .wxi Include files.
In the main Product.wxs within the Wix element:
<?define registry_key_path="SOFTWARE\MySoftwareGroup\MySoftware" ?>
Then in an include file Component.wxi within a Component element:
<RegistryValue
Root="HKLM"
Key="$(var.registry_key_path)"
Name="InstallFolder"
Value="[INSTALLDIR]"
Type="string" />
The install fails with error:
Error 1406. Could not write value InstallFolder to key
\"SOFTWARE\MySoftwareGroup\MySoftware"
You can see that the key contains the quotes. It should read:
\SOFTWARE\MySoftwareGroup\MySoftware
If I remove the quotes from the define:
<?define registry_key_path=SOFTWARE\MySoftwareGroup\MySoftware ?>
the installer correctly parses the variable and finds the right registry key and writes to it.
Why are the quotes being included?
How would I quote the string value if it contained a space?
Works for me with WiX v3.11.1.2318. Open your .msi in Orca to inspect the Registry table and see if the quotes exist there. If you can reproduce it in a small example .wixproj, please open a bug.
I have a shortcut definition like this:
<Component Id="PowershellShortcut" Guid="{12345678-1234-1234-1234-1234567890AB}">
<Condition>POWERSHELL_INSTALL_LOCATION</Condition>
<Shortcut Id="PowershellStartMenuShortcut"
Name="Powershell Environment"
Description="Powershell Environment"
Target="[POWERSHELL_INSTALL_LOCATION]"
Arguments="-PSConsoleFile "[#Powershell.Environment]"" />
</Component>
I want to pass the path to the resultant .lnk file into a CustomAction. I've tried various things, e.g.:
<CustomAction Id="SetCustomActionData_ElevatePowershellShortcut" Return="check"
Property="ElevatePowershellShortcut"
Value="<WHAT-GOES-HERE?>" />
Where I've tried the following in place of <WHAT-GOES-HERE?>:
[$PowershellShortcut] -- This almost gets me there. I get the folder the .lnk file is in, but not the file itself
[$PowershellStartMenuShortcut] -- Empty string
[#PowershellStartMenuShortcut] -- Empty string. This works on <File> elements...
An alternative would be to keep using the [$PowershellShortcut] value and also pass in the name of the .lnk file. Which would be the <Shortcut>'s Name attribute. I'm not sure how to get at it, either...
The reason I want to do this is that we've already had a case where the Name of the shortcut was changed, and everything stopped working, so we don't want to have to update the name/path of the shortcut in more than one place.
Just after I wrote this question, I came up with a solution. It's not quite what I asked for, but it solved my problem, so I'm posting it. If somebody can figure out how to do what I actually asked for, I will mark their answer as the correct one, although my solution is fairly clean and straight forward.
I ended up defining the following variable in my WiX define file:
<?define PowershellShortcutName="Powershell Environment" ?>
and then I set the <Shortcut Name="$(var.PowershellShortcutName)"> and the CustomAction to:
<CustomAction Id="SetCustomActionData_ElevatePowershellShortcut" Return="check"
Property="ElevatePowershellShortcut"
Value="[$PowershellShortcut]$(var.PowershellShortcutName).lnk" />
Everything works like it should now.
I'm trying to setup a custom action to initialize my SQLite database using the sqlite3.exe command line tool. In a command prompt I type the following: c:\sqlite3.exe database.db < sqlscript.sql
My Wix custom action falls apart in the ExeCommand attribute because I cannot seem to escape out the <.
<CustomAction Id="InitializeDatabase" FileKey="SQLiteEXE" ExeCommand="database.db < sqlscript.sql" Execute.../>
I've tried "<" as well.
I know I could just install an empty initiailzed database but I'm curious how to redirect inputs.
Thanks.
So, what exactly is happening when you say it falls apart? Does it compile?
Just so that we're on the same page, are you ending you XML entity with the semi-colon. You probably are, but it didn't come through in your code sample. Are you using:
<
If that doesn't work, you could try putting the command into a property and using CDATA tags, such as:
<Property Id="MyCommand">
<![CDATA[
database.db < sqlscript.sql
]]>
</Property>
and using that in the ExeCommand attribute:
ExeCommand="[MyCommand]"
That might work.
If you really have to call an EXE, I reccomend using the WiX QuietExec Custom Action pattern. Worse case you could install a .BAT file then use the cmd /c foo.bat command to call it. Then you wouldn't have to escape the <.
Otherwise I would search for an alternative to the EXE. I try to stick with data driven custom actions that run in process ( say C++ or C#/DTF ).
Quiet Execution Custom Action
I have a custom action inside an MSI installer that makes some changes to some configuration file. my requirement is to run the installation in silent mode so I am using msiexec.
Here is the command:
msiexec /i myInstaller.msi /l* out.txt myContextParameter=value1
myContextParameter is never passed to the custom action so when I do
context.Parameters["myContextParameter"] I get a null value.
When I run my MSI in UI mode the parameter is passed correctly. I also made sure the name of the property is correctly set in the CustomActionData.
I've been beating my head against the wall on this one, so here's what I found out:
You have to set your parameters on the commandline, as well as on the "CustomActionData" property on each of your Custom Actions (whatever you have under Install, Commit, etc)
Your commandline will look something like this:
msiexec /i myInstaller.msi MYFIRSTPARAM=VALUE1 MYSECONDPARAM=VALUE2
Then, your CustomActionData should look like this:
/myfirstparam=[MYFIRSTPARAM] /mysecondparam=[MYSECONDPARAM]
Now, here's a bunch of special cases:
It looks like #Klaus is right, you need to use ALLCAPS in your parameter names.
if your values contain spaces, you'll need quotes around them in both the commandline and your CustomActionData properties, as in:
msiexec /i myInstaller.msi MYFIRSTPARAM="VALUE1" MYSECONDPARAM="VALUE2"
/myfirstparam="[MYFIRSTPARAM]" /mysecondparam="[MYSECONDPARAM]"
if your values end with a slash, like most file paths do, you'll have a weird problem: when the msiexec builds your customactiondata, it'll create this string:
/myfirstparam="C:\myfile\" /mysecondparam="C:\myfile\"
it doesn't matter if you use quotes on the commandline or not, if that slash is the last character on your value, it will effectively be read as an escape character, and will escape the quote in your customactiondata property. This causes havoc. The solution is to either 1) add a space between your parameter and the last quote, and then remember to trim() it in your code somewhere, or 2) add and extra slash between your parameter and quote, in order to escape the escape character. See both methods below:
/myfirstparam="[MYFIRSTPARAM] " /mysecondparam="[MYSECONDPARAM]\"
Hope that helps.
MixedCase properties are "private" and will not be passed in from the command line.
ALLCAPS properties are "public" and can be passed in on the command line.
However only secure public properties are passed through to the 'server' (i.e. retained during UAC elevation). See the SecureCustomProperties property documentation.
Assuming you're trying to access this property in a deferred CA, this is happening on the server side so you need to use a public property (all caps) that is also marked as secure.
Here's an example using WiX:
<Property Id="MYPUBLICPROPERTY" Secure="yes" Value="{}">
If you want to be able to pass parameters from the outside you need to use ALLCAPS in your parameter names. I know it sounds weird, but try it! :-)
I know this is an old thread, but I tried a variety of things here and it seemed that I was at a loss. I then found the following thread on msdn:
http://social.msdn.microsoft.com/Forums/windows/en-US/8dd009ce-52d5-4737-98c8-89d9831ab60b/unable-to-pass-parameters-to-msi-thro-msiexec-via-command-prompt?forum=winformssetup&prof=required
Viewing the MSI in ORCA, you can see a few entries under "CustomAction." These Entries will basically override the values passed in from the command prompt. If you simply delete the entries in the CustomAction Table like: "CustomTextA_SetProperty_EDIT1" and then save the MSI (Save AS has a different behavior in ORCA). You can then pass the Property Values from the command line to the MSI. This will allow me to install remotely using msiexec and I am now be able to pass the parameters to the install via the command line. I imagine this happens because the logic for the CustomAction values is executed after having populated the property values from the command line which means that the CustomAction values overwrite the command line populated values.
There is also a link at the bottom of the thread to do some manipulation in VS as opposed to ORCA.
http://blogs.technet.com/b/alipka/archive/2007/04/20/how-to-use-custom-actions-in-visual-studio-setup-project-msi-from-command-line.aspx
I am reading WIX script written by others. There are some code really confuses me.
<Custom Action='UnLoadSchedulerPerfCounters' After='InstallInitialize'>
<![CDATA[(Installed) AND (!Scheduler = 3)]]>
</Custom>
<Custom Action='RollbackSchedulerPerfCounters' After='WriteRegistryValues'>
<![CDATA[(&Scheduler = 3)]]>
</Custom>
So, what's the difference between !Scheduler and &Scheduler?
Is any special meaning when property is prefix-ed by & or !?
From http://www.tramontana.co.hu/wix/lesson5.php#5.3:
Prepending some special characters to
the names will give them extra
meaning:
% environment variable (name is case insensitive)
$ action state of component
? installed state of component
& action state of feature
! installed state of feature
The last four can return the following
integer values:
-1 no action to be taken
1 advertised (only for components)
2 not present
3 on the local computer
4 run from the source
Those are operators on the Windows Installer condition syntax. See this MSI SDK documentation for a complete list: http://msdn.microsoft.com/en-us/library/aa368012.aspx.