No-Touch Deployment


In addition to letting you deploy WinForms controls, .NET also lets you use IE to deploy entire WinForms applications. This is a completely new feature for the Windows platform. You can best see its value by trying it:

  1. Using the New Project dialog, create a new Windows application and call it DeploymentFun.

  2. Feel free to drag and drop some controls from the Toolbox, but before going too far, compile your application.

  3. In the shell explorer, navigate to your DeploymentFun\bin folder and right-click on the Debug folder, choosing Properties.

  4. Choose Web Sharing and turn it on, using DeploymentFun as the name of the share. This will create a new Internet Information Server (IIS) Web application containing DeploymentFun.exe.

  5. Now surf to your WinForms app using Start Run and the following URL: http://localhost/DeploymentFun/DeploymentFun.exe.

  6. After basking in the glory of using no-touch deployment (NTD) to deploy a real Windows application over the Web without doing any setup, stop playing around and read the rest of this chapter!

Application Download

As a test of the no-touch deployment model for WinForms applications, I built a simple game, as shown in Figure 15.4. [4]

[4] Any similarity to any other very popular game that you may already be familiar with is strictly intentional.

Figure 15.4. The Game of Wahoo!

On the Web server, deployment of a .NET application is merely a matter of dropping the .exe file into a Web application directory so that the Web server can hand out the bits on demand. The .NET runtime is not required on the server, nor is Microsoft's Internet Information Server nor even Windows itself. On the client side, however, things are a bit more interesting. When you feed Internet Explorer an URL such as http://localhost/wahoo/wahoo.exe, it forms an HTTP request for the wahoo.exe file to be streamed back to the client:

  GET /wahoo.exe HTTP/1.1  Accept: */* Accept-Language: en-us Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Q312461; .NET CLR 1.0.3705) Host: localhost Connection: Keep-Alive 

The response from the server is just a stream of bytes:

  HTTP/1.1 200 OK  Server: Microsoft-IIS/5.1 Date: Fri, 01 Feb 2002 02:11:29 GMT Content-Type: application/octet-stream Accept-Ranges: bytes Last-Modified: Fri, 01 Feb 2002 01:41:16 GMT ETag: "50aae089c1aac11:916" Content-Length: 45056  <<stream of bytes from wahoo.exe>>  

In addition to the bytes themselves , the last modified date and time are cached by IE on the client side. This is used to form a request each subsequent time that the application is launched using the same URL:

  GET /wahoo.exe HTTP/1.1  Accept: */* Accept-Language: en-us Accept-Encoding: gzip, deflate  If-Modified-Since: Fri, 01 Feb 2002 01:41:16 GMT  If-None-Match: "50aae089c1aac11:916" User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Q312461; .NET CLR 1.0.3705) Host: localhost Connection: Keep-Alive 

The If-Modified-Since header is kept in IE's download cache and is sent back with each request. In this way, if the bits on the server haven't changed, the server can respond with a header that indicates that the cache is still good, reducing the payload that needs to be downloaded to the client:

  HTTP/1.1 304 Not Modified  Server: Microsoft-IIS/5.1 Date: Fri, 01 Feb 2002 02:42:03 GMT ETag: "a0fa92bc8aac11:916"  Content-Length: 0  

The bytes themselves are cached in two places: IE's download cache, managed by IE, and the .NET download cache , which is a cache for .NET assemblies (both .exe and .dll files) downloaded on demand. The contents of the .NET download cache can be examined using gacutil.exe /ldl and cleared using gacutil.exe /cdl. If, during your testing, you'd like to ensure that a download happens, make sure to clear IE's cache using the Internet control panel and clear .NET's cache using gacutil.

Versioning

While we're talking about caching and downloading the "latest version," you may be curious about how actual versions affect things. As you may know, you can tag a .NET assembly with a specific version using the AssemblyVersionAttribute: [5]

[5] NET versioning is discussed at length in Essential .NET (Addison-Wesley, 2003), by Don Box, with Chris Sells.

 // Strong naming is required when versioning [assembly: AssemblyKeyFileAttribute("wahoo.key")]  [assembly: AssemblyVersionAttribute("1.2.3.4")]  

With this in mind, you may wonder whether .NET versioning affects caching and downloading. It doessometimes.

When a request is formed for http://localhost/wahoo/wahoo.exe, the runtime doesn't have any idea which version we'd like, so it simply asks the Web server for the latest HTTP version as indicated by the If-Modified-Since header sent along with the HTTP request. If the runtime already has the latest HTTP version, no download needs to happen. However, if the server has a newer binary (based on the date/time stamp on the file)even if that binary is of a lower .NET version (based on the AssemblyVersionAttribute)the latest HTTP version will be downloaded. In other words, the .NET version plays no role in what constitutes the "latest version" of the application launched with an URL.

On the other handand this is the "sometimes" partany assembly can reference other assemblies, either implicitly as part of the manifest or explicitly via the Assembly.Load method. For example, wahoo.exe references wahooControl.dll. Whatever the .NET version is of wahooControl.dll that wahoo.exe compiles against will be the version that the assembly resolver (the part of the .NET runtime responsible for finding code) expects to find at run time. If that .NET version of wahooControl.dll is in the cache, the assembly resolver will not send a request to the Web server asking whether it has a newer .NET version. This means that if you'd like the client to have a newer .NET version of a referenced assembly, you must make sure that the Web server is serving up an updated EXE assembly that refers to the referenced assembly.

Related Files

As I just mentioned, assemblies can reference other assemblies. For example, an assembly may already be present in the Global Assembly Cache (GAC), the place where systemwide shared assemblies are kept in .NET. If an assembly is in the GAC, such as System.Windows.Forms.dll, then that's where the assembly will be loaded from. If the assembly is not in the GAC, the .NET download cache is checked. If the download cache doesn't contain the assembly, the assembly resolver goes back to the originating server using the application base (appbase) of the assembly. The appbase is the "directory" from which the initial assembly was loadedfor example, c:\wahoo or http://localhost/wahoo. The appbase is available using the GetData function of the currently executing application domain (appdomain) , which is the context under which all .NET code runs. [6] The appbase can be obtained for the appdomain in this way:

[6] For details of appdomains and appbases, you should read Essential .NET (Addison-Wesley, 2003), by Don Box, with Chris Sells.

 string appbase = AppDomain.CurrentDomain.BaseDirectory; 

For example, when wahoo.exe needs wahooControls.dll and it's not present in the GAC or the download cache, the assembly resolver will go back to the originating Web server, as you've seen. Referenced assemblies, however, are not the only files that the assembly resolver will look for when an executable is loaded. In fact, on my machine when I surf to the initial version of the signed wahoo.exe after the caches have been cleared, 35 requests are made for files, as shown in Table 15.3.

Table 15.3. Files Requested When Surfing to wahoo.exe

Request #

GET Request

1

/wahoo/wahoo.exe

2

/wahoo/wahoo.exe.config

3

/wahoo/WahooControl.DLL

4

/wahoo/en-US/Wahoo.resources.DLL

5

/wahoo/en-US/Wahoo.resources/Wahoo.resources.DLL

6

/wahoo/bin/en-US/Wahoo.resources.DLL

7

/wahoo/bin/en-US/Wahoo.resources/Wahoo.resources.DLL

8

/wahoo/en-US/Wahoo.resources.EXE

9

/wahoo/en-US/Wahoo.resources/Wahoo.resources.EXE

10

/wahoo/bin/en-US/Wahoo.resources.EXE

11

/wahoo/bin/en-US/Wahoo.resources/Wahoo.resources.EXE

12

/wahoo/en/Wahoo.resources.DLL

13

/wahoo/en/Wahoo.resources/Wahoo.resources.DLL

14

/wahoo/bin/en/Wahoo.resources.DLL

15

/wahoo/bin/en/Wahoo.resources/Wahoo.resources.DLL

16

/wahoo/en/Wahoo.resources.EXE

17

/wahoo/en/Wahoo.resources/Wahoo.resources.EXE

18

/wahoo/bin/en/Wahoo.resources.EXE

19

/wahoo/bin/en/Wahoo.resources/Wahoo.resources.EXE

20

/wahoo/en-US/Wahoo.resources.DLL

21

/wahoo/en-US/Wahoo.resources/Wahoo.resources.DLL

22

/wahoo/bin/en-US/Wahoo.resources.DLL

23

/wahoo/bin/en-US/Wahoo.resources/Wahoo.resources.DLL

24

/wahoo/en-US/Wahoo.resources.EXE

25

/wahoo/en-US/Wahoo.resources/Wahoo.resources.EXE

26

/wahoo/bin/en-US/Wahoo.resources.EXE

27

/wahoo/bin/en-US/Wahoo.resources/Wahoo.resources.EXE

28

/wahoo/en/Wahoo.resources.DLL

29

/wahoo/en/Wahoo.resources/Wahoo.resources.DLL

30

/wahoo/bin/en/Wahoo.resources.DLL

31

/wahoo/bin/en/Wahoo.resources/Wahoo.resources.DLL

32

/wahoo/en/Wahoo.resources.EXE

33

/wahoo/en/Wahoo.resources/Wahoo.resources.EXE

34

/wahoo/bin/en/Wahoo.resources.EXE

35

/wahoo/bin/en/Wahoo.resources/Wahoo.resources.EXE

The .config File

The first request in Table 15.3 makes sense because it's the assembly we asked for to begin with. The second request is for a .config file, which you may recall from Chapter 11: Applications and Settings. If you're serving your WinForms application from an IIS installation, you'll need to enable anonymous access to your .exe file's Web application. Also, if ASP.NET is installed on the server, you may need to override the default behavior in a virtual directory to disable any .config files being supplied. If you find that your application's .config is available on the server but is not being downloaded to the client, use the following settings in a web.config file at the base of the virtual directory:

 <configuration>   <system.web>  <!--   Remove the *.config handler so that we can serve up   *.exe.config files, but make it forbidden to serve up the   web.config file itself.   -->   <httpHandlers>   <remove verb="*" path="*.config" />   <add verb="*" path="web.config"   type="System.Web.HttpForbiddenHandler"/>   </httpHandlers>  </system.web> </configuration> 

These configuration settings remove the restriction on all .config files and reinstate it for only web.config files, which still need protection from download. Some versions of ASP.NET disable all .config files, whereas others don't, so if the <remove> element causes an error, you shouldn't need these extra settings in your web.config at all.

Resources

The third request in Table 15.3 is for the wahooControl.dll assembly that wahoo.exe references, as we expect. The next request is for a resources assembly called Wahoo.resources. You should recognize this request (and the rest of the requests) as made by the resource manager looking for localized resources, as discussed in Chapter 10: Resources. These requests are being made for the WahooControl object's background image, which is stored in the wahooControl assembly's resources.

On the local machine or a LAN, the localization probe performed by the resource manager is chewy goodness, but that's not necessarily so in a WAN environment. When the latest wahoo.exe and wahooControl.dll are already cached on my machine, I've seen these additional requests take more than 75 percent of the load time. These extra round-trips can make for a very poor user experience, especially when culture-neutral resources are the only resources in your application.

In this case, you have a couple of options. One option is to avoid using WinForms Designer to set properties that use resources. In this way, the Designer-generated code doesn't create a resource manager. Then, to load resources, you write the code yourself in a culture-neutral way:

 public MainForm() {   // Let the Designer-generated code run   InitializeComponent();  // Init culture-neutral properties   this.game.BackgroundImage =   new Bitmap(typeof(MainForm), "sblogo.gif");  } 

Loading resources manually is handy for resources that you know are culture-neutral and never want to localize, but it does mean giving up WinForms Designer for resource management. If you share my addiction to WYSIWYG form design, the resource manager supports an optimization that often makes this kind of handwritten code unnecessary. Recall NeutralResourcesLanguageAttribute from Chapter 10: Resources. This attribute marks the resources bundled in your assembly as culture-specific so that they will be found first without the round-trips to the Web server when launched from that culture:

 [assembly: NeutralResourcesLanguageAttribute("en-US")] 

This attribute reduces the number of requests from 34 to 2 when the assembly is launched from a machine with the culture of the assembly, thereby improving load times considerably. If you'd like to let the Designer generate the code and reduce round-trips for cultures other than the one in which you're writing the application, you can put zero-length files in the first places that the resource manager looks. For example, zero-length files on the server under the following names will be used for the English language and the US:

 en-US\assemName.resources.dll en\assemName.resources.dll 

The presence of zero-length files at the appropriate locations causes the resource manager to find the resource files it's looking for, even if they're empty. When it comes to resolving specific resources, zero-length files will cause an extra lookup by the resource manager for a culture- or language-specific resource, but if it's not found, the culture-neutral resources in the resolving assembly will be used in the normal way.

Working Offline

Of course, the ultimate reduction of requests is to use no requests at all. By putting IE into offline mode (via the File menu), surfing to an NTD application will work completely from the cache. A better model is to use the cache automatically if the client machine was not connected to the Internet or the server was unavailable, but, as of .NET 1.1, that feature is not part of the NTD implementation.



Windows Forms Programming in C#
Windows Forms Programming in C#
ISBN: 0321116208
EAN: 2147483647
Year: 2003
Pages: 136
Authors: Chris Sells

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net