SysInternal: WinDiag (Windows Memory Diagnostic)

Windows Memory Diagnostic

The Windows Memory Diagnostic tests the Random Access Memory (RAM) on your computer for errors. The diagnostic includes a comprehensive set of memory tests. If you are experiencing problems while running Windows, you can use the diagnostic to determine whether the problems are caused by failing hardware, such as RAM or the memory system of your motherboard. Windows Memory Diagnostic is designed to be easy and fast. On most configurations, you can download the diagnostic, read the documentation, run the test and complete the first test pass in less than 30 minutes.

To run Windows Memory Diagnostic, you must reboot your computer with the disk or CD-ROM on which you installed Windows Memory Diagnostic in the drive. After the reboot, Windows Memory Diagnostic will load and its interface will appear. After loading, the first test pass will begin, using the default standard test suite, and continue until complete, unless Windows Memory Diagnostic is either paused or exited. Once the first test pass is complete, Windows Memory Diagnostic will begin a second test pass using the same settings as before. Windows Memory Diagnostic will continue to run test passes until you exit.

Windows Memory Diagnostic User Guide
Download Windows Memory Diagnostic

.Net2.0: ClickOnce Deployment in .NET Framework 2.0

ClickOnce Deployment in .NET Framework 2.0
By Thiru Thangarathinam
Rating: 4.2 out of 5
Rate this article

· print this article

· email this article to a colleague

· suggest an article

It is very common among the developers of previous generations to choose web applications over rich Windows UIs because of the deployment challenges associated with deploying a Smart Client Windows Forms application. However with the release of Visual Studio 2005, Microsoft has released a new technology named ClickOnce that is designed to solve the deployment issues for a windows forms application. This new technology not only provides an easy application installation mechanism but also enables easy deployment of upgrades to existing applications. This article will demonstrate how to take advantage of the excellent features of the ClickOnce deployment technology by discussing examples on how to utilize this new feature.


Since the introduction of the powerful server side web technologies such as ASP, JSP, ASP.NET, developers have shown more interest in building web applications rather than in windows applications. The factors that attracted the developers toward web applications can be summarized as follows:

  • A web application is ubiquitous, making it accessible in all the places where an internet connection is available.
  • The second and most important factor is the deployment. With web applications, there is no need to deploy any software on the client side. All the client application needs is just the browser. This makes it possible for the developers to easily deploy updates to the existing web application without impacting the client machines.

If you talk to the developers, you will find that the main reason for preference for web applications over windows applications is the second point in the above list. Even though this is true with traditional applications, Microsoft is making every attempt to ensuring that windows applications can be deployed and updated with the same ease as the web applications. You can see proofs of this in the initial release of .NET Framework when Microsoft introduced the deployment of windows forms application through HTTP. Using this approach, you could simply use HREF HTML element to point to a managed executable (.exe). Then when you click on the HREF link, Internet Explorer can automatically download and install the executable on the client machine. Even though this approach sounds very promising, it also presents some interesting challenges. One of the most important challenges is the downloading of the updated code through the HTTP. Since this process was not transacted, it was possible for the application to be left in an inconsistent state. Moreover there was no way for you to specify if the application could work in offline mode apart from the traditional online mode. Combined with the operational mode issue, this approach also did not provide the ability to create shortcuts that can be used to launch the application. Even though this approach presented itself with a lot of issues, it could still be used in controlled environments. However for complex multi-assembly dependant windows forms applications, you needed a transacted and easily updateable way of deployment. This is exactly what the ClickOnce technology introduced with .NET Framework 2.0 provides. In this article, we will see how to effectively use this technology to deploy a windows form application.

How does ClickOnce Deployment Technology Work?

Before we look at an example, let us understand how this technology works.

  • You create a Windows forms application and use the Publish option to deploy the application onto any of the following locations: File System, Local Web Server, FTP Site, or a Remote Web Site.
  • Once the application is deployed onto the target location, the users of the application can browse to the publish.htm file and install the application onto their machine. Note that publish.htm file is the entry point for installing the application and this will be discussed in the later part of this article.
  • Once the user has installed the application, a shortcut icon will be added to the desktop and the application will also be listed in the Control Panel/Add Remove Programs.
  • When the user launches the application again, the manifest will contain all the information to decide if the application should go to the source location and check for updates to the original application. Let us say, for instance, a newer version of the application is available, it will be automatically downloaded and made available to the user. Note that when the new version is downloaded, it is performed in a transacted manner meaning that either the entire update is downloaded or nothing is downloaded. This will ensure that the application integrity is preserved.

Let us look at an example to understand this.

A Simple ClickOnce Deployment Example

Let us start by creating a simple Visual C# Windows forms application named ClickOnceDemo using Visual Studio 2005. Once the project is created, place a command button on the form and double click on the command button and modify its code to look like the following.

private void btnClick_Click(object sender, EventArgs e)

If you run the ClickOnceDemo application and click on the button, you will see an output that is somewhat similar to the following depending on the location of your project folder.

Now that we have created the application, let us publish it. But before we do that, let us look at some of the properties associated with publishing of the forms application. Right click on the ClickOnceDemo project from the solution explorer and select Properties from the context menu. You should see the following dialog box being displayed.

The Publish tab in the Project Properties dialog box shown in the above screenshot provides a number of options for configuring publish related settings. Let us look at each one of these options in detail.

At the top of the properties page is the Publishing Location dropdown box that allows you to specify the location in which the application will be published. When you click on the ... button right next to the dropdown, it brings up the following window wherein you can specify the target virtual directory for publishing.

Using the Publish properties dialog box, you can also specify if the application is available only in online mode or in both online and offline modes. This option is available in the Install Mode and Settings panel. This panel also contains options that let you specify the prerequisites for your windows forms application. To specify this, click on the Prerequisites... command button and you will see the following dialog box.

By default, the .NET Framework 2.0 option will be checked and you can choose any of the remaining options depending on your application requirements.

Right below the Prerequisities option, there is a command button named Updates... that lets you configure the manner and timing in which the updates to the application will be delivered to the client machine. Clicking on the Updates... button will result in the following dialog box.

As you can see from the above dialog box, you have a number of options that allow you to exercise finer level of control over the application updates.

Right below the Updates button is the Options... button that brings up the following dialog box when clicked.

Using the Publish options, you can not only indicate the language in which the application will be published but also specify the Start menu shortcut name. Once you publish this application to the target location, the root directory of the application install will contain a file called publish.htm, which you can use to launch the application on the client machine. By default, the name of the file is set to publish.htm and can be modified using the above dialog box.

Now that we have a understanding of the properties in a general sense, let us see how to publish the application.

Publishing the Application

To publish the application, start by selecting Publish ClickOnceDemo from the Publish menu. This will bring up the first step in the publish wizard, which is shown below.

In the above dialog box, you can specify the location where you want to publish the application. The locations to which you can deploy the application are: File System, Local IIS, FTP Sites, and Remote Sites. For the purposes of this example, let us leave the default value of http://localhost/ClickOnceDemo. Clicking Next in the above dialog box will result in the following dialog box, which allows you to specify the modes in which the application will be available.

The default value in the above screen is dependant on the value set in the Install Mode Settings panel of the Publish properties dialog box. Then click Next and you will be asked to specify the key file used for strongly signing the application. Since we haven’t created a key file yet, select the option that says "<Create new strong name key>" as shown in the following screenshot.

Clicking Next in the above dialog box will bring up the Confirm dialog box, wherein you can hit Finish to complete the publishing.

If you hit Finish in the above dialog box, Visual Studio will build the project, publish the application to the ClickOnceDemo folder under the default web site, and then automatically bring up the publish.htm file in the browser. Before we look at the publish.htm file, let us examine the files generated by the wizard. Navigate to the ClickOnceDemo folder in the default web site through the Windows explorer. You will see the following screenshot.

The ClickOnceDemo_1.0.0.0 folder is the one that contains the .exe file and the corresponding manifest files. Since we mentioned that the prerequisites (specified through the Publish properties dialog box in the earlier section) for this application is .NET Framework 2.0, Visual Studio automatically created a folder named dotnetfx that contained the executable for installing the .NET Framework 2.0. Now that we have had a look at the files created by the wizard, let us turn our focus to the publish.htm that provides a means for launching the application.

As you can see from the above screenshot, this html page enables you to install the ClickOnceDemo application through a hyperlink. Click the Install ClickOnceDemo hyperlink to install the application. You will be presented with the following dialog box, wherein you can just hit Install to continue the installation.

Once the application is installed, it will automatically execute the application and bring up the form. Click on the command and you will see an output that is somewhat similar to the following.

As you can see, now the path displayed the message box is different than the previously generated message box. This is because of the fact that the application is now downloaded and locally cached in the folder shown in the above message box. If you navigate to that folder from windows explorer, you will see folders as listed in the following screenshot. These folders contain files such as manifests, and the actual executable itself and so on.

You will also notice the following changes as a result of the installation.

  • An icon is added to the Start menu
  • An entry is added in Control Panel -> Add/Remove Programs.

From this point onwards, you can launch the application through the shortcut in the Start -> Programs menu. From Add/Remove Programs, you can either completely uninstall the application or revert to the previous version, if there was one.


The features of ClickOnce we have seen in this article are only the tip of the iceberg and it offers many more benefits. However, the key motivation for using ClickOnce is the ease of deployment, installation, and versioning for your Windows Forms applications.

C++/Unicode: Notes on Strings in C and C++ Programs (Unicode)

Notes on Strings in C and C++ Programs

Be aware that there are considerations when you prepare an application for an international market. Windows NT and Windows 2000 support the Unicode character set, which uses two bytes to represent a character. Windows 98 and Windows 95 use either the one-byte ANSI character set for many Western languages or the double byte character set (DBCS), also known as the multi-byte character set (MBCS), for languages that require multiple bytes to represent a single character.

To make code as portable as possible, you should use the Microsoft-specific generic-text mappings defined in Microsoft Visual C++. Generic-text mappings include definitions for various library functions so that they can be mapped at compile time to either the single-byte, double-byte, or wide-character (Unicode) variant of the function. Thus, _tprintf becomes wprint when the program is compiled with _UNICODE defined. This mapping extends to data types as well, so _TCHAR chVarible would declare chVariable to be a char (single-byte character) under ANSI, and a wchar_t (two-byte character) when compiled with _UNICODE defined. The underscore character (_) indicates that the function, macro, or datatype is not part of the Standard ANSI C/C++ language definition. Microsoft Visual C++ prefixes _t to all generic text macros.

To complicate matters, COM strings, including all ADSI and Active Directory strings, must be Unicode strings. That means that even if you compile the program on Windows 98 using the ANSI character set, you need to specify that the strings passed to and returned from COM functions are Unicode. For string literals in C and C++, you do this by inserting the letter L before the string. For example, L"This is a wide string" would tell the compiler to generate a Unicode string regardless of whether _UNICODE is defined.

C#: Migrating 32-bit Managed Code to 64-bit

Migrating 32-bit Managed Code to 64-bit

Microsoft Corporation

Updated May 2005

Applies to:
Microsoft .NET
Microsoft .NET Framework 2.0

Summary: Find out what is involved in migrating 32-bit managed applications to 64-bit, issues that can impact migration, and the tools that are available to assist you. (17 printed pages)


Managed Code in a 32-bit Environment
Enter the CLR for the 64-bit Environment
Migration and Platform Invoke
Migration and COM Interoperability
Migration and Unsafe Code
Migration and Marshaling
Migration and Serialization


This whitepaper discusses:

· What is involved in migrating managed applications from 32-bit to 64-bit

· The issues that can impact migration

· What tools are available to assist you

This information is not meant to be prescriptive; rather it is intended to familiarize you with the different areas that are susceptible to issues during the process of migrating to 64-bit. At this point there is no specific "cookbook" of steps that you can follow and insure your code will work on 64-bit. The information contained in this whitepaper will familiarize you with the different issues and what should be reviewed.

As you will soon see, if your managed assembly is not 100% type safe code you will need to review your application and its dependencies to determine your issues with migrating to 64-bit. Many of the items you will read about in the next sections can be addressed through programming changes. In a number of cases you will also need to set aside time to update your code in order to run correctly in both 32-bit and 64-bit environments, if you want it to run in both.

Microsoft .NET is a set of software technologies for connecting information, people, systems, and devices. Since its 1.0 release in 2002, organizations have succeeded in deploying .NET-based solutions whether built in-house, by independent software vendors (ISVs), or some combination. There are several types of .NET applications that push the limits of the 32-bit environment. These challenges include, but are not limited to, the need for more real addressable memory and the need for increased floating-point performance. x64 and Itanium offer better performance for floating-point operations than you can get on x86. However, it is also possible that the results you get on x64 or Itanium will be different from the results you get on x86. The 64-bit platform aims to help address these issues.

With the release of .NET Framework version 2.0, Microsoft includes support for managed code running on the x64 and Itanium 64-bit platforms.

Managed code is simply "code" that provides enough information to allow the .NET Common Language Runtime (CLR) to provide a set of core services, including:

· Self description of code and data through metadata

· Stack walking

· Security

· Garbage collection

· Just-in-Time compilation

In addition to managed code there are several other definitions that are important to understand as you investigate the migration issues.

Managed Data—data that is allocated on the managed heap and collected via garbage collection.

Assembly—the unit of deployment that allows the CLR to fully understand the contents of an application and to enforce the versioning and dependency rules defined by the application.

Type safe code—code that uses only managed data, and no unverifiable data types or unsupported data type conversion/coercion operations (that is, non-discriminated unions or structure/interface pointers). C#, Visual Basic .NET, and Visual C++ code compiled with /clr:safe generate type safe code.

Unsafe Code—code that is permitted to perform such lower-level operations as declaring and operating on pointers, performing conversions between pointers and integral types, and taking the address of variables. Such operations permit interfacing with the underlying operating system, accessing a memory-mapped device, or implementing a time-critical algorithm. Native code is unsafe.

Managed Code in a 32-bit Environment

To understand the complexities involved with migrating managed code to the 64-bit environment, let’s review how managed code is executed in a 32-bit environment.

When an application, managed or unmanaged, is selected to be executed, the Windows loader is invoked and is responsible for deciding how to load and then execute the application. Part of this process involves peeking inside of the executable’s portable execution (PE) header to determine if the CLR is required. As you might have already guessed, there are flags in the PE that indicate managed code. In this case the Windows loader starts the CLR that is then responsible for loading and executing the managed application. (This is a simplified description of the process as there are many steps involved, including determining which version of the CLR to execute, setting up the AppDomain ‘sandbox’, etc.)


As the managed application runs, it can (assuming appropriate security permissions) interact with native APIs (including the Win32 API) and COM objects through the CLR interoperability capabilities. Whether calling a native platform API, making a COM request, or marshaling a structure, when running completely within the 32-bit environment the developer is isolated from having to think about data type sizes and data alignment.

When considering the migration to 64-bit it will be essential to research what dependencies your application has.

Enter the CLR for the 64-bit Environment

In order for managed code to execute in the 64-bit environment consistent with the 32-bit environment, the .NET team developed the Common Language Runtime (CLR) for the Itanium and x64 64-bit systems. The CLR had to strictly comply with the rules of the Common Language Infrastructure (CLI) and Common Language Type System to insure that code written in any of the .NET languages would be able to interoperate as they do in the 32-bit environment. In addition, the following is a list of some of the other pieces that also had to ported and/or developed for the 64-bit environment:

· Base class libraries (System.*)

· Just-In-Time compiler

· Debugging support

· .NET Framework SDK

64-bit managed code support

The .NET Framework version 2.0 supports the Itanium and x64 64-bit processors running:

· Windows Server 2003 SP1

· Future Windows 64 bit client releases

(You cannot install the .NET Framework version 2.0 on Windows 2000. Output files produced using the .NET Framework versions 1.0 and 1.1 will run under WOW64 on a 64-bit operating system.)

When installing the .NET Framework version 2.0 on the 64-bit platform, you are not only installing all of the necessary infrastructure to execute your managed code in 64-bit mode, but you are installing the necessary infrastructure for your managed code to run in the Windows-on-Windows subsystem, or WoW64 (32-bit mode).

A simple 64-bit migration

Consider a .NET application that is 100% type safe code. In this scenario it is possible to take your .NET executable that you run on your 32-bit machine and move it to the 64-bit system and have it run successfully. Why does this work? Since the assembly is 100% type safe we know that there are no dependencies on native code or COM objects and that there is no ‘unsafe’ code which means that the application runs entirely under the control of the CLR. The CLR guarantees that while the binary code that is generated as the result of Just-in-time (JIT) compilation will be different between 32-bit and 64-bit, the code that executes will both be semantically the same. (You cannot install the .NET Framework version 2.0 on Windows 2000. Output files produced using .NET Framework versions 1.0 and 1.1 will run under WOW64 on a 64-bit operating system.)

In reality the previous scenario is a bit more complicated from the perspective of getting the managed application loaded. As discussed in the previous section, the Windows loader is responsible for deciding how to load and execute the application. However, unlike the 32-bit environment, running on a 64-bit Windows platform means that there are two (2) environments where the application could be executed, either in the native 64-bit mode or in WoW64.

The Windows loader now has to make decisions based on what it discovers in the PE header. As you might have guessed there are settable flags in the managed code that assist with this process. (See corflags.exe to display the settings in a PE.) The following list represents information that is found in the PE that aids in the decision making process.

· 64-bit—denotes that the developer has built the assembly specifically targeting a 64-bit process.

· 32-bit—denotes that the developer has built the assembly specifically targeting a 32-bit process. In this instance the assembly will run in WoW64.

· Agnostic—denotes that the developer built the assembly with Visual Studio 2005, code-named "Whidbey". or later tools and that the assembly can run in either 64-bit or 32-bit mode. In this case, the 64-bit Windows loader will run the assembly in 64-bit.

· Legacy—denotes that the tools that built the assembly were "pre-Whidbey". In this particular case the assembly will be run in WoW64.

Note There is also information in the PE that tells the Windows loader if the assembly is targeted for a specific architecture. This additional information ensures that assemblies targeted for a particular architecture are not loaded in a different one.

The C#, Visual Basic .NET, and C++ Whidbey compilers let you set the appropriate flags in the PE header. For example, C# and THIRD have a /platform:{anycpu, x86, Itanium, x64} compiler option.

Note While it is technically possible to modify the flags in the PE header of an assembly after it has been compiled, Microsoft does not recommend doing this.

If you are curious to know how these flags are set on a managed assembly, you can run the ILDASM utility provided in the .NET Framework SDK. The following illustration shows a "legacy" application.

Keep in mind that a developer marking an assembly as Win64 determined that all dependencies of the application would execute in 64-bit mode. A 64-bit process cannot use a 32-bit component in process (and a 32-bit process cannot load a 64-bit component in process). Keep in mind that the ability for the system to load the assembly into a 64-bit process does not automatically mean that it will execute correctly.

So, we now know that an application comprised of managed code that is 100% type safe can be copied (or xcopy deploy it) to a 64-bit platform and have it JIT and run successfully with .NET in 64-bit mode.

However, we often see situations that aren’t ideal, and that brings us to the main focus of this paper, which is to increase awareness of the issues related to migrating.

You can have an application that isn’t 100% type safe and that is still able to run successfully in 64-bit under .NET. It will be important for you to look at your application carefully, keeping in mind the potential issues discussed in the following sections and make the determination of whether you can or cannot run successfully in 64-bit.

Migration and Platform Invoke

Making use of the platform invoke (or p/invoke) capabilities of .NET refers to managed code that is making calls to non-managed, or native, code. In a typical scenario this native code is a dynamic link library (DLL) that is either part of the system (Windows API, etc.), part of your application, or a third-party library.

Using non-managed code does not mean explicitly that a migration to 64-bit will have issues; rather it should be considered an indicator that additional investigation is required.

Data types in Windows

Every application and every operating system has an abstract data model. Many applications do not explicitly expose this data model, but the model guides the way in which the application’s code is written. In the 32-bit programming model (known as the ILP32 model), integer, long, and pointer data types are 32 bits in length. Most developers have used this model without realizing it.

In 64-bit Microsoft Windows, this assumption of parity in data type sizes is invalid. Making all data types 64 bits in length would waste space, because most applications do not need the increased size. However, applications do need pointers to 64-bit data, and they need the ability to have 64-bit data types in selected cases. These considerations led the Windows team to select an abstract data model called LLP64 (or P64). In the LLP64 data model, only pointers expand to 64 bits; all other basic data types (integer and long) remain 32 bits in length.

The .NET CLR for 64-bit platforms uses the same LLP64 abstract data model. In .NET there is an integral data type, not widely known, that is specifically designated to hold ‘pointer’ information: IntPtr whose size is dependent on the platform (e.g., 32-bit or 64-bit) it is running on. Consider the following code snippet:



public void SizeOfIntPtr() {

Console.WriteLine( "SizeOf IntPtr is: {0}", IntPtr.Size );


When run on a 32-bit platform you will get the following output on the console:


SizeOf IntPtr is: 4

On a 64-bit platform you will get the following output on the console:


SizeOf IntPtr is: 8

Note If you want to check at runtime whether or not you are running in a 64-bit environment, you can use the IntPtr.Size as one way to make this determination.

Migration considerations

When migrating managed applications that use p/invoke, consider the following items:

· Availability of a 64-bit version of the DLL

· Use of data types


One of the first things that needs to be determined is whether the non-managed code that your application has a dependency on is available for 64-bit.

If this code was developed in-house, then your ability for success is increased. Of course, you will still need to allocate resources to port the non-managed code to 64-bit along with appropriate resources for testing, quality assurance, etc. (This whitepaper isn’t making recommendations about development processes; rather, it is trying to point out that resources may need to be allocated to tasks to port code.)

If this code is from a third party, you will need to investigate whether this third party already has the code available for 64-bit and whether the third party would be willing to make it available.

The higher risk issue will arise if the third party no longer provides support for this code or if the third party is not willing to do the work. These cases necessitate additional research into available libraries that do similar functionality, whether the third party will let the customer do the port themselves, etc.

It is important to keep in mind that a 64-bit version of the dependent code may have altered interface signatures that may mean additional development work and to resolve differences between the 32-bit and 64-bit versions of the application.

Data types

Using p/invoke requires that the code developed in .NET declare a prototype of the method that the managed code is targeting. Given the following C declaration:



typedef void * HANDLE

HANDLE GetData();

Examples of prototyped methods are shown below:



[DllImport( "sampleDLL",
CallingConvention=CallingConvention.Cdecl )]

public static extern int DoWork( int x, int y );

[DllImport( "sampleDLL",
CallingConvention=CallingConvention.Cdecl )]

public unsafe static extern int GetData();

Let’s review these examples with an eye towards 64-bit migration issues:

The first example calls the method DoWork passing in two (2) 32-bit integers and we expect a 32-bit integer to be returned. Even though we are running on a 64-bit platform, an integer is still 32 bits. There is nothing in this particular example that should hinder our migration efforts.

The second example requires some changes to the code to successfully run in 64-bit. What we are doing here is calling the method GetData and declared that we are expecting an integer to be returned, but where the function actually returns an int pointer. Herein lies our problem: remember that integers are 32 bits but in 64-bit pointers are 8 bytes. As it turns out, quite a bit of code in the 32-bit world was written assuming that a pointer and an integer were the same length, 4 bytes. In the 64-bit world this is no longer true.

In this last case the problem can be resolved by changing the method declaration to use an IntPtr in place of the int.


public unsafe static extern IntPtr GetData();

Making this change will work in both the 32-bit and 64-bit environments. Remember, IntPtr is platform-specific.

Using p/invoke in your managed application does not mean that migrating to the 64-bit platform will not be possible. Nor does it mean that there will be problems. What it does mean is that you must review the dependencies on non-managed code that your managed application has, and determine if there will be any issues.

Migration and COM Interoperability

COM interoperability is an assumed capability of the .NET platform. Like the previous discussion on platform invoke, making use of COM interoperability means that managed code is making calls to non-managed code. However, unlike platform invoke, COM interoperability also means having the ability for non-managed code to call managed code as if it were a COM component.

Once again, using non-managed COM code does not mean that a migration to 64-bit will have problems; rather it should be considered an indicator that additional investigation is required.

Migration considerations

It is important to understand that with the release of .NET Framework version 2.0 there is no support for inter-architecture interoperability. To be more succinct, you cannot make use of COM interoperability between 32-bit and 64-bit in the same process. But you can make use of COM interoperability between 32-bit and 64-bit if you have an out-of-process COM server. If you cannot use an out-of-process COM server, you will want to mark your managed assembly as Win32 rather than Win64 or Agnostic in order to have your program run in WoW64 so that it can interoperate with the 32-bit COM object.

The following is a discussion of the different considerations that must be given to making use of COM interoperability where managed code makes COM calls in a 64-bit environment. Specifically,

· Availability of a 64-bit version of the DLL

· Use of data types

· Type libraries


The discussion in the p/invoke section regarding availability of a 64-bit version of the dependent code is relevant to this section as well.

Data types

The discussion in the p/invoke section regarding data types of a 64-bit version of the dependent code is relevant to this section as well.

Type libraries

Unlike assemblies, type libraries cannot be marked as ‘neutral’; they must be marked as either Win32 or Win64. In addition, the type library must be registered for each environment in which the COM will run. Use tlbimp.exe to generate a 32-bit or 64-bit assembly from a type library.

Using COM interoperability in your managed application does not mean that migrating to the 64-bit platform will not be possible. Nor does it mean that there will be problems. What it does mean is that you must review the dependencies your managed application has and determine if there will be any issues.

Migration and Unsafe Code

The core C# language differs notably from C and C++ in its omission of pointers as a data type. Instead, C# provides references and the ability to create objects that are managed by a garbage collector. In the core C# language it is simply not possible to have an uninitialized variable, a "dangling" pointer, or an expression that indexes an array beyond its bounds. Whole categories of bugs that routinely plague C and C++ programs are thus eliminated.

While practically every pointer type construct in C or C++ has a reference type counterpart in C#, there are situations where access to pointer types becomes a necessity. For example, interfacing with the underlying operating system, accessing a memory-mapped device, or implementing a time-critical algorithm may not be possible or practical without access to pointers. To address this need, C# provides the ability to write unsafe code.

In unsafe code it is possible to declare and operate on pointers, to perform conversions between pointers and integral types, to take the address of variables, and so forth. In a sense, writing unsafe code is much like writing C code within a C# program.

Unsafe code is in fact a "safe" feature from the perspective of both developers and users. Unsafe code must be clearly marked with the modifier unsafe, so developers can’t possibly use unsafe features accidentally.

Migration considerations

In order to discuss the potential issues with unsafe code let’s explore the following example. Our managed code makes calls to an unmanaged DLL. In particular, there is a method called GetDataBuffer that returns 100 items (for this example we are returning a fixed number of items). Each of these items consists of an integer and a pointer. The sample code below is an excerpt from the managed code showing the unsafe function responsible for handling this returned data.



public unsafe int UnsafeFn() {

IntPtr * inputBuffer = sampleDLL.GetDataBuffer();

IntPtr * ptr = inputBuffer;

int result = 0;

for ( int idx = 0; idx < 100; idx ++ ) {

// Add ‘int’ from DLL to our result

result = result + ((int) *ptr);

// Increment pointer over int (

ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( int ) );

// Increment pointer over pointer (

ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( int ) );


return result;


Note This particular example could have been accomplished without the use of unsafe code. More specifically, there are other techniques such as marshaling that could have been used. But for this purpose we are using unsafe code.

The UnsafeFn loops through the 100 items and sums the integer data. As we are walking through a buffer of data, the code needs to step over both the integer and the pointer. In the 32-bit environment this code works fine. However, as we’ve previously discussed, pointers are 8 bytes in the 64-bit environment and therefore the code segment (shown below) will not work correctly, as it is making use of a common programming technique, e.g., treating a pointer as equivalent to an integer.


// Increment pointer over pointer (

ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( int ) );

In order for this code to work in both the 32-bit and 64-bit environment it would be necessary to alter the code to the following.


// Increment pointer over pointer (

ptr = (IntPtr*)( ( (byte *) ptr ) + sizeof( IntPtr ) );

As we’ve just seen, there are instances where using unsafe code is necessary. In most cases it is required as a result of the managed code’s dependency on some other interface. Regardless of the reasons unsafe code exists, it has to be reviewed as part of the migration process.

The example we used above is relatively simple and the fix to make the program work in 64-bit was straightforward. Clearly there are many examples of unsafe code that are more complex. Some will require deep review and perhaps stepping back and rethinking the approach the managed code is using.

To repeat what you’ve already read—using unsafe code in your managed application does not mean that migrating to the 64-bit platform will not be possible. Nor does it mean that there will be problems. What it does mean is that you must review all of the unsafe code your managed application has and determine if there will be any issues.

Migration and Marshaling

Marshaling provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks, and converting managed to unmanaged types, as well as other miscellaneous methods used when interacting with unmanaged code.

Marshaling is manifested through the .NET Marshal class. The static or shared in Visual Basic, methods defined on the Marshal class are essential to working with unmanaged data. Advanced developers building custom marshalers who need to provide a bridge between the managed and unmanaged programming models typically use most of the methods defined.

Migration considerations

Marshaling poses some of the more complex challenges associated with the migration of applications to 64-bit. Given the nature of what the developer is trying to accomplish with marshaling, namely transferring structured information to, from, or to-and-from managed and unmanaged code, we will see that we are providing information, sometimes low-level, to assist the system.

In terms of layout there are two specific declarations that can be made by the developer; these declarations are typically made through the use of coding attributes.


Let’s review the definition as supplied in the .NET Framework SDK Help:

"The members of the object are laid out sequentially, in the order in which they appear when exported to unmanaged memory. The members are laid out according to the packing specified in StructLayoutAttribute.Pack, and can be noncontiguous."

We are being told that the layout is specific to the order in which it is defined. Then, all we need to do is make sure that the managed and unmanaged declarations are similar. But, we are also being told that packing is a critical ingredient, too. At this point you won’t be surprised to learn that without explicit intervention by the developer, there is a default pack value. As you might have already guessed, the default pack value is not the same between 32-bit and 64-bit systems.

The statement in the definition regarding noncontiguous members is referring to the fact that, because there are default pack sizes, data that is laid out in memory may not be at byte 0, byte 1, byte2, etc. Rather, the firstmember will be at byte 0, but the second member might be at byte 4. The system does this default packing to allow the machine to get access to members without having to deal with misalignment problems.

Here is an area that we need to pay close attention to packing, and at the same time, try to let the system act in its preferred mode.

The following is an example of a structure as defined in managed code, as well as the corresponding structure defined in unmanaged code. You should take careful note of how this example demonstrates setting the pack value in both environments.




public class XYZ {

public byte arraysize = unchecked((byte)-1);

[MarshalAs(UnmanagedType.ByValArray, SizeConst=52)]

public int[] padding = new int[13];


[unmanaged c++]

#pragma pack(1)

typedef struct{

BYTE arraysize; // = (byte)-1;

int padding[13];

} XYZ;


Let’s review the definition as supplied in the .NET FrameworkSDK Help:

"The precise position of each member of an object in unmanaged memory is explicitly controlled. Each member must use the FieldOffsetAttribute to indicate the position of that field within the type."

We are being told here that the developer will be providing exact offsets to aid in the marshaling of information. So, it is essential that the developer correctly specify the information in the FieldOffset attribute.

So, where are the potential problems? Keeping in mind that the field offsets are defined knowing the size of the proceeding data member size, it is important to remember that not all data type sizes are equal between 32-bit and 64-bit. Specifically, pointers are either 4 or 8 bytes in length.

We now have a case where we may have to update our managed source code to target the specific environments. The example below shows a structure that includes a pointer. Even though we’ve made the pointer an IntPtr there is still a difference when moving to 64-bit.




internal struct FooValue {

[FieldOffset(0)] public int dwType;

[FieldOffset(4)] public IntPtr pType;

[FieldOffset(8)] public int typeValue;


For 64-bit we have to adjust the field offset for the last data member in the structure as it really begins at offset 12 rather than 8.




internal struct FooValue {

[FieldOffset(0)] public int dwType;

[FieldOffset(4)] public IntPtr pType;

[FieldOffset(12)] public int typeValue;


The use of marshaling is a reality when complex interoperability between managed and unmanaged code is required. Making use of this powerful capability is not an indicator that you can migrate your 32-bit application to the 64-bit environment. However, because of the complexities associated with using marshaling, this is an area where careful attention to detail is required.

Analysis of your code will indicate whether separate binaries are required for each of the platforms and whether you will also have to make modifications to your unmanaged code to address issues like packing.

Migration and Serialization

Serialization is the process of converting the state of an object into a form that can be persisted or transported. The complement of serialization is deserialization, which converts a stream into an object. Together, these processes allow data to be easily stored and transferred.

The .NET Framework features two serializing technologies:

· Binary serialization preserves type fidelity, which is useful for preserving the state of an object between different invocations of an application. For example, you can share an object between different applications by serializing it to the Clipboard. You can serialize an object to a stream, to a disk, to memory, over the network, and so forth. .NET Remoting uses serialization to pass objects "by value" from one computer or application domain to another.

· XML serialization serializes only public properties and fields and does not preserve type fidelity. This is useful when you want to provide or consume data without restricting the application that uses the data. Because XML is an open standard, it is an attractive choice for sharing data across the Web. SOAP is likewise an open standard, which makes it an attractive choice.

Migration considerations

When we think about serialization we need to keep in mind what we are trying to achieve. One question to keep in mind as you migrate to 64 bit is whether you intend to share serialized information between the different platforms. In other words, will the 64-bit managed application read (or deserialize) information stored by a 32-bit managed application.

Your answer will help drive the complexity of your solution.

· You may want to write your own serialization routines to account for the platforms.

· You may want to restrict the sharing of information, while still allowing each platform to read and write its own data.

· You may want to revisit what you are serializing and make alterations to help avoid some of the problems.

So after all that, what are the considerations with respect to serialization?

· IntPtr is either 4 or 8 bytes in length depending on the platform. If you serialize the information then you are writing platform-specific data to the output. This means that you can and will experience problems if you attempt to share this information.

If you consider our discussion in the previous section about marshaling and offsets, you might come up with a question or two about how serialization addresses packing information. For binary serialization .NET internally uses the correct unaligned access to serialization stream by using byte based reads and correctly handling the data.

As we’ve just seen, the use of serialization does not prevent migration to 64-bit. If you use XML serialization you have to convert from and to native managed types during the serialization process, isolating you from the differences between the platforms. Using binary serialization provides you with a richer solution but creates the situation where decisions need to be made regarding how the different platforms share serialized information.


Migration to 64-bit is coming and Microsoft has been working to make the transition from 32-bit managed applications to 64-bit as simple as possible.

However, it is unrealistic to assume that one can just run 32-bit code in a 64-bit environment and have it run without looking at what you are migrating.

As mentioned earlier, if you have 100% type safe managed code then you really can just copy it to the 64-bit platform and run it successfully under the 64-bit CLR.

But more than likely the managed application will be involved with any or all of the following:

· Invoking platform APIs via p/invoke

· Invoking COM objects

· Making use of unsafe code

· Using marshaling as a mechanism for sharing information

· Using serialization as a way of persisting state

Regardless of which of these things your application is doing it is going to be important to do your homework and investigate what your code is doing and what dependencies you have. Once you do this homework you will have to look at your choices to do any or all of the following:

· Migrate the code with no changes.

· Make changes to your code to handle 64-bit pointers correctly.

· Work with other vendors, etc., to provide 64-bit versions of their products.

· Make changes to your logic to handle marshaling and/or serialization.

There may be cases where you make the decision either not to migrate the managed code to 64-bit, in which case you have the option to mark your assemblies so that the Windows loader can do the right thing at start up. Keep in mind that downstream dependencies have a direct impact on the overall application.


You should also be aware of the tools that are available to assist you in your migration.

Today Microsoft has a tool called FxCop which is a code analysis tool that checks .NET managed code assemblies for conformance to the Microsoft .NET Framework Design Guidelines. It uses reflection, MSIL parsing, and call graph analysis to inspect assemblies for more than 200 defects in the following areas: naming conventions, library design, localization, security, and performance. FxCop includes both GUI and command-line versions of the tool, as well as an SDK, to create your own rules. For more information, refer to the FxCop Web site. Microsoft is in the process of developing additional FxCop rules that will provide you information to assist you in your migration efforts.

There area also managed library functions to assist you at runtime to determine what environment you are running in.

· System.IntPtr.Size—to determine if you are running in 32-bit or 64-bit mode

· System.Reflection.Module.GetPEKind—to programmatically query an .exe or .dll to see if it is meant to run only on a specific platform or under WOW64

There is no specific set of procedures to address all of the challenges that you could run into. This whitepaper is intended to raise your awareness to these challenges and present you with possible alternatives

ClickOnce: Microsoft ClickOnce Technology // Contains details about click once technology. Visist the site. It also contains Differences between ClickOnce and Windows Installer (MSI), Choosing Between ClickOnce and Windows Installer, ClickOnce Presentations at PDC 2003 etc.

Microsoft ClickOnce Technology

See also:

ClickOnce is a technology that allows developers to write Windows Forms applications that utilize the powerful features of the client, yet are as hassle-free to deploy and update as a Web page. Here is a list of some introductory articles and webcasts. Links to additional articles and related blogs can be found below.

Books about ClickOnce

ClickOnce Tools and Samples

"dasBlonde" ClickOnce Samples

A package of samples that show how to detect a ClickOnce application from one that is not, along with other important states such as IsNetworkDeployed, detecting first run ever versus first run since last update, using the data directory or the isolated storage for local user storage, how to use a custom setup project (MSI) that deploys a GAC dependency for a ClickOnce application, as a bootstrapped MSI, how to download of required files on demand, manually detecting updates, and more. These samples can be found at "dasBlonde", the blog of Michéle Leroux Bustamante.

Visit Web Site

Bootstrapper Manifest Generator

The Bootstrapper in Visual Studio 2005 allows developers to add components to be redistributed along with their applications, allowing a single starting point to install applications and their prerequisites. For example, users can now run a single setup.exe that will install the .NET Frameworks, SQL Server Express, and your application over the web, from a CD, or from a UNC path. A bootstrapper is the only way to deploy prerequisites for a ClickOnce setup. This tool makes it much easier to add your own prerequisites to the bootstrapper.

Visit Web Site


ClickOnceMore is a commercial tool from Red Sky Software

ClickOnceMore is an easy to use ClickOnce application that assists .Net developers in creating the manifest files necessary for an effective ClickOnce deployment.

Visit Web Site

Known Problems with ClickOnce

Nothing happens when you try to install the WinForms app from the auto-generated PUBLISH.HTM within Internet Explorer
This can be caused by a iexplore.exe.config file in the IE directory, containing
<supportedRuntime version="v1.1.4322"/>
For details see Frank Prengel’s Blog

ClickOnce does not support FireFox
ClickOnce provides an implemention of the IE mime handler interface for the mime type application/x-ms-application which is associated with .application files on servers hosting ClickOnce application. Hence when a user clicks on a .application in IE our mime handler is invoked which downlods the .application file and fires up the ClickOnce install. When a user clicks on a .application in FireFox the FireFox equivalent of the Open/Save dialog comes up.
For a discussion of possible workarounds see Saurabh Pant’s Weblog

ClickOnce Articles and WebCasts

Deploying Visual Basic 2005 Applications Using ClickOnce (WebCast)

Once you have your Microsoft Visual Basic 2005 applications developed and tested, is it taking too long to deploy them? This webcast can help you change that; it shows how easy it is to deploy Visual Basic 2005 applications with the ClickOnce deployment model. Join us for a look at deployment, security and signing, and bootstrapping prerequisite components for your solution.

View Recording (recorded July 21, 2006)

Secure Smart Client Deployment Using ClickOnce (WebCast)

ClickOnce provides an easy-to-use and flexible mechanism for getting smart client applications in the hands of end users with minimal administrative effort. ClickOnce also provides built-in protections during installation and at runtime for the machine on which you are deploying the application. This webcast describes what security mechanisms are available, how they work, and how to best utilize them for a number of scenarios. We discuss and demonstrate how ClickOnce isolates applications and how permissions are granted. We also show how to use the Trusted Application Deployment technology to deploy applications with elevated privileges on a user’s machine, based on either user prompting or trusted publishers.

View Recording (recorded July 6, 2006)

ClickOnce WebCast Series

Using Visual Studio’s ClickOnce Technology to Deploy a Smart Client Application (Level 200)
You’ve decided to implement a Smart Client architecture for your application. The new ClickOnce technology, available in Visual Studio 2005, can make your deployment strategy significantly more flexible and easier to implement. During this session, you will learn how to incorporate ClickOnce into your application, as well as explore some of the key design decisions you will need to consider to ensure maximum flexibility in deployment without sacrificing security.
View recorded Webcast (recorded June 7, 2005)

Detecting and Deploying Prerequisites for Your Application with ClickOnce (Level 300)
Your application depends on the existence of some other software on the end user’s workstation. What is the best way to ensure a smooth deployment? This webcast will explore some of the recommended techniques for determining whether the workstation already has the prerequisites your application needs, and how to incorporate the installation of these prerequisites seamlessly into your application’s deployment process.
View recorded Webcast (recorded June 14, 2005)

Using ClickOnce to Deploy an Application with Elevated Security Requirements (Level 300)
One of the key advantages to building a rich smart client application is the ability to perform activities on the user’s workstation that require higher privileges than a simple Web application can be granted. During this webcast, learn how to use the security features of ClickOnce to check for the specific permissions your code needs to accomplish its tasks. We also discuss best practices for handling situations where the required permissions are not available.
View recorded Webcast (recorded June 21, 2005)

Building a ClickOnce Toolkit (Level 400)
You have mastered the basics of how it works and what you can do with it, but now it’s time to incorporate more advanced ClickOnce technology in Microsoft Visual Studio 2005 functionality into your solution. During this 60-minute webcast we will demonstrate some sample code blocks you can use and show how to encapsulate all of your updating functionality into a reusable class library that includes "toast" notification of application updates.
View recorded Webcast (recorded June 28, 2005)

Simplify App Deployment with ClickOnce and Registration-Free COM (MSDN Magazine)

This article from the April 2005 edition of MSDN Magazine explains the benefits and the limitations of Reg-Free COM, and how to isolate existing COM components and ActiveX controls using Visual Studio 2005. Reg-Free COM is not limited to ClickOnce but can also be useful for other setup technologies.

MSDN Magazine (April 2005)

Introducing ClickOnce – Web Deployment for Windows Forms Applications (WebCast)

In this MSDN TV show Jamie Cool, program manager in the .NET client team at Microsoft, explains the idea behind ClickOnce, shows how to create a ClickOnce installation using a alpha release of the next version of Visual Studio, and demonstrates some deployment samples. (Windows Media, 23 minutes)

Microsoft Download Center (January 2004)

Deploying Windows Forms Applications with ClickOnce (MSDN Library)

ClickOnce is a new Windows Forms deployment technology that will ship with Visual Studio 2005. It enables easy application installation and upgrading of Web applications with smart clients. The deployment of Windows Forms applications through HTTP has been available since the first version of the .NET Framework and has been evolving ever since. This article discusses the advantages of Windows Forms applications and the evolution of this technology leading up to ClickOnce. It also shows a simple example using the public Beta 1 version of Visual Studio 2005.

Read article in MSDN Library (December 2004)

Deutsche Version dieses Artikels

Windows Forms-Anwendungen mit ClickOnce (MSDN Bibliothek)

In diesem Artikel wird die ClickOnce-Technologie erläutert und mit anderen Bereitstellungstechnologien verglichen. Zudem zeigt der Autor, wie Sie ClickOnce in Ihren Anwendungen verwenden können.
ClickOnce ist eine neue Bereitstellungstechnologie für Windows Forms, die in Visual Studio 2005 enthalten ist. Mit ClickOnce können Sie Anwendungen einfach installieren und Webanwendungen mit Smart Clients einfach aktualisieren. Die Bereitstellung von Windows Forms-Anwendungen über HTTP ist seit der ersten Version des .NET Framework verfügbar und wurde seither ständig weiterentwickelt. In diesem Artikel werden die Vorteile von Windows Forms-Anwendungen und die Entwicklung dieser Technologie bis hin zu ClickOnce erläutert. Außerdem enthält er ein einfaches Beispiel, in dem die offizielle Beta 1-Version von Visual Studio 2005 verwendet wird.

Artikel in der MSDN Bibliothek lesen (Februar 2005)

ClickOnce: Deploy and Update Your Smart Client Projects Using a Central Server (MSDN Magazine)

This article from the May 2004 edition of MSDN Magazine discusses using ClickOnce to deploy real apps, versioning benefits, and programmatic and automatic updating.

MSDN Magazine (May 2004)

Deploy Smart Client Applications with ClickOnce (WebCast)

A key enabler for adopting Smart Client architecture is having an easy and flexible way to deploy client applications to the users’ desktop. ClickOnce is a new capability built into the .NET 2.0 runtime that allows you to automatically deploy applications to the user through a single user action – clicking on a link to the application on a single deployment server. ClickOnce supports numerous automatic and manual update scenarios, and has strong security measures built in. This webcast will describe and demonstrate the capabilities of ClickOnce for deploying and updating client applications in a trustworthy, secure, and easy to use manner.

View Recording (August 2004)

Introducing Client Application Deployment with "ClickOnce" (Book Chapter)

MSDN has published a draft chapter from the forthcoming Addison Wesley title "Essential ClickOnce". Duncan Mackenzie describes how "ClickOnce" will simplify client deployment of Whidbey applications.

Microsoft Developer Network (October 2003)

ClickOnce Deployment Overview (TechNet Library)

Topics in this article: What is a ClickOnce Application? How ClickOnce Deployment Works. ClickOnce and Windows Installer Comparison Table.

Read article in TechNet Library

German MSDN WebCast

Software-Deployment der nächsten Generation von .NET (WebCast)

Keine Installation (in eigentlichen Sinne) mehr. Updates automatisch. Bestimmen, wann nach Updates gesucht werden soll. Und wie. Rollback zur Vorversion. .NET Interfaces. Adé DLL Hölle. Beschränken der Rechte von ausführbarem Code. Unabhängig vom Benutzer. Sandbox-Debugging. … Klingt nach Zukunftsmusik.
Wieviel davon wahr wird in der nächsten Generation von .NET, wird Ihnen hier näher gebracht.

(Während der ersten Demo ist leider nur Audio zu hören, die Bildaufzeichnung ist ausgefallen. Ein Teil dieser Demo wird aber am Ende des WebCasts wiederholt)

Info-Seite zum WebCast (Dezember 2004)
direkt zur Wiedergabe (Dezember 2004)

Additional Click Once Articles


ClickOnce FAQ

On there’s a FAQ that answers frequently asked questions about ClickOnce.

ClickOnce FAQ

Questions & Answers

Does ClickOnce use Windows Installer (MSI) technology?

No, ClickOnce is a technology completely separate from Windows Installer.

Why is Microsoft introducing a new installer technology?

ClickOnce should fill the gap between web applications that run in the browser, and rich client applications that are installed using MSI. The intention is to bring the robustness and ease of use of web application deployment to client applications.

Will ClickOnce replace Windows Installer (MSI)?

No. The two technologies will co-exist. There are a number of scenarios where you can’t use ClickOnce. See the table below for additional information.

Can I use ClickOnce to deploy applications today?

No, but you can play with it. Runtime support for ClickOnce requires a new version of the .NET Framework, which is included in the "Longhorn" SDK that’s available to MSDN subscribers.
Extended client side support for ClickOnce will be included in the next version of Windows, code named "Longhorn". A preview of "Longhorn" is also available to MSDN subscribers.

Which tools are available to build ClickOnce setups?

Building ClickOnce installations will be supported in Microsoft Visual Studio 2005, code named "Whidbey" (see Microsoft’s Developer Tools Roadmap for additional information). Preview and Beta versions of Visual Studio 2005 are available from Microsoft.
At PDC 03 InstallShield showed a pre-release version of DevStudio with ClickOnce support.

Some Differences between ClickOnce and Windows Installer (MSI)

ClickOnce Windows Installer (MSI)
Prerequisites ClickOnce requires that version 2.0 of the .NET framework is already installed on the target machine. You can use an old-fashioned bootstrapper exe to ensure this.
If your application requires runtime packages such as MDAC, MSDE etc. on the target computer again you must use a bootstrapper exe to install them. This cannot be achieved with ClickOnce.
The MSI runtime is required on the target computer. You can use a bootstrapper exe to install it. The current Windows versions already include the MSI runtime.
If your application requires runtime packages such as MDAC, MSDE etc. on the target computer, it’s often a good idea to use a bootstrapper exe to install them, although in some cases it’s possible to install them using a custom action inside your MSI setup.
User input Installing an application via ClickOnce requires two clicks: a click on a hyperlink to launch the install, and clicking Yes on the confirmation dialog. The rest of the UI is a progress bar. There is no way to collect input from the user. Any personalization has to be done inside the application, e.g. on first run. Typically displays a wizard sequence where users can enter a user name and serial number, select features and installation directory, etc. If you run a MSI setup in BasicUI mode you get a user experience that’s somewhat similar to ClickOnce.
Per-user and per-machine installations ClickOnce installations are always for the current user only. Per-machine installations are impossible. If multiple users on a machine install the same software you end up with multiple copies of your application files. You can specify per-user installations and per-machine installations that are available to all users on the system.
Installation directory You application files will always be copied to the My Applications folder under the user’s My Documents folder. You can specify the installation directory for your application files at design time or at run time.
Shortcuts A shortcut to your application will be placed in the Start menu under Programs > Your Company Name. This is not customizable. You cannot create shortcuts on the desktop. You can create as many shortcuts as you need in any place you wish, including the Start menu and the desktop.
Target computer modifications Besides copying the application files and creating a Start menu shortcut ClickOnce installations cannot modify the target computer. Can create and modify files, registry entries etc. on the target computer, only limited by access permissions set by the administrator.
Application isolation ClickOnce applications are isolated from each other and the operating system. A ClickOnce setup cannot damage the target computer. Replacing system files and modifying registry entries can cause all sorts of problems on the target computer ("DLL Hell").
Update installation ClickOnce can automatically detect when a newer version of your application is available and download and install the update.
Only the modified files are downloaded, but always complete files, not parts of files.
Detecting available updates requires additional tools, this is not built into MSI.
Patches can include either modified files in whole, or only the changed parts of a file (binary difference) which may result in a smaller download.
Manageability ClickOnce applications (and updates) are published simply by posting them on the web or file server. There is no method to push them to clients during off work hours and there are no inventory or other management functions built in. MSI packages work nicely with management and deployment tools such as Active Directory and SMS.

Choosing Between ClickOnce and Windows Installer

Michael Sanford takes an in-depth look at the .NET Framework 2.0 ClickOnce technology and compares it with the existing Windows Installer technology. Michael concludes by making some recommendations on when to use each technology.

MSDN Article (January 2005)

ClickOnce Presentations at PDC 2003

On the 2003 Professional Developers Conference (PDC 03) in Los Angeles, Microsoft presented a new installation technology code named "ClickOnce". Session recordings are no longer available online, but you can still download the Powerpoint slides.

Introducing ClickOnce: The New Web Based Application Deployment for Windows Forms and “Avalon”

Learn how you can write Windows applications that utilize the powerful features of the client, yet are as hassle-free to deploy and update as a Web-page. "Whidbey" introduces a technology called ClickOnce, which allows developers to deploy and update their applications by simply copying the files to a Web-site and doesn’t require separate setup authoring. These applications are isolated from other applications, and as a result have the TCO advantages of a Web browser-based application. "Longhorn" takes your investment in ClickOnce forward and adds great additional capabilities such as background updates, full desktop shell integration, progressive rendering, and more.
(Session CLI370 held by Jamie Cool, Program Manager, .NET Client team)

Download Powerpoint Slides

ClickOnce: Advanced Topics in Web Based Application Deployment for Windows Forms and "Avalon"

Learn everything you ever wanted to know about the new ClickOnce deployment technology in "Whidbey" and "Longhorn." Learn the nuts and bolts of how ClickOnce works and all of the tips and tricks to using the ClickOnce deployment technology today. Drill into advanced topics such as how to use the new deployment APIs to customize how your application gets updated. Hear about the security aspects of deploying client applications over the web; what you need to know as the application developer and what you need to know as the admin.
This session includes a demonstration of ClickOnce support in InstallShield.
(Session CLI400 held by Jamie Cool, Program Manager, .NET Client team)

Download Powerpoint Slides

Visual Studio "Whidbey": Deploying Applications Using ClickOnce

Imagine all the benefits of the Web application deployment model brought to the Windows client application! With a focus on no-touch deployment, Visual Studio "Whidbey" makes strides in all areas of application deployment. This session covers new "Whidbey" deployment capabilities for offline application support, rolling back to previous versions of an application, listing an application in the Start Menu and control panel, .NET Framework redistribution, and zone-based debugging.
(Session TLS344 held by Sean Draine, Program Manager, Visual Basic team)

Download Powerpoint Slides