Pass value from command line to Custom action-Burn - c#

I am in a need to pass the value from command line to custom action.The custom action should get the value from command line and modify one file(app.config) during installation of EXE.I have the below code in custom action
if (Context.Parameters["ENV"] == "test") //Test environment
{
authEndPoint = "http://192.168.168.4/api/user_authentication/";
}
else if (Context.Parameters["ENV"] == " ") //Production environment
{
authEndPoint = "https://livesiteurl/api/user_authentication/";
}
I want to install the exe file like below
myapplication.exe env=test
I seen lot of sample to pass the value from command line to msi. How to pass the value from command line to CA and modify the app.config file.

There are better ways to do what you're trying to do here than use a custom action. Take a look at this for how use the WiXUtilExtension to modify the file, then create a property and reference it from the command line. If you still need/want to use a bootstrapper you can set that property you created with MsiProperty inside MsiPackage in the bundle.

Related

Disable Wix Custom action on /quiet /silent

In a WIX custom action, is there a way to detect whether the MSI was invoked with /silent or /quiet command line switches? Basically what I want is to not execute the custom action (since it shows a form) or handle it differently if these command line switches were passed but I am unable to find this out.
Is there a way to possibly detect it?
You can check the property UILevel and execute your CA based on your conditions.
I finally figured it out. Wix basically always sets the UILevel property to 2.0. It has its own property called WixBundleUILevel. Now important thing here is that prior to Wix 3.11 this WixBundleUILevel was an internal property and was not accessible to Bundle projects or MSI Custom Actions. So here is what I did
Defined a property in MSI called UI_LEVEL (important, make it all upper case)
In Bundle.wxs, right where I call MSIPackage, I set the UI_LEVEL property like so
<MsiPackage SourceFile="$(var.MsiPath)">
<MsiProperty Name="UI_LEVEL" Value="[WixBundleUILevel]" />
</MsiPackage>
Then finally in the custom action I check for this property like
int uiLevel;
if (int.TryParse(session["UI_LEVEL"], out uiLevel))
{
if (uiLevel == 4)
using (var form = new WhatsNew())
{
form.ShowDialog();
}
else
session.Log("Skipping What's new dialogue as UI Level is not 4");
}
else
{
session.Log("Couldnt figure out the UI level, so skipped the prompt");
}
And finally
here are the possible values of this f**ed up property
WixBundleUILevel Value Burn parameters
BOOTSTRAPPER_DISPLAY_FULL 4 (none)
BOOTSTRAPPER_DISPLAY_PASSIVE 3 /silent
BOOTSTRAPPER_DISPLAY_NONE 2 /quiet

Avoid Constructor called from Tab key

I'm writing a PowerShell module in C#. At runtime one of the cmdlets is called like this:
Test-Path -Path \\path\to\somewhere
My constructor looks like this:
public TestPath()
{
checkPathExistence();
}
This is working until the user at runtime presses the Tab key in order to autocomplete parameter name:
Test-Path -Pa <TAB>
The Tab key fires the constructor and this causes my checkPathExistence() method to give unwanted results. How can I make my checkPathExistence() wait for the Enter key before checking anything?
My first idea was to check Path being null. But Path isn't mandatory. If the cmdlet is being called without any parameter some standard path from former sessions is being set.
void checkPathExistence()
{
if (!File.Exists(this.Path))
{
Path = Properties.Settings.Default.Path;
}
else
{
Properties.Settings.Default.Path = Path;
Properties.Settings.Default.Save();
Console.WriteLine("The path has changed to: " + Path);
}
}
}
The problem here is that you are calling checkPathExistence during the constructor. Instead, it sounds like you only want to call it while processing the command-line including the path. Leave the constructor empty, and instead handle the command-line during ProcessRecord. See Cmdlet Input Processing.

Pass parameters with apostrophs to a batch file

How do I passt following parameters to my batch file?
custom.bat mode="test" logs="true"
I tried to double the " but nothing helped.
custom.bat "mode="test"" "logs="true""
And, in custom.bat you remove the unneeded quotes
#echo off
set "arg1=%~1"
set "arg2=%~2"
echo [%arg1%] [%arg2%]
You may use CALL command to launch a new batch-file. After executing the last line of the "called file", the control will return back to the "calling file".
You may set the parameters to the "called .bat fie" by using either a simple string or a variable.
eg.
CALL MyScript.bat "1234"
or
SET _MyVar="1234"
CALL MyScript.bat %_MyVar%
As a precaution, you may use SETLOCAL & ENDLOCAL to keep separation between variables of same-name among different files.

Send Custom Action Data via Command Line for Visual Studio Installer

I have a Visual Studio Installer that has a custom UI with one text box recovering a value that is set to QUEUEDIRECTORY property. Then I have a custom action (an Installer class) that passes in that property value with this line /queuedir="[QUEUEDIRECTORY]" - and the installer works great.
Now, I need to send that value via the command-line so that this installer can be run by system administrators all across the organization. So, I tried the following command line statements but it just doesn't work.
msiexec /i Setup.msi QUEUEDIRECTORY="D:\temp"
Setup.msi QUEUEDIRECTORY="D:\temp"
Setup.msi queuedir="D:\temp"
msiexec /i Setup.msi queuedir="D:\temp"
Further, I can't seem to find anything online that doesn't feel like they hacked it because they just couldn't find the solution. I mean I've found some solutions where they are editing the MSI database and everything, but man that just doesn't seem like it's the right solution - especially since I'm using Visual Studio 2010 - Microsoft has surely made some enhancements since its initial release of this offering.
Here is one of the articles that appears would work but still really feels like a hack.
At any rate, I hope that you can help me out!
This is what I did to add command line only property values to my MSI in Visual Studio 2010. It's similar to the accepted answer, but less hacky. Create CommandLineSupport.js in setup project (.vdproj) directory, with the following code:
//This script adds command-line support for MSI installer
var msiOpenDatabaseModeTransact = 1;
if (WScript.Arguments.Length != 1)
{
WScript.StdErr.WriteLine(WScript.ScriptName + " file");
WScript.Quit(1);
}
WScript.Echo(WScript.Arguments(0));
var filespec = WScript.Arguments(0);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
var sql
var view
try
{
sql = "INSERT INTO `Property` (`Property`, `Value`) VALUES ('MYPROPERTY', 'MYPROPERTY=\"\"')";
view = database.OpenView(sql);
view.Execute();
view.Close();
database.Commit();
}
catch(e)
{
WScript.StdErr.WriteLine(e);
WScript.Quit(1);
}
Then click on your Deployment Project in Visual Studio to view the Properties of the project, and set the PostBuildEvent to this:
cscript.exe "$(ProjectDir)CommandLineSupport.js" "$(BuiltOuputPath)"
Then set up the Delopyment Project with a Custom Action. Click on the Primary Output to get to the Custom Action Properties, and set the CustomActionData field to /MYPROPERTY="[MYPROPERTY]"
You can then access that property in your Custom Action installer class like this:
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
string the_commandline_property_value = Context.Parameters["MYPROPERTY"].ToString();
}
In the end you can run the cmd. C:\>Setup.msi MYPROPERTY=VALUE
This doesn't require any messing about in Orca, or using any custom dialog controls like in the accepted answer. You don't have to modify the PostBuildEvent to have the correct .msi name either. Etc. Also can add as many properties as you wish like this:
INSERT INTO `Property` (`Property`, `Value`) VALUES ('MYPROPERTY', 'MYPROPERTY=\"\"'),('MYPROPERTY2', 'MYPROPERTY2=\"\"', ('MYPROPERTY3', 'MYPROPERTY3=\"\"')) ";
Have fun!
Alright, so I ended up going with the solution I linked to in the question. But let me put the script here for completeness. The first thing I needed to do was build a JS file that had the following code (I named it CommandLineSupport.js) and put it in the same directory as the .vdproj.
//This script adds command-line support for MSI build with Visual Studio 2008.
var msiOpenDatabaseModeTransact = 1;
if (WScript.Arguments.Length != 1)
{
WScript.StdErr.WriteLine(WScript.ScriptName + " file");
WScript.Quit(1);
}
WScript.Echo(WScript.Arguments(0));
var filespec = WScript.Arguments(0);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
var sql
var view
try
{
//Update InstallUISequence to support command-line parameters in interactive mode.
sql = "UPDATE InstallUISequence SET Condition = 'QUEUEDIRECTORY=\"\"' WHERE Action = 'CustomTextA_SetProperty_EDIT1'";
view = database.OpenView(sql);
view.Execute();
view.Close();
//Update InstallExecuteSequence to support command line in passive or quiet mode.
sql = "UPDATE InstallExecuteSequence SET Condition = 'QUEUEDIRECTORY=\"\"' WHERE Action = 'CustomTextA_SetProperty_EDIT1'";
view = database.OpenView(sql);
view.Execute();
view.Close();
database.Commit();
}
catch(e)
{
WScript.StdErr.WriteLine(e);
WScript.Quit(1);
}
You of course would need to ensure that you're replacing the right Action by opening the MSI in Orca and matching that up to the Property on the custom dialog you created.
Next, now that I had the JS file working, I needed to add a PostBuildEvent to the .vdproj and you can do that by clicking on the setup project in Visual Studio and hitting F4. Then find the PostBuildEvent property and click the elipses. In that PostBuildEvent place this code:
cscript "$(ProjectDir)CommandLineSupport.js" "$(BuildOutputPath)Setup.msi"
Making sure to replace Setup.msi with the name of your MSI file.
Though I still feel like it's a hack ... because it is ... it works and will do the job for now. It's a small enough project that it's really not a big deal.
This is an old thread, but there's a simpler, working solution that still seems hard to find, hence why I'm posting it here.
In my scenario we're working with VS2013 (Community Ed.) and VS 2013 Installer Project extension. Our installer project has a custom UI step collecting two user texts and a custom action bound to Install\Start step that receives those texts.
We were able to make this work from GUI setup wizard, but not from command line. In the end, following this workaround, we were able to make also command line work, without any MSI file Orca editing.
The gist of the thing was to set a value for all needed custom dialog properties directly from Visual Studio, and such value should be in the form [YOUR_DIALOG_PROPERTY_NAME]. Also, it seems like such "public" properties must be named in all caps.
Here's the final setup:
Custom dialog properties
Note e.g. Edit1Property and Edit1Value.
Custom action properties
Note as property key used later in code can be named in camel case.
Custom action code
string companyId = Context.Parameters["companyId"];
string companyApiKey = Context.Parameters["companyApiKey"];
Command line
> setup.exe COMPANYID="Some ID" COMPANYAPIKEY="Some KEY" /q /l mylog.txt
HTH

environmental variable in a c#

I am using the following command to set a value to the environmental variable in a c# Console application.
System.Environment.SetEnvironmentVariable(envvar, result,EnvironmentVariableTarget.Process);
After running the application in the command window, when I try to echo that variable ,I cannot see the value.
I have to use this application in a batch file.
I want the functionality like SET command. Please help..
Edit:
I tried using System.Environment.SetEnvironmentVariable(envvar,result,EnvironmentVariableTarget.user) and to propagate the change I tried this Propagating Change in Env VAr. But I cant echo the variable in same command window.
Let me rephrase the question:
I want to set a value to a Env Var in c#. I must be able to use that variable in same command window (ie i should not open a new cmd window to see the change). We use SET command and we can use that variable immediately .. rt ? I want such functionality. Plzz help
When you use EnvironmentVariableTarget.Process the variable set will only visible in the current process as you can see in this sample:
System.Environment.SetEnvironmentVariable("myVar", "myValue", EnvironmentVariableTarget.Process);
string s = System.Environment.GetEnvironmentVariable("myVar",EnvironmentVariableTarget.Process);
Above myVar will show s = "myValue" but not visible in command window.
If you want to set the value visible at command windows then you need to use EnvironmentVariableTarget.User:
System.Environment.SetEnvironmentVariable("myVar", "myValue", EnvironmentVariableTarget.User);
This way the setting myVar=myValue will be stored and then you can see on command windows.
A detailed sample is located here
In order to see the env in the current batch process. You have to output it in you program as string and parse it and call set in the batch file.
Or you can try EnvironmentVariableTarget.User. The env will be visible in all new processes when setted with this option.

Categories