Out of the box, basic web project deployment is taken care of as soon as web port is configured in BizTalk application and MSI is exported. When running, this MSI will create web directory under default IIS web site and copy all files found in this directory on the build server. Now, what if we want to change physical location of web directory to be different from the build server, or limit set of files that must be deployed, or deploy precompiled web project (by source files get deployed)? There are ways to achieve these goals.
To add web directory to an application when building a package we can use following command:
BtsTask.exe AddResource -Type:System.BizTalk:WebDirectory
/Source:value /Destination:value
There’s one problem though: the Destination parameter defines only virtual path. The physical path will be the same as on the source machine where the package is built. We can change it by creating IIsVirtualDir metabase entry with Path property set to desired physical location prior to calling AddResource command. This will still leave us with physical path hardwired into the msi without ability to alter it at the install time. Another problem with this approach is that all files from source directory will be added to the package as is (not compiled source files) which is not always desired.
More flexible way would be to take full control of the web project installation process and here is how.
Package build:
1) Compile web project in desired mode to designated folder (in this example PrecompiledPath) using aspnet_compiler.exe. There are three compilation modes available for web projects: default no precompilation (source code, will be compiled on request), precompiled updateable, binaries only. Pasting following code into project’s build subscript (i.e. %AppName%_build_projects.bat in the previous post) will take care of this step:
IF %BuildMode%==Debug (SET WebEmitDebug=-d)
aspnet_compiler -v /%VirtDirName% -f -fixedNames %WebEmitDebug% “PrecompiledPath“
2) Add required only files from this folder to the package using BtsTask AddResource. One way of doing this:
FOR %%F IN (“PrecompiledPath\*.*”) DO btstask AddResource /A:%AppName% /Type:System.BizTalk:File /Source:”%%F” /Destination:”%%BTAD_InstallDir%%\TargetFolderName\%%~xnF” /Overwrite
FOR %%F IN (“PrecompiledPath\bin\*.*”) DO btstask AddResource /A:%AppName% /Type:System.BizTalk:File /Source:”%%F” /Destination:”%%BTAD_InstallDir%%\TargetFolderName\bin\%%~xnF” /Overwrite
3) Create script that will configure virtual directory during installation when invoked. The script can use whether WMI or ADSI. Here’s an example of WMI one:
Sub ConfigureWebApplication(installPath, appPoolName, webDirName, serviceAccount, password)
Dim iisvdirCmd, winDir, objWMI, items, item
Const OutOfProcess = 1
Const WaitOnReturn = True
Const CreateIfNotExist = True
Const WindowStyle = 0
Set shell = CreateObject(“WScript.Shell”)
Set environment = shell.Environment(“Process”)
winDir = environment(“WINDIR”)
‘Create virtual directory
iisvdirCmd = winDir & “\system32\iisvdir.vbs /create “ & Chr(34) & “Default Web Site” & Chr(34) & ” “ & webDirName & ” “ & _
Chr(34) & installPath & “\” & webDirName & Chr(34)
shell.Run iisvdirCmd, WindowStyle, WaitOnReturn
Set objWMI = GetObject (“winmgmts:{authenticationLevel=pktPrivacy}\\.\root\microsoftiisv2”)
Set items = objWMI.ExecQuery(“Select * From IIsWebVirtualDir Where Name = ‘W3SVC/1/ROOT/” & webDirName & “‘”)
For Each item in items
item.AppCreate3 OutOfProcess, appPoolName, CreateIfNotExist
Wscript.Echo “Creating web application “ & item.Name
Next
Set items = objWMI.ExecQuery(“Select * From IIsWebVirtualDirSetting Where Name = ‘W3SVC/1/ROOT/” & webDirName & “‘”)
For Each item in items
Wscript.Echo “Configuring security for virtual directory “ & item.Name
item.AccessSSL = True
item.AccessSSL128 = True
item.AccessSSLRequireCert = True
item.AppFriendlyName = webDirName
item.Put_
Next
‘Set application pool identity
Set items = objWMI.ExecQuery(“Select * from IIsApplicationPoolSetting Where Name = ‘W3SVC/apppools/” & appPoolName & “‘”)
For Each item in items
Wscript.Echo “Setting identity of application pool “ & item.Name
item.WAMUserName = serviceAccount
item.WAMUserPass = password
item.Put_
Next
End Sub
This function not only creates virtual directory but completely configures web application to be used by BizTalk including setting up application pool and its identity. There are also functions to create folders, write to registry and do other useful tasks that I don’t show here.
We have to make sure our script is invoked in right context, so it can be like this:
Sub RunTasks()
Dim installMode, path
installMode = environment(“BTAD_InstallMode”)
If installMode=“Install” Then
path = environment(“BTAD_InstallDir”)
‘Get other deployment parameters through dialog or config file omited
CreateFolders(path)
WriteToRegistry(path)
ConfigureWebApplication(path, appPoolName, webDirName, serviceAccount, password)
End If
End Sub
Finally, let’s add this script to the package as preprocessing (install stage):
btstask AddResource /A:%AppName% /Type:System.BizTalk:PreProcessingScript
/Source:PreInstallScript.vbs /Overwrite
If we want to script web service publishing there’s a way to call it through object model:
WebServiceDescription desc = WebServiceDescription.LoadXml(path);
WebServiceBuilder builder = new WebServiceBuilder();
builder.WebServiceDescription = desc;
builder.BuildWebService();
Where the path variable points to the WebServiceDescription.xml generated by Web Services publishing wizard.
Installation:
1) Run MSI on target machine and point to the desired installation directory
2) Provide installation parameters like serviceAccount/password for IIS application pool identity. This can be done from text file or interactive form.
Now we have full control over BizTalk web project installation and can easily move application through staging deployments.