Partager via


Utiliser des solutions

Cette rubrique s’applique à Dynamics 365 Customer Engagement (on-premises). Pour la version Power Apps de cette rubrique, consultez : Utiliser des solutions.

Cette rubrique présente les tâches de programmation spécifiques incluses dans Exemple : Utiliser des solutions et Exemple : Rechercher les dépendances de solution.

Créer un éditeur

Toutes les solutions requièrent un éditeur, représenté par l’entité Publisher. Une solution ne peut pas utiliser l’éditeur Microsoft Corporation, mais elle peut utiliser l’éditeur Default pour l’organisation ou un nouvel éditeur.

Un éditeur requiert les informations suivantes :

  • Un préfixe de personnalisation

  • Un nom unique

  • Un nom convivial

    L’exemple suivant définit tout d’abord un éditeur, puis vérifie si l’éditeur existe déjà en fonction du nom unique. S’il existe déjà, le préfixe de personnalisation a pu être modifié. L’exemple cherche alors à capturer le préfixe de personnalisation actuel. PublisherId est également capturé afin que l’enregistrement d’éditeur puisse être supprimé. Si l’éditeur est introuvable, un nouvel éditeur est créé à l’aide de IOrganizationService. méthode Create

    
    
    
    
    //Define a new publisher
    Publisher _crmSdkPublisher = new Publisher
    {
        UniqueName = "sdksamples",
        FriendlyName = "Microsoft CRM SDK Samples",
        SupportingWebsiteUrl = "https://msdn.microsoft.com/dynamics/crm/default.aspx",
        CustomizationPrefix = "sample",
        EMailAddress = "someone@microsoft.com",
        Description = "This publisher was created with samples from the Microsoft Dynamics CRM SDK"
    };
    
    //Does publisher already exist?
    QueryExpression querySDKSamplePublisher = new QueryExpression
    {
        EntityName = Publisher.EntityLogicalName,
        ColumnSet = new ColumnSet("publisherid", "customizationprefix"),
        Criteria = new FilterExpression()
    };
    
    querySDKSamplePublisher.Criteria.AddCondition("uniquename", ConditionOperator.Equal, _crmSdkPublisher.UniqueName);
    EntityCollection querySDKSamplePublisherResults = _serviceProxy.RetrieveMultiple(querySDKSamplePublisher);
    Publisher SDKSamplePublisherResults = null;
    
    //If it already exists, use it
    if (querySDKSamplePublisherResults.Entities.Count > 0)
    {
        SDKSamplePublisherResults = (Publisher)querySDKSamplePublisherResults.Entities[0];
        _crmSdkPublisherId = (Guid)SDKSamplePublisherResults.PublisherId;
        _customizationPrefix = SDKSamplePublisherResults.CustomizationPrefix;
    }
    //If it doesn't exist, create it
    if (SDKSamplePublisherResults == null)
    {
        _crmSdkPublisherId = _serviceProxy.Create(_crmSdkPublisher);
        Console.WriteLine(String.Format("Created publisher: {0}.", _crmSdkPublisher.FriendlyName));
        _customizationPrefix = _crmSdkPublisher.CustomizationPrefix;
    }
    
    

Récupérer l’éditeur par défaut

Cet exemple montre comment récupérer l’éditeur par défaut. L’éditeur par défaut contient une valeur GUID constante : d21aab71-79e7-11dd-8874-00188b01e34f.



// Retrieve the Default Publisher

//The default publisher has a constant GUID value;
Guid DefaultPublisherId = new Guid("{d21aab71-79e7-11dd-8874-00188b01e34f}");

Publisher DefaultPublisher = (Publisher)_serviceProxy.Retrieve(Publisher.EntityLogicalName, DefaultPublisherId, new ColumnSet(new string[] {"friendlyname" }));

EntityReference DefaultPublisherReference = new EntityReference
{
    Id = DefaultPublisher.Id,
    LogicalName = Publisher.EntityLogicalName,
    Name = DefaultPublisher.FriendlyName
};
Console.WriteLine("Retrieved the {0}.", DefaultPublisherReference.Name);

Créer une solution

L’exemple suivant montre comment créer une solution non gérée à l’aide de l’éditeur d’exemples du SDK créé dans Créer un éditeur.

Une solution requiert les informations suivantes :

  • Un éditeur

  • Un nom convivial

  • Un nom unique

  • Un numéro de version

    La variable _crmSdkPublisherId est une valeur de GUID représentant la valeur publisherid.

    Cet exemple vérifie si la solution existe déjà dans l’organisation en fonction du nom unique. Si la solution n’existe pas, elle est créée. La valeur SolutionId est capturée de sorte que la solution puisse être supprimée.

    
    
    // Create a Solution
    //Define a solution
    Solution solution = new Solution
    {
        UniqueName = "samplesolution",
        FriendlyName = "Sample Solution",
        PublisherId = new EntityReference(Publisher.EntityLogicalName, _crmSdkPublisherId),
        Description = "This solution was created by the WorkWithSolutions sample code in the Microsoft Dynamics CRM SDK samples.",
        Version = "1.0"
    };
    
    //Check whether it already exists
    QueryExpression queryCheckForSampleSolution = new QueryExpression
    {
        EntityName = Solution.EntityLogicalName,
        ColumnSet = new ColumnSet(),
        Criteria = new FilterExpression()
    };
    queryCheckForSampleSolution.Criteria.AddCondition("uniquename", ConditionOperator.Equal, solution.UniqueName);
    
    //Create the solution if it does not already exist.
    EntityCollection querySampleSolutionResults = _serviceProxy.RetrieveMultiple(queryCheckForSampleSolution);
    Solution SampleSolutionResults = null;
    if (querySampleSolutionResults.Entities.Count > 0)
    {
        SampleSolutionResults = (Solution)querySampleSolutionResults.Entities[0];
        _solutionsSampleSolutionId = (Guid)SampleSolutionResults.SolutionId;
    }
    if (SampleSolutionResults == null)
    {
        _solutionsSampleSolutionId = _serviceProxy.Create(solution);
    }
    
    

Récupérer une solution

Pour récupérer une solution en particulier, vous pouvez utiliser l’attribut UniqueName de la solution. Chaque organisation aura une solution par défaut avec une valeur de GUID constante : FD140AAF-4DF4-11DD-BD17-0019B9312238.

Cet exemple montre comment récupérer les données d’une solution avec le nom unique « samplesolution ». Une solution portant ce nom est créée dans Créer une solution.



// Retrieve a solution
String solutionUniqueName = "samplesolution";
QueryExpression querySampleSolution = new QueryExpression
{
    EntityName = Solution.EntityLogicalName,
    ColumnSet = new ColumnSet(new string[] { "publisherid", "installedon", "version", "versionnumber", "friendlyname" }),
    Criteria = new FilterExpression()
};

querySampleSolution.Criteria.AddCondition("uniquename", ConditionOperator.Equal, solutionUniqueName);
Solution SampleSolution = (Solution)_serviceProxy.RetrieveMultiple(querySampleSolution).Entities[0];

Ajouter un nouveau composant de solution

Cet exemple montre comment créer un composant de solution associé à une solution spécifique. Si vous n’associez pas le composant de solution à une solution spécifique lors de sa création, il est uniquement ajouté à la solution par défaut et vous devrez l’ajouter à une solution manuellement ou à l’aide du code inclus dans Ajouter un composant de solution existant.

Ce code crée un groupe d’options global et l’ajoute à la solution avec un nom unique égal à _primarySolutionName.



OptionSetMetadata optionSetMetadata = new OptionSetMetadata()
{
    Name = _globalOptionSetName,
    DisplayName = new Label("Example Option Set", _languageCode),
    IsGlobal = true,
    OptionSetType = OptionSetType.Picklist,
    Options =
{
    new OptionMetadata(new Label("Option 1", _languageCode), 1),
    new OptionMetadata(new Label("Option 2", _languageCode), 2)
}
};
CreateOptionSetRequest createOptionSetRequest = new CreateOptionSetRequest
{
    OptionSet = optionSetMetadata                
};

createOptionSetRequest.SolutionUniqueName = _primarySolutionName;
_serviceProxy.Execute(createOptionSetRequest);

Ajouter un composant de solution existant

Cet exemple montre comment ajouter un composant de solution existant à une solution.

Le code suivant utilise AddSolutionComponentRequest pour ajouter l’entité Account en tant que composant de solution à une solution non gérée.



// Add an existing Solution Component
//Add the Account entity to the solution
RetrieveEntityRequest retrieveForAddAccountRequest = new RetrieveEntityRequest()
{
    LogicalName = Account.EntityLogicalName
};
RetrieveEntityResponse retrieveForAddAccountResponse = (RetrieveEntityResponse)_serviceProxy.Execute(retrieveForAddAccountRequest);
AddSolutionComponentRequest addReq = new AddSolutionComponentRequest()
{
    ComponentType = (int)componenttype.Entity,
    ComponentId = (Guid)retrieveForAddAccountResponse.EntityMetadata.MetadataId,
    SolutionUniqueName = solution.UniqueName
};
_serviceProxy.Execute(addReq);

Supprimer un composant de solution

Cet exemple montre comment supprimer un composant de solution d’une solution non gérée. Le code suivant utilise RemoveSolutionComponentRequest pour supprimer un composant de solution d’entité d’une solution non gérée. solution.UniqueName fait référence à la solution créée dans Créer une solution.



// Remove a Solution Component
//Remove the Account entity from the solution
RetrieveEntityRequest retrieveForRemoveAccountRequest = new RetrieveEntityRequest()
{
    LogicalName = Account.EntityLogicalName
};
RetrieveEntityResponse retrieveForRemoveAccountResponse = (RetrieveEntityResponse)_serviceProxy.Execute(retrieveForRemoveAccountRequest);

RemoveSolutionComponentRequest removeReq = new RemoveSolutionComponentRequest()
{
    ComponentId = (Guid)retrieveForRemoveAccountResponse.EntityMetadata.MetadataId,
    ComponentType = (int)componenttype.Entity,
    SolutionUniqueName = solution.UniqueName
};
_serviceProxy.Execute(removeReq);

Exporter ou empaqueter une solution

Cet exemple montre comment exporter une solution non gérée ou empaqueter une solution gérée. Le code utilise ExportSolutionRequest pour exporter un fichier compressé représentant une solution non gérée. La possibilité de créer une solution gérée est définie avec la propriété Managed. Cet exemple enregistre un fichier nommé samplesolution.zip dans le dossier c:\temp\.



// Export or package a solution
//Export an a solution

ExportSolutionRequest exportSolutionRequest = new ExportSolutionRequest();
exportSolutionRequest.Managed = false;
exportSolutionRequest.SolutionName = solution.UniqueName;

ExportSolutionResponse exportSolutionResponse = (ExportSolutionResponse)_serviceProxy.Execute(exportSolutionRequest);

byte[] exportXml = exportSolutionResponse.ExportSolutionFile;
string filename = solution.UniqueName + ".zip";
File.WriteAllBytes(outputDir + filename, exportXml);

Console.WriteLine("Solution exported to {0}.", outputDir + filename);

Installer ou mettre à niveau une solution

Cet exemple montre comment installer ou mettre à niveau une solution à l’aide du message ImportSolutionRequest.

Vous pouvez utiliser l’entité ImportJob pour capturer des données sur la réussite de l’importation.

Cet exemple explique comment importer une solution sans suivre la réussite.



// Install or Upgrade a Solution                  

byte[] fileBytes = File.ReadAllBytes(ManagedSolutionLocation);

ImportSolutionRequest impSolReq = new ImportSolutionRequest()
{
    CustomizationFile = fileBytes
};

_serviceProxy.Execute(impSolReq);

Console.WriteLine("Imported Solution from {0}", ManagedSolutionLocation);

Suivi de la réussite de l’importation

Lorsque vous spécifiez ImportJobId pour ImportSolutionRequest, vous pouvez utiliser la valeur pour interroger l’entité ImportJob à propos du statut de l’importation.

ImportJobId peut également être utilisé pour télécharger un fichier journal à l’aide du message RetrieveFormattedImportJobResultsRequest.

Récupération des données de tâche d’importation

L’exemple suivant explique comment récupérer l’enregistrement de tâche d’importation et le contenu de l’attribut ImportJob.Data.



// Monitor import success
byte[] fileBytesWithMonitoring = File.ReadAllBytes(ManagedSolutionLocation);

ImportSolutionRequest impSolReqWithMonitoring = new ImportSolutionRequest()
{
    CustomizationFile = fileBytes,
    ImportJobId = Guid.NewGuid()
};

_serviceProxy.Execute(impSolReqWithMonitoring);
Console.WriteLine("Imported Solution with Monitoring from {0}", ManagedSolutionLocation);

ImportJob job = (ImportJob)_serviceProxy.Retrieve(ImportJob.EntityLogicalName, impSolReqWithMonitoring.ImportJobId, new ColumnSet(new System.String[] { "data", "solutionname" }));


System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(job.Data);

String ImportedSolutionName = doc.SelectSingleNode("//solutionManifest/UniqueName").InnerText;
String SolutionImportResult = doc.SelectSingleNode("//solutionManifest/result/@result").Value;

Console.WriteLine("Report from the ImportJob data");
Console.WriteLine("Solution Unique name: {0}", ImportedSolutionName);
Console.WriteLine("Solution Import Result: {0}", SolutionImportResult);
Console.WriteLine("");

// This code displays the results for Global Option sets installed as part of a solution.

System.Xml.XmlNodeList optionSets = doc.SelectNodes("//optionSets/optionSet");
foreach (System.Xml.XmlNode node in optionSets)
{
    string OptionSetName = node.Attributes["LocalizedName"].Value;
    string result = node.FirstChild.Attributes["result"].Value;

    if (result == "success")
    {
        Console.WriteLine("{0} result: {1}",OptionSetName, result);
    }
    else
    {
        string errorCode = node.FirstChild.Attributes["errorcode"].Value;
        string errorText = node.FirstChild.Attributes["errortext"].Value;

        Console.WriteLine("{0} result: {1} Code: {2} Description: {3}",OptionSetName, result, errorCode, errorText);
    }
}

Le contenu de la propriété Data correspond à une chaîne représentant un fichier XML. L’exemple suivant a été capturé avec le code de cet exemple. Cette solution gérée contenait un groupe d’options global unique appelé sample_tempsampleglobaloptionsetname.

<importexportxml start="634224017519682730"  
                 stop="634224017609764033"  
                 progress="80"  
                 processed="true">  
 <solutionManifests>  
  <solutionManifest languagecode="1033"  
                    id="samplesolutionforImport"  
                    LocalizedName="Sample Solution for Import"  
                    processed="true">  
   <UniqueName>samplesolutionforImport</UniqueName>  
   <LocalizedNames>  
    <LocalizedName description="Sample Solution for Import"  
                   languagecode="1033" />  
   </LocalizedNames>  
   <Descriptions>  
    <Description description="This solution was created by the WorkWithSolutions sample code in the Microsoft CRM SDK samples."  
                 languagecode="1033" />  
   </Descriptions>  
   <Version>1.0</Version>  
   <Managed>1</Managed>  
   <Publisher>  
    <UniqueName>sdksamples</UniqueName>  
    <LocalizedNames>  
     <LocalizedName description="Microsoft CRM SDK Samples"  
                    languagecode="1033" />  
    </LocalizedNames>  
    <Descriptions>  
     <Description description="This publisher was created with samples from the Microsoft CRM SDK"  
                  languagecode="1033" />  
    </Descriptions>  
    <EMailAddress>someone@microsoft.com</EMailAddress>  
    <SupportingWebsiteUrl>https://msdn.microsoft.com/dynamics/crm/default.aspx</SupportingWebsiteUrl>  
    <Addresses>  
     <Address>  
      <City />  
      <Country />  
      <Line1 />  
      <Line2 />  
      <PostalCode />  
      <StateOrProvince />  
      <Telephone1 />  
     </Address>  
    </Addresses>  
   </Publisher>  
   <results />  
   <result result="success"  
           errorcode="0"  
           errortext=""  
           datetime="20:49:12.08"  
           datetimeticks="634224269520845122" />  
  </solutionManifest>  
 </solutionManifests>  
 <upgradeSolutionPackageInformation>  
  <upgradeRequired>0</upgradeRequired>  
  <upgradeValid>1</upgradeValid>  
  <fileVersion>5.0.9669.0</fileVersion>  
  <currentVersion>5.0.9669.0</currentVersion>  
  <fileSku>OnPremise</fileSku>  
  <currentSku>OnPremise</currentSku>  
 </upgradeSolutionPackageInformation>  
 <entities />  
 <nodes />  
 <settings />  
 <dashboards />  
 <securityroles />  
 <workflows />  
 <templates />  
 <optionSets>  
  <optionSet id="sample_tempsampleglobaloptionsetname"  
             LocalizedName="Example Option Set"  
             Description=""  
             processed="true">  
   <result result="success"  
           errorcode="0"  
           errortext=""  
           datetime="20:49:16.10"  
           datetimeticks="634224269561025400" />  
  </optionSet>  
 </optionSets>  
 <ConnectionRoles />  
 <SolutionPluginAssemblies />  
 <SdkMessageProcessingSteps />  
 <ServiceEndpoints />  
 <webResources />  
 <reports />  
 <FieldSecurityProfiles />  
 <languages>  
  <language>  
   <result result="success"  
           errorcode="0"  
           errortext=""  
           datetime="20:49:12.00"  
           datetimeticks="634224269520092986" />  
  </language>  
 </languages>  
 <entitySubhandlers />  
 <publishes>  
  <publish processed="false" />  
 </publishes>  
 <rootComponents>  
  <rootComponent processed="true">  
   <result result="success"  
           errorcode="0"  
           errortext=""  
           datetime="20:49:20.83"  
           datetimeticks="634224269608387238" />  
  </rootComponent>  
 </rootComponents>  
 <dependencies>  
  <dependency processed="true">  
   <result result="success"  
           errorcode="0"  
           errortext=""  
           datetime="20:49:20.97"  
           datetimeticks="634224269609715208" />  
  </dependency>  
 </dependencies>  
</importexportxml>  

Suppression d’une solution

Cet exemple montre comment supprimer une solution. Cet exemple explique comment récupérer une solution à l’aide de l’attribut uniquename de la solution, puis récupérer l’attribut solutionid dans les résultats. Utilisez solutionid avec IOrganizationService. méthode Delete.



// Delete a solution

QueryExpression queryImportedSolution = new QueryExpression
{
    EntityName = Solution.EntityLogicalName,
    ColumnSet = new ColumnSet(new string[] { "solutionid", "friendlyname" }),
    Criteria = new FilterExpression()
};


queryImportedSolution.Criteria.AddCondition("uniquename", ConditionOperator.Equal, ImportedSolutionName);

Solution ImportedSolution = (Solution)_serviceProxy.RetrieveMultiple(queryImportedSolution).Entities[0];

_serviceProxy.Delete(Solution.EntityLogicalName, (Guid)ImportedSolution.SolutionId);

Console.WriteLine("Deleted the {0} solution.", ImportedSolution.FriendlyName);

Détecter les dépendances de solutions

Cet exemple montre comment créer un rapport montrant les dépendances entre les composants de solution.

Ce code :

  • récupère tous les composants d’une solution ;

  • récupère toutes les dépendances de chaque composant ;

  • affiche un rapport décrivant la dépendance, pour chaque dépendance détectée.

    
    
    
    // Grab all Solution Components for a solution.
    QueryByAttribute componentQuery = new QueryByAttribute
    {
        EntityName = SolutionComponent.EntityLogicalName,
        ColumnSet = new ColumnSet("componenttype", "objectid", "solutioncomponentid", "solutionid"),
        Attributes = { "solutionid" },
    
        // In your code, this value would probably come from another query.
        Values = { _primarySolutionId }
    };
    
    IEnumerable<SolutionComponent> allComponents =
        _serviceProxy.RetrieveMultiple(componentQuery).Entities.Cast<SolutionComponent>();
    
    foreach (SolutionComponent component in allComponents)
    {
        // For each solution component, retrieve all dependencies for the component.
        RetrieveDependentComponentsRequest dependentComponentsRequest =
            new RetrieveDependentComponentsRequest
            {
                ComponentType = component.ComponentType.Value,
                ObjectId = component.ObjectId.Value
            };
        RetrieveDependentComponentsResponse dependentComponentsResponse =
            (RetrieveDependentComponentsResponse)_serviceProxy.Execute(dependentComponentsRequest);
    
        // If there are no dependent components, we can ignore this component.
        if (dependentComponentsResponse.EntityCollection.Entities.Any() == false)
            continue;
    
        // If there are dependencies upon this solution component, and the solution
        // itself is managed, then you will be unable to delete the solution.
        Console.WriteLine("Found {0} dependencies for Component {1} of type {2}",
            dependentComponentsResponse.EntityCollection.Entities.Count,
            component.ObjectId.Value,
            component.ComponentType.Value
            );
        //A more complete report requires more code
        foreach (Dependency d in dependentComponentsResponse.EntityCollection.Entities)
        {
            DependencyReport(d);
        }
    }
    
    

    La méthode DependencyReport est utilisée dans l’exemple de code suivant.

Rapport de dépendance

La méthode DependencyReport fournit un message plus convivial à partir des informations disponibles dans la dépendance.

Note

Dans cet exemple, la méthode est uniquement partiellement mise en œuvre. Elle affiche des messages uniquement pour les composants de solution d’attributs et de groupes d’options.



   /// <summary>
   /// Shows how to get a more friendly message based on information within the dependency
   /// <param name="dependency">A Dependency returned from the RetrieveDependentComponents message</param>
   /// </summary> 
public void DependencyReport(Dependency dependency)
   {
 //These strings represent parameters for the message.
    String dependentComponentName = "";
    String dependentComponentTypeName = "";
    String dependentComponentSolutionName = "";
    String requiredComponentName = "";
    String requiredComponentTypeName = "";
    String requiredComponentSolutionName = "";

 //The ComponentType global Option Set contains options for each possible component.
    RetrieveOptionSetRequest componentTypeRequest = new RetrieveOptionSetRequest
    {
     Name = "componenttype"
    };

    RetrieveOptionSetResponse componentTypeResponse = (RetrieveOptionSetResponse)_serviceProxy.Execute(componentTypeRequest);
    OptionSetMetadata componentTypeOptionSet = (OptionSetMetadata)componentTypeResponse.OptionSetMetadata;
 // Match the Component type with the option value and get the label value of the option.
    foreach (OptionMetadata opt in componentTypeOptionSet.Options)
    {
     if (dependency.DependentComponentType.Value == opt.Value)
     {
      dependentComponentTypeName = opt.Label.UserLocalizedLabel.Label;
     }
     if (dependency.RequiredComponentType.Value == opt.Value)
     {
      requiredComponentTypeName = opt.Label.UserLocalizedLabel.Label;
     }
    }
 //The name or display name of the compoent is retrieved in different ways depending on the component type
    dependentComponentName = getComponentName(dependency.DependentComponentType.Value, (Guid)dependency.DependentComponentObjectId);
    requiredComponentName = getComponentName(dependency.RequiredComponentType.Value, (Guid)dependency.RequiredComponentObjectId);

 // Retrieve the friendly name for the dependent solution.
    Solution dependentSolution = (Solution)_serviceProxy.Retrieve
     (
      Solution.EntityLogicalName,
      (Guid)dependency.DependentComponentBaseSolutionId,
      new ColumnSet("friendlyname")
     );
    dependentComponentSolutionName = dependentSolution.FriendlyName;
    
 // Retrieve the friendly name for the required solution.
    Solution requiredSolution = (Solution)_serviceProxy.Retrieve
      (
       Solution.EntityLogicalName,
       (Guid)dependency.RequiredComponentBaseSolutionId,
       new ColumnSet("friendlyname")
      );
    requiredComponentSolutionName = requiredSolution.FriendlyName;

 //Display the message
     Console.WriteLine("The {0} {1} in the {2} depends on the {3} {4} in the {5} solution.",
     dependentComponentName,
     dependentComponentTypeName,
     dependentComponentSolutionName,
     requiredComponentName,
     requiredComponentTypeName,
     requiredComponentSolutionName);
   }

Détecter si un composant de solution peut être supprimé

Utilisez le message RetrieveDependenciesForDeleteRequest pour identifier les autres composants de solution qui pourraient empêcher un composant de solution donné d’être supprimé. L’exemple de code suivant recherche tous les attributs utilisant un groupe d’options global connu. Tout attribut utilisant le groupe d’options global empêcherait le groupe d’options défini d’être supprimé.



// Use the RetrieveOptionSetRequest message to retrieve  
// a global option set by it's name.
RetrieveOptionSetRequest retrieveOptionSetRequest =
    new RetrieveOptionSetRequest
    {
     Name = _globalOptionSetName
    };

// Execute the request.
RetrieveOptionSetResponse retrieveOptionSetResponse =
    (RetrieveOptionSetResponse)_serviceProxy.Execute(
    retrieveOptionSetRequest);
_globalOptionSetId = retrieveOptionSetResponse.OptionSetMetadata.MetadataId;
if (_globalOptionSetId != null)
{ 
 //Use the global OptionSet MetadataId with the appropriate componenttype
 // to call RetrieveDependenciesForDeleteRequest
 RetrieveDependenciesForDeleteRequest retrieveDependenciesForDeleteRequest = new RetrieveDependenciesForDeleteRequest 
{ 
 ComponentType = (int)componenttype.OptionSet,
 ObjectId = (Guid)_globalOptionSetId
};

 RetrieveDependenciesForDeleteResponse retrieveDependenciesForDeleteResponse =
  (RetrieveDependenciesForDeleteResponse)_serviceProxy.Execute(retrieveDependenciesForDeleteRequest);
 Console.WriteLine("");
 foreach (Dependency d in retrieveDependenciesForDeleteResponse.EntityCollection.Entities)
 {

  if (d.DependentComponentType.Value == 2)//Just testing for Attributes
  {
   String attributeLabel = "";
   RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest
   {
    MetadataId = (Guid)d.DependentComponentObjectId
   };
   RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)_serviceProxy.Execute(retrieveAttributeRequest);

   AttributeMetadata attmet = retrieveAttributeResponse.AttributeMetadata;

   attributeLabel = attmet.DisplayName.UserLocalizedLabel.Label;
  
    Console.WriteLine("An {0} named {1} will prevent deleting the {2} global option set.", 
   (componenttype)d.DependentComponentType.Value, 
   attributeLabel, 
   _globalOptionSetName);
  }
 }                 
}

Voir aussi

Packager et distribuer les extensions avec les solutions Dynamics 365 Customer Engagement
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
Exemple : utiliser des solutions
Exemple : Rechercher les dépendances de solution