DeploymentExceptionMapper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / MS / Internal / AppModel / DeploymentExceptionMapper.cs / 2 / DeploymentExceptionMapper.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: DeploymentExceptionMapper class definition. 
// 
// History:
//  2005/02/08 : MingChan - Created 
//  2005/08/22 : MingChan - Added boot WinFX functionality
//  2007/08/01 : ChangoV  - Added detection of System.Core.dll to infer required platform version.
//                          Because WPF v3.5 still has WindowsBase v3.0.0.0, the original heuristic failed.
//  2008/04/08 : ChangoV  - Update for v3.5 SP1. ClickOnce has bestowed upon us two more sentinel assemblies! 
//                            > Sentinel.v3.5Client: for applications explicitly targeting the "client"
//                              ("Arrowhead") subset of the framework; 
//                            > System.Data.Entity: for applications targeting the full v3.5 SP1. 
//                          (It would have been much better if they agreed to just add System.Core v3.5.1
//                          and v3.5.2 instead, which would allow v3.0 SP1/v3.5 to properly bootstrap 
//                          applications targeting this new release...)
//
//---------------------------------------------------------------------------
 
using System;
using System.Collections; 
using System.Globalization; 
using System.Resources;
using System.Reflection; 
using System.Windows;
using System.Deployment.Application;
using System.Text.RegularExpressions;
 
namespace MS.Internal
{ 
    internal enum MissingDependencyType 
    {
        Others = 0, 
        WinFX = 1,
        CLR = 2
    }
 
    internal static class DeploymentExceptionMapper
    { 
        // This is the hardcoded fwlink query parameters, the only dynamic data we pass to fwlink server 
        // is the WinFX or CLR version we parse from the ClickOnce error message.
        // Product ID is always 11953 which is the WinFX Runtime Components and subproduct is always bootwinfx 
        // The winfxsetup.exe is language neutral so we always specify 0x409 for languages.
        const string fwlinkPrefix = "http://go.microsoft.com/fwlink?prd=11953&sbp=Bootwinfx&pver=";
        const string fwlinkSuffix = "&plcid=0x409&clcid=0x409&";
 
        //-----------------------------------------------------
        // 
        //  Internal Methods 
        //
        //----------------------------------------------------- 
        #region Internal Methods

        // Check if the platform exception is due to missing WinFX or CLR dependency
        // Parse the exception message and find out the dependent WinFX version and create the 
        // corresponding fwlink Uri.
        static internal MissingDependencyType GetWinFXRequirement(Exception e, 
                                                            InPlaceHostingManager hostingManager, 
                                                            out string version,
                                                            out Uri fwlinkUri) 
        {
            version = String.Empty;
            fwlinkUri = null;
 
            // ClickOnce detects whether it's running as part of the v3.5 "client" subset ("Arrowhead") and
            // if so blocks older applications that don't explicitly opt into the subset framework. 
            // (Unfortunately, it does not block an application targeting the full 3.5 SP1 framework this way.) 
            // The exception message has ".NET Framework 3.5 SP1" hard-coded in it (referring to the version
            // of the framework needed to run the application, which is not strictly right, but older versions 
            // can't/shouldn't be installed on top of the "client" subset).
            // To make this exception message parsing at least potentially somewhat future-proof, a regex is
            // used that allows for some variability of syntax and version number.
            // We don't include the "SP1" part in the fwlink query. This is for consistency with the detection 
            // via sentinel assemblies. The server can be updated to offer the latest release/SP compatible
            // with the requested major.minor version. 
            if (e is DependentPlatformMissingException) 
            {
                Regex regex = new Regex(@".NET Framework (v\.?)?(?\d{1,2}(\.\d{1,2})?)", 
                                        RegexOptions.ExplicitCapture|RegexOptions.IgnoreCase);
                string msg = e.Message;
                Match match = regex.Match(msg);
                if(match.Success) 
                {
                    version = match.Groups[1].Value; 
                    ConstructFwlinkUrl(version, out fwlinkUri); 
                    return MissingDependencyType.WinFX;
                } 
            }

            // Load the clickonce resource and use it to parse the exception message
            Assembly deploymentDll = Assembly.GetAssembly(hostingManager.GetType()); 

            if (deploymentDll == null) 
            { 
                return MissingDependencyType.Others;
            } 

            ResourceManager resourceManager = new ResourceManager("System.Deployment", deploymentDll);

            if (resourceManager == null) 
            {
                return MissingDependencyType.Others; 
            } 

            String clrProductName = resourceManager.GetString("PlatformMicrosoftCommonLanguageRuntime", CultureInfo.CurrentUICulture); 
            String versionString = resourceManager.GetString("PlatformDependentAssemblyVersion", CultureInfo.CurrentUICulture);

            if ((clrProductName == null) || (versionString == null))
            { 
                return MissingDependencyType.Others;
            } 
 
            // Need to trim off the parameters in the ClickOnce strings:
            // "{0} Version {1}" -> "Version" 
            // "Microsoft Common Language Runtime Version {0}" -> "Microsoft Common Language Runtime Version"
            clrProductName = clrProductName.Replace("{0}", "");
            versionString = versionString.Replace("{0}", "");
            versionString = versionString.Replace("{1}", ""); 

            string[] sentinelAssemblies = { 
                // The Original & "Only" 
                "WindowsBase",
                // A reference to System.Core is what makes an application target .NET v3.5. 
                // Because WindowsBase still has v3.0.0.0, it's not the one that fails the platform requirements
                // test when a v3.5 app is run on the v3 runtime. (This additional check added for v3 SP1.)
                "System.Core",
                // New sentinel assemblies for v3.5 SP1 (see the revision history) 
                "Sentinel.v3.5Client", "System.Data.Entity" };
 
            // Parse the required version and trim it to major and minor only 
            string excpMsg = e.Message;
            int index = excpMsg.IndexOf(versionString, StringComparison.Ordinal); 

            if (index != -1)
            {
                // ClickOnce exception message is ErrorMessage_Platform* 
                // from clickonce/system.deployment.txt
                version = String.Copy(excpMsg.Substring(index + versionString.Length)); 
                int indexToFirstDot = version.IndexOf(".", StringComparison.Ordinal); 
                int indexToSecondDot = version.IndexOf(".", indexToFirstDot+1, StringComparison.Ordinal);
 
                // Defense in depth here in case Avalon change the version scheme to major + minor only
                // and we might never see the second dot
                if (indexToSecondDot != -1)
                { 
                    version = version.Substring(0, indexToSecondDot);
                } 
 
                if (excpMsg.IndexOf(clrProductName, StringComparison.Ordinal) != -1)
                { 
                    // prepend CLR to distinguish CLR version fwlink query
                    // vs. WinFX version query.
                    string clrVersion = String.Concat("CLR", version);
                    return (ConstructFwlinkUrl(clrVersion, out fwlinkUri) ? MissingDependencyType.CLR : MissingDependencyType.Others); 
                }
                else 
                { 
                    bool sentinelMissing = false;
                    foreach (string sentinelAssembly in sentinelAssemblies) 
                    {
                        if (excpMsg.IndexOf(sentinelAssembly, StringComparison.OrdinalIgnoreCase) > 0)
                        {
                            sentinelMissing = true; 
                            break;
                        } 
                    } 
                    if (!sentinelMissing)
                    { 
                        version = String.Empty;
                    }
                }
            } 

            return (ConstructFwlinkUrl(version, out fwlinkUri) ? MissingDependencyType.WinFX : MissingDependencyType.Others); 
        } 

 
        static internal void GetErrorTextFromException(Exception e, out string errorTitle, out string errorMessage)
        {
            errorTitle = String.Empty;
            errorMessage = String.Empty; 

            if (e == null) 
            { 
                errorTitle = SR.Get(SRID.CancelledTitle);
                errorMessage = SR.Get(SRID.CancelledText); 
            }
            else if (e is DependentPlatformMissingException)
            {
                errorTitle = SR.Get(SRID.PlatformRequirementTitle); 
                errorMessage = e.Message;
            } 
            else if (e is InvalidDeploymentException) 
            {
                errorTitle = SR.Get(SRID.InvalidDeployTitle); 
                errorMessage = SR.Get(SRID.InvalidDeployText);
            }
            else if (e is TrustNotGrantedException)
            { 
                errorTitle = SR.Get(SRID.TrustNotGrantedTitle);
                errorMessage = SR.Get(SRID.TrustNotGrantedText); 
            } 
            else if (e is DeploymentDownloadException)
            { 
                errorTitle = SR.Get(SRID.DownloadTitle);
                errorMessage = SR.Get(SRID.DownloadText);
            }
            else if (e is DeploymentException) 
            {
                errorTitle = SR.Get(SRID.DeployTitle); 
                errorMessage = SR.Get(SRID.DeployText); 
            }
            else 
            {
                errorTitle = SR.Get(SRID.UnknownErrorTitle);
                errorMessage = SR.Get(SRID.UnknownErrorText) + "\n\n" + e.Message;
            } 
        }
 
        static internal bool ConstructFwlinkUrl(string version, out Uri fwlinkUri) 
        {
            string fwlink = String.Empty; 
            fwlinkUri = null;

            if (version != String.Empty)
            { 
                fwlink = String.Copy(fwlinkPrefix);
                fwlink = String.Concat(fwlink, version); 
                fwlink = String.Concat(fwlink, fwlinkSuffix); 
                // Mitigate against proxy server caching, append today's day to the fwlink
                // query. This matches the fwlink query from unmanaged bootwap functionality 
                // in IE7.
                DateTime today = System.DateTime.Today;
                fwlink = String.Concat(fwlink, today.Year.ToString());
                fwlink = String.Concat(fwlink, today.Month.ToString()); 
                fwlink = String.Concat(fwlink, today.Day.ToString());
                fwlinkUri = new Uri(fwlink); 
                return true; 
            }
 
            return false;
        }

        #endregion 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: DeploymentExceptionMapper class definition. 
// 
// History:
//  2005/02/08 : MingChan - Created 
//  2005/08/22 : MingChan - Added boot WinFX functionality
//  2007/08/01 : ChangoV  - Added detection of System.Core.dll to infer required platform version.
//                          Because WPF v3.5 still has WindowsBase v3.0.0.0, the original heuristic failed.
//  2008/04/08 : ChangoV  - Update for v3.5 SP1. ClickOnce has bestowed upon us two more sentinel assemblies! 
//                            > Sentinel.v3.5Client: for applications explicitly targeting the "client"
//                              ("Arrowhead") subset of the framework; 
//                            > System.Data.Entity: for applications targeting the full v3.5 SP1. 
//                          (It would have been much better if they agreed to just add System.Core v3.5.1
//                          and v3.5.2 instead, which would allow v3.0 SP1/v3.5 to properly bootstrap 
//                          applications targeting this new release...)
//
//---------------------------------------------------------------------------
 
using System;
using System.Collections; 
using System.Globalization; 
using System.Resources;
using System.Reflection; 
using System.Windows;
using System.Deployment.Application;
using System.Text.RegularExpressions;
 
namespace MS.Internal
{ 
    internal enum MissingDependencyType 
    {
        Others = 0, 
        WinFX = 1,
        CLR = 2
    }
 
    internal static class DeploymentExceptionMapper
    { 
        // This is the hardcoded fwlink query parameters, the only dynamic data we pass to fwlink server 
        // is the WinFX or CLR version we parse from the ClickOnce error message.
        // Product ID is always 11953 which is the WinFX Runtime Components and subproduct is always bootwinfx 
        // The winfxsetup.exe is language neutral so we always specify 0x409 for languages.
        const string fwlinkPrefix = "http://go.microsoft.com/fwlink?prd=11953&sbp=Bootwinfx&pver=";
        const string fwlinkSuffix = "&plcid=0x409&clcid=0x409&";
 
        //-----------------------------------------------------
        // 
        //  Internal Methods 
        //
        //----------------------------------------------------- 
        #region Internal Methods

        // Check if the platform exception is due to missing WinFX or CLR dependency
        // Parse the exception message and find out the dependent WinFX version and create the 
        // corresponding fwlink Uri.
        static internal MissingDependencyType GetWinFXRequirement(Exception e, 
                                                            InPlaceHostingManager hostingManager, 
                                                            out string version,
                                                            out Uri fwlinkUri) 
        {
            version = String.Empty;
            fwlinkUri = null;
 
            // ClickOnce detects whether it's running as part of the v3.5 "client" subset ("Arrowhead") and
            // if so blocks older applications that don't explicitly opt into the subset framework. 
            // (Unfortunately, it does not block an application targeting the full 3.5 SP1 framework this way.) 
            // The exception message has ".NET Framework 3.5 SP1" hard-coded in it (referring to the version
            // of the framework needed to run the application, which is not strictly right, but older versions 
            // can't/shouldn't be installed on top of the "client" subset).
            // To make this exception message parsing at least potentially somewhat future-proof, a regex is
            // used that allows for some variability of syntax and version number.
            // We don't include the "SP1" part in the fwlink query. This is for consistency with the detection 
            // via sentinel assemblies. The server can be updated to offer the latest release/SP compatible
            // with the requested major.minor version. 
            if (e is DependentPlatformMissingException) 
            {
                Regex regex = new Regex(@".NET Framework (v\.?)?(?\d{1,2}(\.\d{1,2})?)", 
                                        RegexOptions.ExplicitCapture|RegexOptions.IgnoreCase);
                string msg = e.Message;
                Match match = regex.Match(msg);
                if(match.Success) 
                {
                    version = match.Groups[1].Value; 
                    ConstructFwlinkUrl(version, out fwlinkUri); 
                    return MissingDependencyType.WinFX;
                } 
            }

            // Load the clickonce resource and use it to parse the exception message
            Assembly deploymentDll = Assembly.GetAssembly(hostingManager.GetType()); 

            if (deploymentDll == null) 
            { 
                return MissingDependencyType.Others;
            } 

            ResourceManager resourceManager = new ResourceManager("System.Deployment", deploymentDll);

            if (resourceManager == null) 
            {
                return MissingDependencyType.Others; 
            } 

            String clrProductName = resourceManager.GetString("PlatformMicrosoftCommonLanguageRuntime", CultureInfo.CurrentUICulture); 
            String versionString = resourceManager.GetString("PlatformDependentAssemblyVersion", CultureInfo.CurrentUICulture);

            if ((clrProductName == null) || (versionString == null))
            { 
                return MissingDependencyType.Others;
            } 
 
            // Need to trim off the parameters in the ClickOnce strings:
            // "{0} Version {1}" -> "Version" 
            // "Microsoft Common Language Runtime Version {0}" -> "Microsoft Common Language Runtime Version"
            clrProductName = clrProductName.Replace("{0}", "");
            versionString = versionString.Replace("{0}", "");
            versionString = versionString.Replace("{1}", ""); 

            string[] sentinelAssemblies = { 
                // The Original & "Only" 
                "WindowsBase",
                // A reference to System.Core is what makes an application target .NET v3.5. 
                // Because WindowsBase still has v3.0.0.0, it's not the one that fails the platform requirements
                // test when a v3.5 app is run on the v3 runtime. (This additional check added for v3 SP1.)
                "System.Core",
                // New sentinel assemblies for v3.5 SP1 (see the revision history) 
                "Sentinel.v3.5Client", "System.Data.Entity" };
 
            // Parse the required version and trim it to major and minor only 
            string excpMsg = e.Message;
            int index = excpMsg.IndexOf(versionString, StringComparison.Ordinal); 

            if (index != -1)
            {
                // ClickOnce exception message is ErrorMessage_Platform* 
                // from clickonce/system.deployment.txt
                version = String.Copy(excpMsg.Substring(index + versionString.Length)); 
                int indexToFirstDot = version.IndexOf(".", StringComparison.Ordinal); 
                int indexToSecondDot = version.IndexOf(".", indexToFirstDot+1, StringComparison.Ordinal);
 
                // Defense in depth here in case Avalon change the version scheme to major + minor only
                // and we might never see the second dot
                if (indexToSecondDot != -1)
                { 
                    version = version.Substring(0, indexToSecondDot);
                } 
 
                if (excpMsg.IndexOf(clrProductName, StringComparison.Ordinal) != -1)
                { 
                    // prepend CLR to distinguish CLR version fwlink query
                    // vs. WinFX version query.
                    string clrVersion = String.Concat("CLR", version);
                    return (ConstructFwlinkUrl(clrVersion, out fwlinkUri) ? MissingDependencyType.CLR : MissingDependencyType.Others); 
                }
                else 
                { 
                    bool sentinelMissing = false;
                    foreach (string sentinelAssembly in sentinelAssemblies) 
                    {
                        if (excpMsg.IndexOf(sentinelAssembly, StringComparison.OrdinalIgnoreCase) > 0)
                        {
                            sentinelMissing = true; 
                            break;
                        } 
                    } 
                    if (!sentinelMissing)
                    { 
                        version = String.Empty;
                    }
                }
            } 

            return (ConstructFwlinkUrl(version, out fwlinkUri) ? MissingDependencyType.WinFX : MissingDependencyType.Others); 
        } 

 
        static internal void GetErrorTextFromException(Exception e, out string errorTitle, out string errorMessage)
        {
            errorTitle = String.Empty;
            errorMessage = String.Empty; 

            if (e == null) 
            { 
                errorTitle = SR.Get(SRID.CancelledTitle);
                errorMessage = SR.Get(SRID.CancelledText); 
            }
            else if (e is DependentPlatformMissingException)
            {
                errorTitle = SR.Get(SRID.PlatformRequirementTitle); 
                errorMessage = e.Message;
            } 
            else if (e is InvalidDeploymentException) 
            {
                errorTitle = SR.Get(SRID.InvalidDeployTitle); 
                errorMessage = SR.Get(SRID.InvalidDeployText);
            }
            else if (e is TrustNotGrantedException)
            { 
                errorTitle = SR.Get(SRID.TrustNotGrantedTitle);
                errorMessage = SR.Get(SRID.TrustNotGrantedText); 
            } 
            else if (e is DeploymentDownloadException)
            { 
                errorTitle = SR.Get(SRID.DownloadTitle);
                errorMessage = SR.Get(SRID.DownloadText);
            }
            else if (e is DeploymentException) 
            {
                errorTitle = SR.Get(SRID.DeployTitle); 
                errorMessage = SR.Get(SRID.DeployText); 
            }
            else 
            {
                errorTitle = SR.Get(SRID.UnknownErrorTitle);
                errorMessage = SR.Get(SRID.UnknownErrorText) + "\n\n" + e.Message;
            } 
        }
 
        static internal bool ConstructFwlinkUrl(string version, out Uri fwlinkUri) 
        {
            string fwlink = String.Empty; 
            fwlinkUri = null;

            if (version != String.Empty)
            { 
                fwlink = String.Copy(fwlinkPrefix);
                fwlink = String.Concat(fwlink, version); 
                fwlink = String.Concat(fwlink, fwlinkSuffix); 
                // Mitigate against proxy server caching, append today's day to the fwlink
                // query. This matches the fwlink query from unmanaged bootwap functionality 
                // in IE7.
                DateTime today = System.DateTime.Today;
                fwlink = String.Concat(fwlink, today.Year.ToString());
                fwlink = String.Concat(fwlink, today.Month.ToString()); 
                fwlink = String.Concat(fwlink, today.Day.ToString());
                fwlinkUri = new Uri(fwlink); 
                return true; 
            }
 
            return false;
        }

        #endregion 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK