Introduction
Here's the sad fact of life: IIS is not redistributable. If you write an ASP.NET application, the target system pretty much has to have IIS preinstalled. If not, your customers will have to have skills to setup IIS and post-configure ASP.NET to run on IIS. This, of course, drastically shrinks your target audience by cutting out those who want to run ASP.NET applications, but don't have an IT Department to setup and maintain IIS. IIS, as far as I know, cannot be automatically installed as part of the installation process. To solve the problem, many developers started relying on different variations of Cassini - a sample web server originally posted at www.asp.net by Microsoft and now made a default debugging web server for Visual Studio .NET 2005. To illustrate how ASP.NET applications can be installed and ran on a box that has no IIS, we'll take one of the Cassini builds that comes with a prepackaged merge module - a self-installing Visual Studio .NET component that automatically installs itself on the target system when included into a Visual Studio .NET Setup Project. You will need to install Cassini Server in order to execute this Setup Project creation walkthrough successfully. Depending on the version of ASP.NET and .NET Framework you use, you will need to get either Cassini 1.1 - for ASP.NET 1.1 applications, or Cassini 2.0 for the latest ASP.NET 2.0 applications.
After you have installed Cassini, first make sure your ASP.NET application is compatible with Cassini. In most cases, it will be, but sometimes you may need to make changes if your application uses IIS-specific features like IIS server variables. To check your application compatibility with Cassini, run the Cassini Explorer from the Programs menu and register your ASP.NET application with Cassini. To register the application, you only need to provide the application's physical location, the default document name if it's not "default.aspx", and generate the application's ID. The rest of the fields are optional. After you have registered the application, click the link on the main Cassini Explorer page to see your ASP.NET application running without IIS. If everything's OK, you can start with creating a setup project that will make your application run on clients' systems without IIS.
Setup Project Creation Walkthrough
In this walkthrough, we will create a regular (non-web) Setup Project, then we'll add your application's Primary Output and Content Output to the Setup Project, include the Cassini merge module, and program the Setup Project's custom actions to programmatically register your application with Cassini during installation, and unregister it during uninstallation.
Now, let's do these things step by step. We assume you already have a solution with your ASP.NET application. The included example includes a one-page ASP.NET sample application along with the sample setup project.
- Start by adding a new Setup Project to the Visual Studio .NET solution hosting your ASP.NET project.
- Since in Vistual Studio 2003, setup projects are excluded from build by default, you will need to right-click the solution and bring up the Configuration Manager. There, switch to Release configuration and check the Build checkbox corresponding to your newly created Setup Project. Do a test build - make sure your Setup Project gets built.
- Add your ASP.NET project output to the Setup Project. To do that, right-click on the Setup Project, and select View | File System. On the Setup Project's File System window, right-click Application Folder and select Add | Project Output. In the popped-up window, select your ASP.NET project from the Project drop-down, if it's not selected by default. Multi-select (by holding Ctrl key) Primary Output and Content Files items from the list box and click OK.
- Add the Cassini self-installing redistributable module to the Setup Project. For that, right-click your Setup Project and select Add | Merge Module. In the popped-up File Open dialog, select CassiniRedistributable.msm file for ASP.NET 1.1 applications, or Cassini2Redistributable.msm for ASP.NET 2.0 applications. If you don't see these files, please make sure that the File Open dialog shows the contents of the "C:\Program Files\Common Files\Merge Modules" folder. Please note that once you've added CassiniRedistributable.msm to the Setup Project, Visual Studio .NET will automatically add the CassiniExplorerMergeModule.msm file into the Detected Dependencies bin. That's OK - just the way it's supposed to be. These two files - the entire Cassini web server - will add a mere 400 KB to the size of your project.
- Add the Custom Installer class to your ASP.NET project. Right-click your ASP.NET project and select Add | Add New Item. From the Templates list, select Installer Class, and click the Open button to add the class to the project.
- Add a reference to the CassiniConfiguration.dll assembly to your ASP.NET project. This assembly implements a simple Cassini applications management API. To do that, right-click your ASP.NET project and select Add Reference. In the popped-up window, click the Browse button and navigate to either the "C:\Program Files\UltiDev\Cassini ASP.NET 1.1 Server" folder for ASP.NET 1.1 applications, or to the "C:\Program Files\UltiDev\Cassini ASP.NET 2.0 Server" for ASP.NET 2.0 applications. From there, select CassiniConfiguration.dll to add to your project references.
Please do the test build of the solution and check if CassiniConfiguration.dll has appeared in the Detected Dependencies bin of your setup project. If not, please go to the File System view of the Setup Project, and highlight the Bin folder under the Application Folder. Right-click Bin folder and select Add | File. Navigate to your ASP.NET application's bin folder, which is usually "c:\inetpub\wwwroot\YourAppName\bin" and double-click CassiniConfiguration.dll.
- Implement the installer custom actions in the custom installer class. Paste the following code into the
Installer1
class implementation:
C# Sample:
private static readonly Guid applicationID =
new Guid("{88EEE2B2-57D5-4869-A85E-9666FCDD390E}");
public override void Install(IDictionary savedState)
{
string appLocation = Context.Parameters["applocation"];
CassiniConfiguration.Metabase.RegisterApplication(applicationID,
"My Great Web Application",
"Application description",
appLocation, "WebForm1.aspx");
base.Install(savedState);
}
public override void Rollback(IDictionary savedState)
{
CassiniConfiguration.Metabase.UnregisterApplication(applicationID);
base.Rollback (savedState);
}
public override void Uninstall(IDictionary savedState)
{
CassiniConfiguration.Metabase.UnregisterApplication(applicationID);
base.Uninstall (savedState);
}
VB.NET Sample:
Imports CassiniConfiguration
Private Shared ReadOnly applicationID As Guid
Shared Sub New()
Installer1.applicationID = _
New Guid("{88EEE2B2-57D5-4869-A85E-9666FCDD390E}")
End Sub
Public Overrides Sub Install(ByVal savedState As IDictionary)
Dim appLocation As String = _
MyBase.Context.Parameters.Item("applocation")
Metabase.RegisterApplication( _
Installer1.applicationID, _
"Is IIS Neccessary?", _
"Life after IIS is fun!", _
appLocation, "WebForm1.aspx")
MyBase.Install(savedState)
End Sub
Public Overrides Sub Rollback(ByVal savedState As IDictionary)
Metabase.UnregisterApplication(Installer1.applicationID)
MyBase.Rollback(savedState)
End Sub
Public Overrides Sub Uninstall(ByVal savedState As IDictionary)
Metabase.UnregisterApplication(Installer1.applicationID)
MyBase.Uninstall(savedState)
End Sub
Now, you need to change the values of the highlighted portions of the code snippet to reflect the actual values appropriate for your application. To generate a new GUID for your application, you can run this command line: %VS71COMNTOOLS%guidgen.exe. In the popped up window, select option 4 and hit the Copy button. Paste the copied value over the GUID value in the snippet above. Do a test build to make sure your solution is doing fine so far.
- Hook up your Custom Installer class to the Setup Project. To do that, right-click the Setup Project, and select View | Custom actions. Now, for each custom action in the list, do this: right-click the custom action folder and select Add Custom Action. In the popped-up window, double-click Application Folder bin and then double-click the Primary Output item of the ASP.NET application project. This will add the invocation of the installer class' methods implemented on the previous step. To pass the name of the installation folder to the installer class, highlight the Primary Output item under the Install Custom Action, and in the property editor, paste /AppLocation="[TARGETDIR]\" as a value of the
CustomActionData
property.
- This is it with regards to the steps necessary to create an installer for your ASP.NET application. Now, you can make a build and run the test installation by right-clicking on your Setup Project and selecting Install. After the installation completes, run the Cassini Explorer from the Programs menu to see your application among the registered Cassini applications. Uninstall your product before making another build.
Please remember, a Visual Studio .NET Setup Project has this kink of getting its Detected Dependencies messed up if you attempt to build when your product is installed. Don't forget to uninstall your product before making another build. If you made a build while having your product installed, uninstall the product and then right-click on Detected Dependencies and select Refresh Dependencies.
The following few steps are optional. They describe how to create a Programs menu shortcut for your application on the target system.
- Start creation of the Programs menu shortcut by adding the LocalStart.htm file to your ASP.NET project. To do that, right-click your ASP.NET project in Visual Studio .NET, and select Add | Add HTML Page. In the popped up window, change the file name to LocalStart.htm and hit OK. Open the LocalStart.htm file in HTML source mode and replace its current HTML with this:
<html>
<head>
<title></title>
<meta http-equiv="refresh"
content="0;url=http://localhost:7756/GoToApplication.
aspx?AppID=88EEE2B2-57D5-4869-A85E-9666FCDD390E"/>
</head>
<body>
</body>
</html>
Replace the highlighted GUID above with your application GUID that you generated at step 7 and save the LocalStart.htm file. You can find your application GUID value in the Installer1.cs file in your ASP.NET project.
If you make a test build and install the product at this point, pointing the browser to the LocalStart.htm should bring up your application. Don't forget to uninstall the product before the next build attempt.
- To create the actual Programs menu shortcut to the LocalStart.htm, first switch to the Setup Project's "File System View" by right-clicking on the Setup Project and selecting View | File System. There, right-click "Application Folder" bin and select Add | File. Navigate to, and then double-click the LocalStart.htm file your have created at the previous step. The usual location of the file is "c:\inetpub\wwwroot\YourApplicationName\LocalStart.htm". Now, you should see the LocalStart.htm file in the "Application Folder" bin of your Setup Project. Right-click the LocalStart.htm file in the "Application Folder" and select Create Shortcut. Rename the shortcut to something like "My Great ASP.NET Application". After that, drag and drop the "My Great ASP.NET Application" item from "Application Folder" to "User's Programs Menu" bin. Save all files, do a test build, and install your product. After the installation is completed, you should see the "My Great ASP.NET Application" item in the Programs menu. Click it and enjoy your ASP.NET application running on a box that need not have IIS installed.
Now, you can play with the Setup Project options to make them reflect your product and company identity.