Partager via


Créer des solutions qui prennent en charge différentes langues.

 

Date de publication : novembre 2016

S’applique à : Dynamics CRM 2015

Mise à jour de Microsoft Dynamics CRM 2015 et de Microsoft Dynamics CRM Online 2015 acceptent plusieurs langues. Pour installer votre solution pour les organisations qui incluent différentes langues de base ou qui ont plusieurs langues, tenez-en compte lorsque vous planifiez votre solution. Le tableau suivant répertorie la tactique à utiliser avec des composants de solution à inclure dans une solution qui accepte plusieurs langues.

Tactique

Type de composant de solution

Option développeur

Ressources Web

Étiquettes imbriquées

Navigation de l'application (SiteMap)
Rubans

Exporter et importer des traductions

Attributs
Graphiques
Tableaux de bord
Entité
Relations d’entités
Formulaires
Messages
Groupes d’options
Vues

Localisation en chaînes de la langue de base

Modèles de contrat
Rôles de connexion
Processus (Workflow)
Rôles de sécurité
Profils de sécurité de champ

Localisation facultative

Étapes de traitement du message SDK
Points de terminaison de service

Composant distinct pour chaque langue

Modèles d’article
Modèles de courriers électroniques
Modèles de publipostage
Rapports
Boîtes de dialogue

Utiliser des ressources Web XML comme ressources linguistiques

Assemblys du plug-in

Les sections suivantes fournissent des informations supplémentaires pour chaque tactique.

Option développeur

Les ressources Web ont un attribut LanguageCode pouvant être défini dans l’interface utilisateur mais cette valeur n’est pas utilisée par l’application. Comme les ressources Web sont accessibles via une adresse URL, vous accédez généralement à une ressource Web avec un nom au lieu d’interroger les ressources Web disponibles avec LanguageCode comme critère. Par conséquent, LanguageCode a une valeur limitée. Le scénario le plus courant est que vous devez détecter la langue appropriée en fonction du contexte dans lequel la ressource Web s’affiche. Pour les ressources Web, l’objet de contexte permet d’accéder aux fonctions d7d0b052-abca-4f81-9b86-0b9dc5e62a66#BKMK_getOrgLcid et d7d0b052-abca-4f81-9b86-0b9dc5e62a66#BKMK_getUserLcid. Ces deux fonctions renvoient une valeur entière qui correspond aux valeurs d’ID de paramètres régionaux (LCID).Les valeurs d'ID de paramètres régionaux valides sont disponibles sur la page Tableau des ID de paramètres régionaux (LCID).

Pour les ressources Web qui exposent du texte de l’interface utilisateur, vous pouvez utiliser la méthode que vous voulez pour gérer comment le texte et la structure prendront en charge les préférences de langue de l’utilisateur. L’implémentation spécifique dépend du type de ressource Web.

Ressources Web HTML

Il est possible de créer des ressources Web localisées distinctes qui varient selon le nom appliqué. Par exemple, vous pouvez avoir une ressource Web nommée new_/my_solution/1033/content.htm pour prendre en charge l’anglais et une autre nommée new_/my_solution/1041/content.htm pour prendre en charge le japonais. Pour les langues nécessitant une orientation de droite à gauche, voir Comment : afficher du texte de droite à gauche en utilisant des balises HTML pour la globalisation.

Si vous voulez pouvoir définir dynamiquement le texte de l’interface utilisateur selon la langue d’un utilisateur, vous pouvez stocker toutes les valeurs de chaîne localisées dans un objet défini dans un fichier de ressources Web de script. Selon la préférence de langue de l’utilisateur, vous pouvez définir les éléments de texte de l’interface utilisateur à l’aide de chaînes stockées dans l’objet lorsque la page se charge. L’exemple de code JavaScript suivant affiche une méthode pour définir des chaînes localisées.

var userLcid = 1033;

var localizedStrings = {
 ErrorMessage: {
  _1033: "There was an error completing this action. Please try again.",
  _1041: "このアクションを完了、エラーが発生しました。もう一度実行してください。",
  _1031: "Es ist ein Fehler aufgetreten, der Abschluss dieser Aktion. Bitte versuchen Sie es erneut.",
  _1036: "Il y avait une erreur complétant cette action. Veuillez essayer à nouveau.",
  _1034: "Hubo un error al completar esta acción. Vuelva a intentarlo.",
  _1049: "Произошла ошибка, выполнение этого действия. Пожалуйста, попробуйте снова."
 },
 Welcome: {
  _1033: "Welcome",
  _1041: "ようこそ",
  _1031: "Willkommen",
  _1036: "Bienvenue",
  _1034: "Bienvenido",
  _1049: "Добро пожаловать"
 }
};
var LocalizedErrorMessage = localizedStrings.ErrorMessage["_" + userLcid];
var LocalizedWelcomeMessage = localizedStrings.Welcome["_" + userLcid];

Ressources Web Silverlight

Les applications Silverlight peuvent être écrites pour prendre en charge des ressources linguistiques localisées.Pour plus d'informations :Localisation des applications Silverlight.

La classe suivante permet d’accéder à la préférence de langue de l’utilisateur selon le contexte dans lequel la ressource Web Silverlight est présentée. Cette classe prend en charge l’anglais américain, l’arabe, l’allemand, l’hébreu et le japonais. Elle doit être modifiée pour les langues spécifiques prises en charge par la ressource Web Silverlight.

public static class Localization    
    {
    // The locale ID.
    public static int LCID { get; set; }
    // Create a dictionary of right-to-left language codes (Hebrew and Arabic).
    private static Dictionary<int, bool> _rightToLeftLanguages =
        new Dictionary<int, bool>
        {
            { 1025, true },
            { 1037, true },
        };
    private static Dictionary<int, String> _lcidToCultureNameMap =
        new Dictionary<int, String>
        {
            { 1025, "ar-SA" },
            { 1031, "de-DE" },
            { 1033, "en-US" },
            { 1037, "he-IL" },
            { 1041, "ja-JP" }
        };
    public static void InitializeCulture()
    {
        // Get the user's LCID from the page's context to determine what language to
        // display.
        dynamic window = HtmlPage.Window;
        //Get the user's language code from the context.
        try
        {
            //If the containing window is a CRM form
            LCID = Convert.ToInt32(window.Xrm.Page.context.getUserLcid());
            // For testing, comment the line above and uncomment one of the lines below
            //representing a user language.
            //LCID = 1033; //English
            //LCID = 1041; //Japanese
            //LCID = 1031; //German
            //LCID = 1037; //Hebrew - a right-to-left language.
            //LCID = 1025; //Arabic - a right-to-left language.
        }
        catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
        {
            try
            {
                //If the containing window is a CRM web resource with
                //the WebResources/ClientGlobalContext.js.aspx page linked
                LCID = Convert.ToInt32(window.GetGlobalContext().getUserLcid());
            }
            catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
            {
                LCID = 1033; //Setting a default for design time when the context
                //object is not present and one of the sample languages are not set.
            }
        }
        // Sets the culture of the thread to the appropriate culture, based on what
        // LCID was retrieved.
        if (_lcidToCultureNameMap.ContainsKey(LCID))
        {
            var culture = new CultureInfo(_lcidToCultureNameMap[LCID]);
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;
        }
    }
    public static FlowDirection GetFlowDirection()
    {
        if (_rightToLeftLanguages.ContainsKey(LCID))
        {
            return FlowDirection.RightToLeft;
        }
        return FlowDirection.LeftToRight;
    }
}

Pour les langues nécessitant une orientation de droite à gauche, voir Propriété FrameworkElement.FlowDirection.

Ressources Web XML

Alors que les ressources Web XML ne sont généralement pas affichées, elles peuvent être utiles pour stocker les chaînes localisées sous forme de ressources pour d’autres composants de solution, comme il est décrit dans Utiliser des ressources Web XML comme ressources linguistiques.

Étiquettes imbriquées

Chaque composant de solution qui utilise cette tactique nécessite que tout texte localisé soit inclus dans le composant de solution.

Rubans

Lorsqu’un module linguistique est installé, le ruban de l’application affiche automatiquement le texte traduit pour tout le texte par défaut dans le ruban. Les étiquettes système sont définies dans une valeur d’attribut ResourceId destinée uniquement à une utilisation interne. Lorsque vous ajoutez votre propre texte, vous devez utiliser l’élément <LocLabels> (RibbonDiffXml) pour fournir du texte localisé pour les langues que vous prenez en charge.Pour plus d'informations :Utiliser les étiquettes localisées avec des rubans

SiteMap

Lorsqu’un module linguistique est installé, le texte par défaut dans la barre de navigation de l’application affiche automatiquement le texte localisé. Pour remplacer le texte par défaut ou fournir votre propre texte, utilisez l’élément <Titles> (SiteMap). L’élément Titles doit contenir un élément <Title> (SiteMap) contenant le texte localisé pour toutes les langues prises en charge par votre solution. Si un élément Title n’est pas disponible pour la langue par défaut de l’utilisateur, le titre correspondant à la langue de base de l’organisation est affiché.

L’élément <SubArea> (SiteMap) permet de passer la préférence de langue de l’utilisateur à l’aide du paramètre userlcid afin que le contenu qui est la cible de l’attribut SubArea.Url puisse être informé de la préférence de langue de l’utilisateur et ajuster en conséquence.Pour plus d'informations :Transmettre les paramètres vers une URL à l’aide du plan de site

Exporter et importer des traductions

Les étiquettes localisables pour les composants de solution du tableau suivant peuvent être exportées en vue de leur localisation.

Entités

Attributs

Relations

Groupe d’options généraux

Messages de l’entité

Formulaires d’entités

Vues d’entités (SavedQuery)

Graphiques

Tableau de bord

Traduction des étiquettes et des chaînes d’affichage

Vous ne pouvez effectuer de personnalisations dans l’application qu’en utilisant la langue de base. Par conséquent, si vous souhaitez fournir les étiquettes et les chaînes d’affichage localisées correspondant à ces personnalisations, vous devez exporter le texte des étiquettes pour qu’elles puissent être localisées pour les autres langues activées pour l’organisation. Effectuez les opérations suivantes :

  1. Assurez-vous que l’organisation sur laquelle vous travaillez a tous les packs d’interface utilisateur multilingue installés et les langues approvisionnées pour lesquelles vous souhaitez fournir des traductions.

  2. Créez votre solution et modifiez les composants.

  3. Après avoir terminé de développer votre solution, utilisez la fonctionnalité Exporter les traductions. Cette opération génère une feuille de calcul Microsoft Office Excel (CrmTranslations.xml) qui contient toutes les étiquettes qui doivent être traduites.

  4. Dans la feuille de calcul, fournissez les traductions correspondantes.

  5. Réimportez les traductions dans la même organisation Microsoft Dynamics 365 à l’aide de la fonctionnalité Importer les traductions et publiez vos modifications.

  6. La prochaine fois que la solution sera exportée, elle conservera toutes les traductions que vous avez fournies.

Lorsqu’une solution est importée, les étiquettes pour les langues non disponibles dans le système cible sont ignorées et un avertissement est consigné.

Si les étiquettes pour la langue de base du système cible ne sont pas disponibles dans le package de solution, les étiquettes de la langue de base de la source sont utilisées à la place. Par exemple, si vous importez une solution contenant les étiquettes pour l’anglais et le français avec l’anglais comme langue de base mais que le système cible a le japonais et le français avec le japonais comme langue de base, les étiquettes anglaises sont utilisées au lieu des étiquettes japonaises. Les étiquettes des langues de base ne peuvent pas être null ou vides.

Exportation des traductions

Avant d’exporter des traductions, vous devez commencer par installer les modules linguistiques et regrouper toutes les langues que vous voulez localiser. Vous pouvez exporter les traductions dans l’application Web ou en utilisant le message ExportTranslationRequest. Pour plus d'informations, voir Aide et formation : exportation d'une entité personnalisée et du texte d'un champ à convertir.

Traduction d’un texte

Lorsque vous ouvrez le fichier CrmTranslations.xml dans Excel, vous voyez les trois feuilles de calcul répertoriées dans le tableau suivant.

Feuille de calcul

Description

Informations

Affiche les informations sur l’organisation et la solution depuis lesquelles les étiquettes et chaînes ont été exportées.

Chaînes d’affichage

Chaînes d’affichage représentant le texte de tous les messages associés à un composant métadonnées. Ce tableau contient des messages d’erreur et des chaînes qui sont utilisés pour les éléments de ruban système.

Étiquettes localisées

Affiche le texte intégral des étiquettes de composant métadonnées.

Vous pouvez envoyer ce fichier à un linguiste, à une agence de traduction ou à une société de localisation. Ils doivent fournir des chaînes localisées pour les cellules vides.

Notes

Pour les entités personnalisées, certaines étiquettes courantes sont partagées avec les entités système, comme Créé le ou Créé par. Comme vous avez déjà installé et mis en service les langues, si vous exportez des langues pour la solution par défaut, vous pouvez probablement mettre en correspondance certaines étiquettes de vos entités personnalisées avec le texte traduit pour les étiquettes identiques utilisées par d’autres entités. Cela peut réduire les coûts de localisation et améliorer la cohérence.

Une fois que le texte présent dans les feuilles de calcul a été localisé, ajoutez les fichiers CrmTranslations.xml et [Content_Types].xml à un même fichier .zip compressé. Vous pouvez maintenant importer ce fichier.

Si vous préférez utiliser les fichiers exportés par programme comme document XML, consultez Schémas de référence Office 2003 XML pour plus d’informations sur les schémas utilisés par ces fichiers.

Importation d’un texte traduit

Important

Vous pouvez uniquement réimporter du texte traduit dans la même organisation d’où il a été exporté.

Après avoir exporté le texte d’entité ou d’attribut personnalisé et l’avoir fait traduire, vous pouvez importer les chaînes de texte traduites dans l’application Web en utilisant le message ImportTranslationRequest. Le fichier que vous importez doit être un fichier compressé qui contient les fichiers CrmTranslations.xml et [Content_Types].xml à la racine. Pour plus d’informations, voir Aide et formation : importation d’un texte de champ et d’entité traduit.

Après avoir importé les traductions terminées, le texte personnalisé s’affiche pour les utilisateurs qui travaillent dans les langues dans lesquelles le texte a été traduit.

Notes

Microsoft Dynamics 365 ne peut pas importer du texte traduit dépassant 500 caractères. Si un des éléments de votre fichier de traductions dépasse 500 caractères, le processus d’importation échoue. Dans ce cas, vérifiez la ligne du fichier à l’origine de l’échec, réduisez le nombre de caractères et réessayez.

La personnalisation n’étant possible que dans la langue de base, vous serez peut-être amené à travailler dans Microsoft Dynamics 365 avec la langue de base définie comme préférence de langue. Pour vérifier que le texte traduit s’affiche, vous devez changer de préférence de langue pour l’interface utilisateur de Microsoft Dynamics 365. Si vous souhaitez effectuer des personnalisations supplémentaires, vous devez revenir dans la langue de base.

Localisation en chaînes de la langue de base

Certains composants de solution ne prennent pas en charge plusieurs langues. Ces composants comprennent les noms ou le texte qui ne peuvent avoir de sens que dans une langue spécifique. Si vous créez une solution pour une langue spécifique, définissez ces composants de solution pour la langue de base prévue pour l’organisation.

Si vous devez prendre en charge plusieurs langues, une tactique consiste à inclure la localisation dans les chaînes de la langue de base. Par exemple, si vous avez un rôle de connexion nommé « Ami » et que vous devez prendre en charge l’anglais, l’espagnol et l’allemand, vous pouvez utiliser le texte « Ami (Amigo/Freund) » comme nom du rôle de connexion. En raison des problèmes de longueur de texte, il existe des limitations quant au nombre de langues qui peuvent être prises en charge avec cette tactique.

Certains composants de solution appartenant à ce groupe sont uniquement visibles par les administrateurs. Comme la personnalisation du système ne peut être effectuée que dans la langue de base de l’organisation, il n’est pas nécessaire de fournir plusieurs versions linguistiques. Les composants Rôles de sécurité et Profil de sécurité de champ appartiennent à ce groupe.

Les Modèles de contrats fournissent une description du type de contrat de service. Ils nécessitent du texte pour les champs Nom et Abréviation. Vous devez penser à utiliser des noms et abréviations uniques et appropriés pour tous les utilisateurs de l’organisation.

Les rôles de connexion dépendent d’une personne qui sélectionne des catégories et noms de rôle de connexion descriptifs. Étant donné que ceux-ci peuvent être relativement courts, il est recommandé d’inclure la localisation dans les chaînes en langue de base.

Les processus (workflows) qui sont initialisés pour les événements peuvent bien fonctionner tant qu’ils n’ont pas besoin de mettre à jour des enregistrements avec du texte qui doit être localisé. Il est possible d’utiliser un assembly de workflow afin que la logique qui peut s’appliquer au texte localisé puisse utiliser la même stratégie que les assemblys de plug-in (Utiliser des ressources Web XML comme ressources linguistiques).

Les workflows à la demande ont besoin d’avoir un nom pour pouvoir être choisis. En plus d’inclure la traduction dans le nom du workflow à la demande, une autre tactique consiste à créer plusieurs workflows avec des noms localisés qui appellent tous le même processus enfant. Toutefois, tous les utilisateurs verront la liste complète des workflows à la demande, pas simplement ceux de leur langue d’interface par défaut de l’utilisateur.

Localisation facultative

Les composants de solution Étape de traitement du message SDK et Point de terminaison de service n’exposent pas le texte localisable aux utilisateurs. S’il est important que ces composants aient des noms et des descriptions qui correspondent à la langue de base de l’organisation, vous pouvez créer et exporter une solution gérée avec des noms et des descriptions dans cette langue.

Composant distinct pour chaque langue

Les composants de solution suivants peuvent contenir chacun une quantité considérable de texte à localiser :

  • Modèles d'article

  • Modèles de courr. électr.

  • Modèles de publipostage

  • Rapports

  • Boîtes de dialogue

Pour ces types de composants de solution, la tactique recommandée consiste à créer des composants distincts pour chaque langue. Cela signifie que vous créez généralement une solution gérée de base qui contient vos composants de solution principales puis une solution gérée distincte qui contient ces composants de solution pour chaque langue. Une fois que les clients ont installé la solution de base, ils peuvent installer les solutions gérées pour les langues qu’ils ont mis en service pour l’organisation.

Contrairement à Processus (workflows), vous pouvez créer des Boîtes de dialogue qui reflètent les paramètres existants de préférence de la langue de l’utilisateur et qui n’affichent les boîtes de dialogue qu’aux utilisateurs de cette langue.

Création d’une boîte de dialogue localisée

  1. Installez le module linguistique approprié et mettez la langue en service.

    Pour plus d’informations, voir TechNet : instructions d’installation du module linguistique.

  2. Modifiez vos options personnelles pour spécifier la Langue de l’interface utilisateur pour la langue souhaitée pour la boîte de dialogue.

  3. Accédez à Paramètres et, dans le groupe Centre de traitement, sélectionnez Processus.

  4. Cliquez sur Nouveau et créez la boîte de dialogue dans la langue que vous avez spécifiée.

  5. Après avoir créé la boîte de dialogue, modifiez vos options personnelles pour spécifier la langue de base de l’organisation.

  6. Lorsque vous utilisez la langue de base de l’organisation, vous pouvez accéder à la zone Solutions dans Paramètres et ajouter la boîte de dialogue localisée dans le cadre d’une solution.

La boîte de dialogue créée dans l’autre langue ne sera affichée qu’aux utilisateurs qui affichent Microsoft Dynamics 365 avec cette langue.

Utiliser des ressources Web XML comme ressources linguistiques

Les composants de solution d’assembly de plug-in peuvent envoyer des messages à un utilisateur final en levant une exception InvalidPluginExecutionException ainsi qu’en créant et en mettant à jour des enregistrements. Contrairement aux ressources Web Silverlight, les plug-ins ne peuvent pas utiliser de fichiers de ressources.

Lorsqu’un plug-in nécessite du texte localisé, vous pouvez utiliser une ressource Web XML pour stocker les chaînes localisées pour permettre au plug-in d’y accéder si nécessaire. La structure du fichier XML est votre option, mais vous pouvez suivre la structure utilisée par les fichiers de ressource ASP.NET (.resx) pour créer des ressources Web XML distinctes pour chaque langue. Par exemple, la ressource suivante est une ressource Web XML nommée localizedString.en_US qui suit le modèle utilisé par les fichiers resx.

<root>
 <data name="ErrorMessage">
  <value>There was an error completing this action. Please try again.</value>
 </data>
 <data name="Welcome">
  <value>Welcome</value>
 </data>
</root>

Le code suivant montre comment un message localisé peut être retransmis dans un plug-in pour afficher un message à un utilisateur. Il concerne la phase de prévalidation d’un événement Delete pour l’entité Account :

protected void ExecutePreValidateAccountDelete(LocalPluginContext localContext)
  {
   if (localContext == null)
   {
    throw new ArgumentNullException("localContext");
   }
   int OrgLanguage = RetrieveOrganizationBaseLanguageCode(localContext.OrganizationService);
   int UserLanguage = RetrieveUserUILanguageCode(localContext.OrganizationService,
 localContext.PluginExecutionContext.InitiatingUserId);
   String fallBackResourceFile = "";
   switch (OrgLanguage)
   {
    case 1033:
     fallBackResourceFile = "new_localizedStrings.en_US";
     break;
    case 1041:
     fallBackResourceFile = "new_localizedStrings.ja_JP";
     break;
    case 1031:
     fallBackResourceFile = "new_localizedStrings.de_DE";
     break;
    case 1036:
     fallBackResourceFile = "new_localizedStrings.fr_FR";
     break;
    case 1034:
     fallBackResourceFile = "new_localizedStrings.es_ES";
     break;
    case 1049:
     fallBackResourceFile = "new_localizedStrings.ru_RU";
     break;
    default:
     fallBackResourceFile = "new_localizedStrings.en_US";
     break;
   }
   String ResourceFile = "";
   switch (UserLanguage)
   {
    case 1033:
     ResourceFile = "new_localizedStrings.en_US";
     break;
    case 1041:
     ResourceFile = "new_localizedStrings.ja_JP";
     break;
    case 1031:
     ResourceFile = "new_localizedStrings.de_DE";
     break;
    case 1036:
     ResourceFile = "new_localizedStrings.fr_FR";
     break;
    case 1034:
     ResourceFile = "new_localizedStrings.es_ES";
     break;
    case 1049:
     ResourceFile = "new_localizedStrings.ru_RU";
     break;
    default:
     ResourceFile = fallBackResourceFile;
     break;
   }
   XmlDocument messages = RetrieveXmlWebResourceByName(localContext, ResourceFile);
   String message = RetrieveLocalizedStringFromWebResource(localContext, messages, "ErrorMessage");
   throw new InvalidPluginExecutionException(message);
  }
  protected static int RetrieveOrganizationBaseLanguageCode(IOrganizationService service)
  {
   QueryExpression organizationEntityQuery = new QueryExpression("organization");
   organizationEntityQuery.ColumnSet.AddColumn("languagecode");
   EntityCollection organizationEntities = service.RetrieveMultiple(organizationEntityQuery);
   return (int)organizationEntities[0].Attributes["languagecode"];
  }
  protected static int RetrieveUserUILanguageCode(IOrganizationService service, Guid userId)
  {
   QueryExpression userSettingsQuery = new QueryExpression("usersettings");
   userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid");
   userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId);
   EntityCollection userSettings = service.RetrieveMultiple(userSettingsQuery);
   if (userSettings.Entities.Count > 0)
   {
    return (int)userSettings.Entities[0]["uilanguageid"];
   }
   return 0;
  }
  protected static XmlDocument RetrieveXmlWebResourceByName(LocalPluginContext context, string webresourceSchemaName)
  {
   context.TracingService.Trace("Begin:RetrieveXmlWebResourceByName, webresourceSchemaName={0}", webresourceSchemaName);
   QueryExpression webresourceQuery = new QueryExpression("webresource");
   webresourceQuery.ColumnSet.AddColumn("content");
   webresourceQuery.Criteria.AddCondition("name", ConditionOperator.Equal, webresourceSchemaName);
   EntityCollection webresources = context.OrganizationService.RetrieveMultiple(webresourceQuery);
   context.TracingService.Trace("Webresources Returned from server. Count={0}", webresources.Entities.Count);
   if (webresources.Entities.Count > 0)
   {
    byte[] bytes = Convert.FromBase64String((string)webresources.Entities[0]["content"]);
    // The bytes would contain the ByteOrderMask. Encoding.UTF8.GetString() does not remove the BOM.
    // Stream Reader auto detects the BOM and removes it on the text
    XmlDocument document = new XmlDocument();
    document.XmlResolver = null;
    using (MemoryStream ms = new MemoryStream(bytes))
    {
     using (StreamReader sr = new StreamReader(ms))
     {
      document.Load(sr);
     }
    }
    context.TracingService.Trace("End:RetrieveXmlWebResourceByName , webresourceSchemaName={0}", webresourceSchemaName);
    return document;
   }
   else
   {
    context.TracingService.Trace("{0} Webresource missing. Reinstall the solution", webresourceSchemaName);
    throw new InvalidPluginExecutionException(String.Format("Unable to locate the web resource {0}.", webresourceSchemaName));
    return null;
 // This line never reached
   }
  }
  protected static string RetrieveLocalizedStringFromWebResource(LocalPluginContext context, XmlDocument resource, string resourceId)
  {
   XmlNode valueNode = resource.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, "./root/data[@name='{0}']/value", resourceId));
   if (valueNode != null)
   {
    return valueNode.InnerText;
   }
   else
   {
    context.TracingService.Trace("No Node Found for {0} ", resourceId);
    throw new InvalidPluginExecutionException(String.Format("ResourceID {0} was not found.", resourceId));
   }
  }

Voir aussi

Empaqueter et distribuer les extensions à l’aide des solutions
Présentation des solutions
Plan de développement de solutions
Suivi de dépendance pour les composants de solution
Créer, exporter ou importer une solution non gérée
Créer, installer et mettre à jour une solution gérée
Désinstaller ou supprimer une solution
Entités de solution
Recherchez les valeurs de propriété de produit

© 2017 Microsoft. Tous droits réservés. Copyright