Walkthrough: Download satellite assemblies on demand with the ClickOnce deployment API

Applies to: yesVisual Studio noVisual Studio for Mac

Note

This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here

Windows Forms applications can be configured for multiple cultures through the use of satellite assemblies. A satellite assembly is an assembly that contains application resources for a culture other than the application's default culture.

As discussed in Localize ClickOnce applications, you can include multiple satellite assemblies for multiple cultures within the same ClickOnce deployment. By default, ClickOnce will download all of the satellite assemblies in your deployment to the client machine, although a single client will probably require only one satellite assembly.

This walkthrough demonstrates how to mark your satellite assemblies as optional, and download only the assembly a client machine needs for its current culture settings. The following procedure uses the tools available in the Windows Software Development Kit (SDK). You can also perform this task in Visual Studio. Also see Walkthrough: Download satellite assemblies on demand with the ClickOnce deployment API using the Designer or Walkthrough: Download satellite assemblies on demand with the ClickOnce deployment API using the Designer.

Note

For testing purposes, the following code example programmatically sets the culture to ja-JP. See the "Next Steps" section later in this topic for information on how to adjust this code for a production environment.

Prerequisites

This topic assumes that you know how to add localized resources to your application using Visual Studio. For detailed instructions, see Walkthrough: Localize Windows forms.

To download satellite assemblies on demand

  1. Add the following code to your application to enable on-demand downloading of satellite assemblies.

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.Threading;
    using System.Globalization;
    using System.Deployment.Application;
    using System.Reflection;
    
    namespace ClickOnce.SatelliteAssemblies
    {
        static class Program
        {
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Thread.CurrentThread.CurrentUICulture = new CultureInfo("ja-JP");
    
                // Call this before initializing the main form, which will cause the resource manager
                // to look for the appropriate satellite assembly.
                GetSatelliteAssemblies(Thread.CurrentThread.CurrentCulture.ToString());
    
                Application.Run(new Form1());
            }
    
            static void GetSatelliteAssemblies(string groupName)
            {
                if (ApplicationDeployment.IsNetworkDeployed)
                {
                    ApplicationDeployment deploy = ApplicationDeployment.CurrentDeployment;
    
                    if (deploy.IsFirstRun)
                    {
                        try
                        {
                            deploy.DownloadFileGroup(groupName);
                        }
                        catch (DeploymentException de)
                        {
                            // Log error. Do not report error to the user, as there may not be a satellite
                            // assembly if the user's culture and the application's default culture match.
                        }
                    }
                }
            }
    
        }
    }
    
    Imports System.Deployment.Application
    Imports System.Globalization
    Imports System.Threading
    
    Public Class Form1
        Shared Sub Main(ByVal args As String())
            Application.EnableVisualStyles()
    
            Thread.CurrentThread.CurrentUICulture = New CultureInfo("ja-JP")
            GetSatelliteAssemblies(Thread.CurrentThread.CurrentUICulture.ToString())
    
            Application.Run(New Form1())
        End Sub
    
        Private Shared Sub GetSatelliteAssemblies(ByVal groupName As String)
            If (ApplicationDeployment.IsNetworkDeployed) Then
    
                Dim deploy As ApplicationDeployment = ApplicationDeployment.CurrentDeployment
    
                If (deploy.IsFirstRun) Then
                    Try
                        deploy.DownloadFileGroup(groupName)
                    Catch de As DeploymentException
                        ' Log error. Do not report error to the user, as there may not be a satellite
                        ' assembly if the user's culture and the application's default culture match.
    
                    End Try
                End If
            End If
        End Sub
    End Class
    
  2. Generate satellite assemblies for your application by using Resgen.exe (Resource File Generator) or Visual Studio.

  3. Generate an application manifest, or open your existing application manifest, by using MageUI.exe. For more information about this tool, see MageUI.exe (Manifest Generation and Editing Tool, Graphical Client).

  4. Click the Files tab.

  5. Click the ellipsis button (...) and select the directory containing all of your application's assemblies and files, including the satellite assemblies you generated using Resgen.exe. (A satellite assembly will have a name in the form <isoCode>\ApplicationName.resources.dll, where <isoCode> is a language identifier in RFC 1766 format.)

  6. Click Populate to add the files to your deployment.

  7. Select the Optional check box for each satellite assembly.

  8. Set the group field for each satellite assembly to its ISO language identifier. For example, for a Japanese satellite assembly, you would specify a download group name of ja-JP. This will enable the code you added in step 1 to download the appropriate satellite assembly, depending upon the user's CurrentUICulture property setting.

Next steps

In a production environment, you will likely need to remove the line in the code example that sets CurrentUICulture to a specific value, because client machines will have the correct value set by default. When your application runs on a Japanese client machine, for example, CurrentUICulture will be ja-JP by default. Setting this value programmatically is a good way to test your satellite assemblies before you deploy your application.

See also