Just a quick post a few hours before my birthday. It took a while a long time ago to figure out how I could execute some code before my Azure Web Role launches, when deploying to Windows Azure. This is only applicable to WebRole and WorkerRole.
This information was found here and sibling pages: http://msdn.microsoft.com/en-us/library/hh180155.aspx
What have you have to do is add the <StartUp> element to your Service Definition Schema file ServiceDefinition.csdef:
<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"> <WebRole name="WebRole1"> <Startup> <Task commandLine="Startup.cmd" executionContext="limited" taskType="simple"> </Task> </Startup> </WebRole> </ServiceDefinition>
Pretty simple, which is awesome.
- commandLine is what you’re going to execute.
- This runs from the context of AppRoot\Bin, which is the folder your application is deployed-to before it’s moved to its real location, in the case of an IIS website.
- In other words, the path this program is executing is not the path of your IIS application.
- If you write a console application in your solution, this will be as simple as ProjectName.exe
- http://msdn.microsoft.com/en-us/library/gg557552.aspx#Startup : “A script, such as a CMD file, containing the commands to run. Startup command and batch files must be saved in ANSI format. File formats that set a byte-order marker at the start of the file will not process properly.”
- This runs from the context of AppRoot\Bin, which is the folder your application is deployed-to before it’s moved to its real location, in the case of an IIS website.
- executionContext is the level of permissions.
- The only options are limited and elevated. Elevated runs as Administrator.
- taskType is how the program will be run.
-
simple
- The task must exit before other tasks are lunched
- background
- System does not wait for task to exist.
- foreground
- Same as background, but role won’t restart until task is finished.
-
What you should know
- You can have multiple <Task>s in your <Startup> element.
- Log errors in the directory of the Environment variable, which is set to C:\Resources\temp\<guid>.<rolename>\RoleTemp .
- It’s important to know that with taskType=”simple”, if the program doesn’t exit with code 0, deployment is considered a failure. When this occurs, the role is not started.
- Startup tasks can also be executed several times between reboots. For example, the startup task will be run each time the role recycles, and role recycles may not always include a reboot. Startup tasks should be written in a way that allows them to run several times without problems.
- You can use environment variables to pass information to the role.
Bonus
In my startup application, I needed to know where my IIS application was deployed. As far as I can tell, Azure does not tell you what this path is and it can be different after each deployment. I used the code below to search for my IIS installation from the path that the Startup program executes. My IIS application contained the folder “Deployment”, which is what I needed to find.
var executingDirectory = Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location ); var rootDir = Directory.GetDirectoryRoot( executingDirectory ); const string deploymentFolderName = "Deployment"; string fullDeploymentPath = null; foreach( var s in Directory.EnumerateDirectories( Path.Combine( rootDir, "sitesroot" ) ) ) { var bin = Path.Combine( s, "bin" ); if( Directory.Exists( bin ) ) { var deployment = Path.Combine( bin, deploymentFolderName ); if( Directory.Exists( deployment ) ) { fullDeploymentPath = deployment; break; } } }