How to assign Session variable values in the main()
What I want --> In the main function, a VirtualDir is declared. I want to set the regular time interval value in IIS in one of the application pools.
In my Wix# project, one of the dialogs takes hours and minutes as input in text boxes from a user. These hours and minutes are converted into minutes and stored in a session variable named RECYCLETIME.
namespace WixSharp_Setup1.Dialogs
{
public partial class ServerConfigDlg : ManagedForm, IManagedDialog
{
void next_Click(object sender, EventArgs e)
{
Runtime.Session["AppPoolLeft"] = txt_IISAppPoolLeft.Text;
Runtime.Session["AppPoolRight"] = txt_IISAppPoolRight.Text;
int hours = int.Parse(txt_IISAppPoolLeft.Text);
int minutes = int.Parse(txt_IISAppPoolRight.Text);
int totalMinutes = (hours * 60) + minutes;
Runtime.Session["RECYCLETIME"] = totalMinutes.ToString();
SaveTextData();
Shell.GoNext();
}
}
}
The VirtualDir is declared in the main function:
I want to assign the value of RECYCLETIME to the RecycleMinutes in the iasVirtualDir.
namespace Project1
{
public class Program
{
static void Main()
{
var serviceUser = new User
{
Id = "MyAppPoolUser",
Name = "[USERNAME]",
};
var iasVirtualDir = new IISVirtualDir
{
Name = "[SERVICENAME]",
AppName = "[SERVICENAME]",
WebSite = new WebSite("[WEBSITENAME]", "*:[WEBPORT]") { InstallWebSite = true },
WebAppPool = new WebAppPool("[SERVICENAME]",
"[USERNAME]" == "" ? "Identity=localSystem; RecycleMinutes=__________; RecycleRequests=10000"
: $"Identity=other; RecycleMinutes=_________; User={serviceUser.Id};")
};
var project = new ManagedProject("MyProduct",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File("Program.cs")));
project.BuildMsi();
}
}
}
When RecycleMinutes is assigned an integer directly, the value is visible in the IIS application pool.
Is there any way to assign the value of RECYCLETIME, declared in one of the dialogs, to RecycleMinutes in the main function? RecycleMinutes only take int values.
Hiho, dont know if helps, but try to create your own public property with Upper letters and set from dialog.
session["MYTIMEVALUE"] = textbox1.Text;
in your project you can add msi properties in project
project.Properties = new[]
{
new Property("MYTIMEVALUE", "default")
};
now you can set and get it from session object in any time of installdialog. This approach i use always if i have to asssign value to custom property.
best regards, Torchok.
Hi @Torchok19081986,
Thanks for the comment. I tried using your solution, but it isn't working.
Do you have any other approaches or solutions that might work?
@oleg-shilo
morning. Now i confused. Why isnt working ? Any errors on install or it doesnt assign your value from dialog to sesssion ? I done it many times in this way. There is only in one way where i cant be working. If your value has to be set from CA. Here you have to use DeffaultDefferedProperties where your custom Property after ADDLOCAL in projectdecription should looks like following
project.DefaultDeferedPropeties =",MYTIMEVALUE"
now you can use it in CA.
Very good example for IIS and Webserver in example from @oleg-shilo. Download latest Wix# latest Folder now navigate to Source\src\WixSharp.Samples\Wix# Samples\IIS.
Maybe this can give you some infos. You can also try to degug it in installdialog all values on install event.
just show messagebox.show in installprogressdialog . Method has SetupEventArgs e und now you can see in messagebox.Show -> e.Session.ToString().
Previously, I used many session variables directly in the main() function that were declared in the dialogs shown below.
When I try to assign ["RECYCLETIME"] to RecycleMinutes, it throws an error.
Error Message -
When I tried to convert ["RECYCLETIME"] to an integer, either the value is blank, or it shows an error indicating it is not a valid integer.
ok, I know, that it has to be Attribute1=[ATTRIBUTEVALUE1] in this Format. Your definition looks ok. Is RECYLETIME in output wxs file exists and show just like error says on WebAppPool Group? Check this passage in wxs file. May wxs file was wrong generated. You can also try, what happens if you set , just for test, your RecyleTime with value.
int RECYCLETIME = 125;
Recycletime ={RECYCLETIME};
if it works, then wxs file generates wrong values.
i just found https://docs.firegiant.com/wix3/xsd/iis/recycletime/ for IIS Wix toolset Extension. According to this link, value has to be DateTime in normal format und Pattern say h:mm. Maybe this helps.
It works. The int variable value is reflected in the regular time interval value in IIS.
Is there any way the Session["RECYCLETIME"] can be converted to an int and used in the main method?
ok, recyclevminuttes value is in minutes. If you use mangedUI setup, you can add custom dialog with content. just add newitem to your solutionproject and search for WixSharp Dialog. Add this Dialog in step on project.ManagedUI.Dialogs.add(WelcomeDialog).Add(Your dialog).
int recycleMinutes = int.Parse(Runtime.Session["RECYCLEMINUTES"].ToString());
Add textbox control to this dialog. After Click next Button on welcomeDialog , now you should see your new Dialog. In this Dialog you can add to session
I dont think, you can do any values in main() , because this happens on msi site and msi want a runtime value, whenever you set value, hardcoded or on install runtime.
and code from above. I cant do anything more, sorry.
Okay, I will try to implement your suggestion. Thanks for your help.
Hello again @oleg-shilo , @Torchok19081986
I am able to update the Regular time interval (minutes) in IIS using a PowerShell script. But I need some help.
During the first-time installation of the .msi, when no application pool is present, the default value of 1740 is set for the Regular time interval of an application pool.
When the application pool is already present in IIS, the value is updated.
This happens because, during the first-time installation, the PowerShell script is executed before the application pool is created, so the default value is set. During subsequent installations, the script finds the existing pool and updates the value.
The application pool code is present in the main() function, and the script to change the Regular time interval is present in the Project_AfterInstall() function.
I have tried using the e.IsInstalled and e.Installing events to set the Regular time interval, but neither of them worked.
namespace Project1
{
public class Program
{
static void Main()
{
var project = new ManagedProject("MyProduct",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File("Program.cs")));
var serviceUser = new User
{
Id = "MyAppPoolUser",
Name = "[USERNAME]",
Password = "[PASSWORD]",
PasswordNeverExpires = true,
CreateUser = false
};
var iasVirtualDir = new IISVirtualDir
{
Name = "[ISSERVICENAME]",
AppName = "[ISSERVICENAME]",
WebSite = new WebSite("[WEBSITENAME]", "*:[WEBPORT]") { InstallWebSite = true },
WebAppPool = new WebAppPool("[ISSERVICENAME]",
"[USERNAME]" == "" ? "Identity=localSystem; RecycleRequests=10000"
: $"Identity=other; User={serviceUser.Id};")
};
project.GUID = new Guid("5ddb2fe5-9cb6-418b-a538-360cd00b2af6");
//custom set of standard UI dialogs
project.ManagedUI = new ManagedUI();
project.ManagedUI.InstallDialogs.Add<WelcomeDialog>()
.Add<LicenceDialog>()
.Add<SetupTypeDialog>()
.Add<FeaturesDialog>()
.Add<InstallDirDialog>()
.Add<ProgressDialog>()
.Add<ExitDialog>();
project.ManagedUI.ModifyDialogs.Add<MaintenanceTypeDialog>()
.Add<FeaturesDialog>()
.Add<ProgressDialog>()
.Add<ExitDialog>();
//project.SourceBaseDir = "<input dir path>";
//project.OutDir = "<output dir path>";
project.AfterInstall += Project_AfterInstall;
project.BuildMsi();
}
private static void Project_AfterInstall(SetupEventArgs e)
{
string test = e.Session.Property("RECYCLETIME");
int recycleInterval = Convert.ToInt32(test);
string appPoolName = e.Session.Property("IASSERVICENAME");
// Powershell Script execution starts
}
}
}
Is there a solution to set the value after the application pool is created?
TL;DR version Either look for "how to set Regular time interval from MSI WiX" or simply wait in your PS Script until the app pool is created and then set the value.
Well designed solution If WiX does not have support for the value you are trying to change, then you need to do it viaa custom routine. And this is where it becomes difficult.
The problem you are facing is caused by your deployment design. You want to take certain actions when an external system gets in a certain state. This is not a task for MSI. MSI has no means for interacting with this system, so it cannot access its state.
This means that you need to start some routine at the end of the installation, and that routine needs to wait for the state change event before doing the final configuration.
That's why good deployment practices require developers to separate the installation (copy files to the appropriate locations) and configuration (integrate your application with the OS). Thus, a good design would look like this:
- Have your msi that deploys all files and creates the base configuration (e.g. install your WebSite)
- Run your application configuration utility from your Project_AfterInstall to finalise the WebSite configuration
- wait until app pool is created
- set Regulat Time Interval of the app pool
This way, you can even invoke your config utility even without restarting the MSI installation. IE iof the configuration has been altered and you need to reset it to the healthy state.
The configuration utility is just a concept. But its implementation can be as simple as your application executable run with a special command line switch (-config) and the handler of this switch, where you do all waiting and configuring the stuff without even resorting to PowerShell.
Thanks. Will try out this solution and let you know.