ne of the most challenging tasks faced by Windows application developers is the deployment of their applications on the client machines. Once an application is deployed, any changes or maintenance to the application require redeployment. Worse, with so many different client configurations, updating a Windows application is always fraught with unknowns.
In Visual Studio 2005, a new deployment technology known as ClickOnce makes such deployments and even updates extremely easy and painless. ClickOnce is the perfect technology to ease the deployment of smart clients.
A smart client, of course, is basically a Windows application that leverages the system’s local resources and is able to intelligently connect to distributed data sources (such as Web services) as needed.
Ubiquitous access was the key advantage that helped propel the popularity of Web-based applications in the enterprise. And while today a lot of companies are still using Web-based apps, network latencies and server delays are some of the issues that companies struggle with. Common frustrations include slow response time from Web sites and limited functionality (due to the stateless nature of the HTTP protocol). A smart client aims to reap the benefit of the rich functionality of the client (Windows) while utilizing the power of Web services to provide ubiquitous data access on the back end. ClickOnce provides a critical piece of enabling infrastructure for a smart client: It allows you to deploy applications onto users’ computers with the same ease that Web-based applications are accessed.
To illustrate how ClickOnce works, I will build a simple Windows application and then publish and deploy the application using a Web server. Furthermore, because ClickOnce has the added benefit of automatically checking for the latest update of the application (you can configure the application to check every time before it runs or to check at regular time intervals), I will also show you how to configure the application with the minimum set of permissions needed for it to perform these checks properly and safely.
Creating the UI
The sample application is a simple text editor. Using this text editor, you can open a file for editing, save a file to disk, as well as perform a simple spell-check using a spell-check Web service.
To build the sample app, launch Visual Studio 2005 and create a new Windows application. Name it C:MyEditor. Populate the default Form1 with the controls as shown in Figure 1.
Set the ContextMenuStrip property of RichTextBox1 to “ContextMenuStrip1” so that when the user right-clicks on the RichTextBox control, a context menu is displayed.
Adding a Web Service
In this section I will add a Web service to the project. The text editor will connect to this Web service for the spell-check functionality. Go to File?>Add?>New Web Site?. Select the ASP.NET Web Service template and name the project http://localhost/SpellCheckWS (see Figure 3).
|Figure 3. Spell Check: Create a new Web service project to provide the spell-check functionality for the smart client text editor.
In the Service1.vb file, code the following:
_ Public Function CheckWord(ByVal word As String) As String() Dim result(0) As String result(0) = "" Select Case word Case "teh" : ReDim result(0) result(0) = "the" Case "comuter" : ReDim result(2) result(0) = "commuter" result(1) = "computer" result(2) = "commuters" End Select Return result End Function
Essentially, the CheckWord() function takes a string parameter and returns an array of strings. For simplicity I have hard-coded the words to spell-check.
Consuming the Web Service
To consume the Web service, right-click on the MyEditor project in Solution Explorer and select Add Web Reference?. In the Add Web Reference dialog, enter the URL as shown in Figure 4 and then click Go. Finally, click Add Reference and then OK.
|Figure 4. Web Service URL: Add a Web reference to the Web service.
Double-click on the Spell Check item in the ContextMenuStrip control and code the following:
Private Sub SpellCheckToolStripMenuItem_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles SpellCheckToolStripMenuItem.Click '---use the web service to spell-check a word Dim ws As New SpellCheckWS.Service Dim result() As String result = ws.CheckWord(RichTextBox1.SelectedText) Dim str As String = "" For i As Integer = 0 To result.Length - 1 str += result(i) & ", " Next '---display the list of possible words MsgBox(str) End Sub
The above block of code will connect to the spell-check Web service and display the result returned by it.
Likewise for the Open button, code the following:
Private Sub btnOpen_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnOpen.Click ' Create an OpenFileDialog to request a file to open. Dim openFile1 As New OpenFileDialog() ' Initialize the OpenFileDialog to look for RTF files. openFile1.DefaultExt = "*.rtf" openFile1.Filter = "RTF Files|*.rtf" ' Determine whether the user selected a file from the ' OpenFileDialog. If (openFile1.ShowDialog() = _ System.Windows.Forms.DialogResult.OK) _ And (openFile1.FileName.Length > 0) Then ' Load the contents of the file into the RichTextBox. RichTextBox1.LoadFile(openFile1.FileName, _ RichTextBoxStreamType.PlainText) End If End Sub
The above block of code will display the Open File dialog to let the user choose a filename. The chosen file is then loaded onto the RichTextBox control.
For the Save button, code the following. This will open the Save File dialog and save the content of the RichTextBox control onto the selected file.
Private Sub btnSave_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnSave.Click ' Create a SaveFileDialog to request a path and file name ' to save to. Dim saveFile1 As New SaveFileDialog() ' Initialize the SaveFileDialog to specify the RTF extension ' for the file. saveFile1.DefaultExt = "*.rtf" saveFile1.Filter = "RTF Files|*.rtf" ' Determine if the user selected a file name from the ' saveFileDialog. If (saveFile1.ShowDialog() = _ System.Windows.Forms.DialogResult.OK) _ And (saveFile1.FileName.Length) > 0 Then ' Save the contents of the RichTextBox into the file. RichTextBox1.SaveFile(saveFile1.FileName, _ RichTextBoxStreamType.PlainText) End If End Sub
That’s it! To test the application, press F5. Type something into the RichTextBox control, right-click on a word and then select Spell Check. The result returned by the Web service will be displayed in dialog that offers suggestions for the misspelled word.
When you click the Save? button, a Save As dialog box will appear. Likewise, when you click the Open? button, the Open dialog box will appear. Try loading a file from disk and make some changes to it. Then, save the file. You should now have a functional simple text editor.
Deploying the Application
To deploy the application using ClickOnce, first build the MyEditor project (Build?>Build MyEditor) and then publish it (Build?>Publish MyEditor).
The Publish Wizard will appear (see Figure 5). You can publish (deploy) a Windows application through a disk, shared folder, FTP server, or Web server. Use the default HTTP method and click Next.
Click Next and then Finish to complete the publish process. Internet Explorer should now display a page similar to that shown in Figure 6. The URL shown is the URL that you will advertise to your users if you want them to install the application using ClickOnce. Users can merely click the Install button to install the application.
Because we have not verified the publisher of this application, users who attempt to download this sample will get a security warning (see Figure 7). Click Install on the dialog to continue.
To prevent your users from being getting the security prompt, a System Administrator can specify a ClickOnce deployment policy that defines a specific application publisher as a trusted source. On computers where this policy is deployed, permissions will automatically be granted and the user will not be prompted.
|Figure 7. Security Warning: If you haven’t defined your application publisher as a trusted source, your end users will get the security prompt shown.
If the application installs successfully, it will launch automatically. You can also launch the application by going to Start?>Programs?>
Configuring ClickOnce Security Settings using Code Access Security
By default, an application deployed by ClickOnce runs under Full Trust. You can verify the trust level for your applications by going to the Security tab of the project Properties window (see Figure 8).
|Figure 8. Full Trust: The default for ClickOnce applications is full trust.
Under Full Trust, the application has unrestricted access to resources such as files, registry, as well as network. This can be potentially dangerous as it opens the possibility of your code being exploited by malicious code. To prevent this, a good solution is to limit the permissions for your application to only what is necessary.
I’ll now modify the ClickOnce Security Permissions for the sample application to make it more secure. From the Security tab of the Properties window, check the option for “This is a partial trust application” and select the Local Intranet zone. Take note of the various permissions recommended. In particular, look out for the following permissions:
Table 1. Important Permission to Limit for Security
|Required for ?
|Displaying the Open and Save As dialog windows
|Performing file I/O (read/write)
|Connecting to the Internet. E.g. Accessing Web services
|Author’s Note: The Internet Zone contains much more restrictive permissions than the Local Intranet Zone.
Notice that for the FileDialogPermission, under the “Included” column, there is a green check icon (see Figure 9). This indicates that this permission is implicitly granted and the application can invoke the Open and Save As dialog windows under this security setting. However, for both the FileIOPermission and the WebPermission permissions, there is no check icon and the permission defaults to the Zone Default (which is Exclude).
You need not click on the Install button to re-install the application. By default, ClickOnce will check for updates every time an application is launched. So, launch the MyEditor application by going to Start?>Programs?>
You will be alerted that there is a new version of the application available (see Figure 11). Click OK to upgrade the application.
Back in Visual Studio 2005, if you set the FileIOPermission’s Settings to Include (see Figure 13) and republish the application, you will now be able to perform file I/O operations. Notice that the icon now changes to an exclamation mark inside a yellow triangle, signifying that this operation requires elevated permission to execute.
|Figure 15. Finely Tuned Security: You can fine-tuning the permission settings.
However, if the application tries to access a Web service hosted on another server, a security exception will be raised. To prevent this, just set the WebPermission permission to Include.
For some permissions, you can fine-tune the permissions assigned. For example, when you select the FileDialogPermission permission and click on Properties?, you can grant permission to the specific type of dialog boxes (see Figure 15).
Earlier in this article I showed that when you republish a modified application, the client will automatically detect the upgrade when the application launches. This is set in the Publish tab in the project properties window via the Updates? button (see Figure 16).
By default, every time you publish the application the Revision number increments by one (see Figure 18). For Major, Minor, or Build number, you need to set them explicitly.
Clicking on the Application Files? button (see Figure 19) will display a list of files that will be deployed to the client’s computer. If you are deploying databases using ClickOnce, be sure to set the correct value for the Copy to Output Directory property for the database. For example, consider the case where a user installs revision 1 of your application and populates the database with data. When you make changes to the application and republish the application, by default the database on the client would be overwritten by the original database. This is because the default value of the Copy to Output Directory property of the database is set to “Copy always”, resulting in the deployment of the original database every time the application is republished. A much safer way would be to set it to “Copy if newer” so that the database on the client computer is only overwritten if it is older than the republished database.
ClickOnce and Ready to Go
In this article, you have learned how to deploy a Windows application easily using the new ClickOnce deployment technology. Not only that, you have also seen how applications can be configured to update automatically. And in the last part of this article, I gave you a hearty look at how to configure the security settings of ClickOnce applications using Code Access Security.