Utilizzare le soluzioni
Data di pubblicazione: gennaio 2017
Si applica a: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online
Questo argomento illustra le attività di pianificazione specifiche incluse in Esempio: utilizzare le soluzioni e Esempio: rilevare le dipendenze delle soluzioni.
In questo argomento
Creare un autore
Recuperare l'autore predefinito
Creare una soluzione
Recuperare una soluzione
Aggiungere un nuovo componente di soluzione
Aggiungere un componente di soluzione esistente
Rimuovere un componente di soluzione
Esportare o comprimere una soluzione
Installare o aggiornare una soluzione
Eliminare una soluzione
Rilevare le dipendenze delle soluzioni
Creare un autore
Ogni soluzione richiede un autore, rappresentato dall'entità Publisher. Una soluzione non può utilizzare un autore Microsoft Corporation ma può utilizzare l'autore Default per l'organizzazione o un nuovo autore.
Un autore richiede quanto segue:
Un prefisso di personalizzazione
Un nome univoco
Un nome descrittivo
Nell'esempio seguente si definisce prima un autore e quindi si controlla se l'autore esiste già in base al nome univoco. Se esiste già, il prefisso di personalizzazione potrebbe essere stato modificato, pertanto l'esempio cerca di acquisire il prefisso di personalizzazione corrente. Anche PublisherId viene acquisito in modo da poter eliminare il record dell'autore. Se l'autore non viene trovato, viene creato un nuovo autore utilizzando il metodo IOrganizationService.Create, metodo
//Define a new publisher
Publisher _crmSdkPublisher = new Publisher
{
UniqueName = "sdksamples",
FriendlyName = "Microsoft CRM SDK Samples",
SupportingWebsiteUrl = "https://msdn.microsoft.com/en-us/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;
}
'Define a new publisher
Dim _crmSdkPublisher As Publisher =
New Publisher With {
.UniqueName = "sdksamples",
.FriendlyName = "Microsoft CRM SDK Samples",
.SupportingWebsiteUrl = "https://msdn.microsoft.com/en-us/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?
Dim querySDKSamplePublisher As QueryExpression =
New QueryExpression With {
.EntityName = Publisher.EntityLogicalName,
.ColumnSet = New ColumnSet("publisherid", "customizationprefix"),
.Criteria = New FilterExpression()
}
querySDKSamplePublisher.Criteria.AddCondition("uniquename",
ConditionOperator.Equal,
_crmSdkPublisher.UniqueName)
Dim querySDKSamplePublisherResults As EntityCollection =
_serviceProxy.RetrieveMultiple(querySDKSamplePublisher)
Dim SDKSamplePublisherResults As Publisher = Nothing
'If it already exists, use it
If querySDKSamplePublisherResults.Entities.Count > 0 Then
SDKSamplePublisherResults = CType(querySDKSamplePublisherResults.Entities(0), Publisher)
_crmSdkPublisherId = CType(SDKSamplePublisherResults.PublisherId, Guid)
_customizationPrefix = SDKSamplePublisherResults.CustomizationPrefix
End If
'If it doesn't exist, create it
If SDKSamplePublisherResults Is Nothing Then
_crmSdkPublisherId = _serviceProxy.Create(_crmSdkPublisher)
Console.WriteLine(String.Format("Created publisher: {0}.", _crmSdkPublisher.FriendlyName))
_customizationPrefix = _crmSdkPublisher.CustomizationPrefix
End If
Recuperare l'autore predefinito
In questo esempio viene illustrato come recuperare l'autore predefinito. L'autore predefinito ha un valore GUID costante: 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);
' Retrieve the Default Publisher
'The default publisher has a constant GUID value;
Dim DefaultPublisherId As New Guid("{d21aab71-79e7-11dd-8874-00188b01e34f}")
Dim DefaultPublisher As Publisher =
CType(_serviceProxy.Retrieve(Publisher.EntityLogicalName,
DefaultPublisherId,
New ColumnSet(New String() {"friendlyname"})),
Publisher)
Dim DefaultPublisherReference As EntityReference = New EntityReference With {
.Id = DefaultPublisher.Id,
.LogicalName = Publisher.EntityLogicalName,
.Name = DefaultPublisher.FriendlyName
}
Console.WriteLine("Retrieved the {0}.", DefaultPublisherReference.Name)
Creare una soluzione
Nell'esempio seguente viene illustrato come creare una soluzione non gestita utilizzando l'autore di esempi di Microsoft Dynamics 365 SDK creato in Creare un autore.
Una soluzione richiede quanto segue:
Un autore
Un nome descrittivo
Un nome univoco
Un numero versione
Il valore _crmSdkPublisherId variabile è un valore GUID che rappresenta il valore publisherid.
Questo esempio controlla se la soluzione esiste già nell'organizzazione in base al nome univoco. Se la soluzione non esiste, viene creata. Il valore di SolutionId viene acquisito quindi la soluzione può essere eliminata.
// 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);
}
' Create a Solution
'Define a solution
Dim solution As Solution =
New Solution With {
.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
Dim queryCheckForSampleSolution As QueryExpression =
New QueryExpression With {
.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.
Dim querySampleSolutionResults As EntityCollection =
_serviceProxy.RetrieveMultiple(queryCheckForSampleSolution)
Dim SampleSolutionResults As Solution = Nothing
If querySampleSolutionResults.Entities.Count > 0 Then
SampleSolutionResults = CType(querySampleSolutionResults.Entities(0), Solution)
_solutionsSampleSolutionId = CType(SampleSolutionResults.SolutionId, Guid)
End If
If SampleSolutionResults Is Nothing Then
_solutionsSampleSolutionId = _serviceProxy.Create(solution)
End If
Recuperare una soluzione
Per recuperare una soluzione specifica è possibile utilizzare l'elemento UniqueName della soluzione. Ogni organizzazione disporrà di una soluzione predefinita con un valore GUID constante: FD140AAF-4DF4-11DD-BD17-0019B9312238.
In questo esempio viene illustrato come recuperare i dati per una soluzione con il nome univoco ”samplesolution”. Una soluzione con lo stesso nome viene creata in Creare una soluzione.
// 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];
' Retrieve a solution
Dim solutionUniqueName As String = "samplesolution"
Dim querySampleSolution As QueryExpression =
New QueryExpression With {
.EntityName = solution.EntityLogicalName,
.ColumnSet = New ColumnSet(New String() {"publisherid",
"installedon",
"version",
"versionnumber",
"friendlyname"}),
.Criteria = New FilterExpression()
}
querySampleSolution.Criteria.AddCondition("uniquename", ConditionOperator.Equal, solutionUniqueName)
Dim SampleSolution As Solution =
CType(_serviceProxy.RetrieveMultiple(querySampleSolution).Entities(0), Solution)
Aggiungere un nuovo componente di soluzione
In questo esempio viene illustrato come creare un componente di soluzione associato a una soluzione specifica. Se non si associa il componente di soluzione a una soluzione specifica quando viene creato, verrà solo aggiunto alla soluzione predefinita e sarà necessario aggiungerlo a una soluzione manualmente o tramite il codice incluso in Aggiungere un componente di soluzione esistente.
Questo codice crea un nuovo set di opzioni globale e lo aggiunge alla soluzione con nome univoco uguale a _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);
Dim optionSetMetadata As New OptionSetMetadata() With {
.Name = _globalOptionSetName,
.DisplayName = New Label("Example Option Set", _languageCode),
.IsGlobal = True,
.OptionSetType = OptionSetType.Picklist
}
optionSetMetadata.Options.AddRange(
{
New OptionMetadata(New Label("Option 1", _languageCode), 1),
New OptionMetadata(New Label("Option 2", _languageCode), 2)
}
)
Dim createOptionSetRequest As CreateOptionSetRequest =
New CreateOptionSetRequest With {
.OptionSet = optionSetMetadata
}
createOptionSetRequest.SolutionUniqueName = _primarySolutionName
_serviceProxy.Execute(createOptionSetRequest)
Aggiungere un componente di soluzione esistente
In questo esempio viene illustrato come aggiungere un componente di soluzione esistente a una soluzione.
Il codice seguente utilizza AddSolutionComponentRequest per aggiungere l'entità Account come componente di soluzione a una soluzione non gestita.
// 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);
' Add an existing Solution Component
'Add the Account entity to the solution
Dim retrieveForAddAccountRequest As New RetrieveEntityRequest() With {
.LogicalName = Account.EntityLogicalName
}
Dim retrieveForAddAccountResponse As RetrieveEntityResponse =
CType(_serviceProxy.Execute(retrieveForAddAccountRequest),
RetrieveEntityResponse)
Dim addReq As New AddSolutionComponentRequest() With {
.ComponentType = componenttype.Entity,
.ComponentId = CType(retrieveForAddAccountResponse.EntityMetadata.MetadataId, Guid),
.SolutionUniqueName = solution.UniqueName
}
_serviceProxy.Execute(addReq)
Rimuovere un componente di soluzione
In questo esempio viene illustrato come rimuovere un componente di soluzione da una soluzione non gestita. Il codice seguente utilizza RemoveSolutionComponentRequest per rimuovere un componente di soluzione dell'entità da una soluzione non gestita.solution.UniqueName fa riferimento alla soluzione creata in Creare una soluzione.
// 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);
' Remove a Solution Component
'Remove the Account entity from the solution
Dim retrieveForRemoveAccountRequest As New RetrieveEntityRequest() With {
.LogicalName = Account.EntityLogicalName
}
Dim retrieveForRemoveAccountResponse As RetrieveEntityResponse =
CType(_serviceProxy.Execute(retrieveForRemoveAccountRequest), RetrieveEntityResponse)
Dim removeReq As New RemoveSolutionComponentRequest() With {
.ComponentId = CType(retrieveForRemoveAccountResponse.EntityMetadata.MetadataId, Guid),
.ComponentType = componenttype.Entity,
.SolutionUniqueName = solution.UniqueName
}
_serviceProxy.Execute(removeReq)
Esportare o comprimere una soluzione
In questo esempio viene illustrato come esportare una soluzione non gestita o comprimere una soluzione gestita. Il codice utilizza ExportSolutionRequest per esportare un file compresso che rappresenta una soluzione non gestita. L'opzione per creare una soluzione gestita può essere impostata tramite la proprietà Managed. In questo esempio viene salvato un file denominato samplesolution.zip nella cartella 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);
' Export or package a solution
'Export an a solution
Dim outputDir As String = "C:\temp\"
Dim exportSolutionRequest As New ExportSolutionRequest()
exportSolutionRequest.Managed = False
exportSolutionRequest.SolutionName = solution.UniqueName
Dim exportSolutionResponse As ExportSolutionResponse =
CType(_serviceProxy.Execute(exportSolutionRequest), ExportSolutionResponse)
Dim exportXml() As Byte = exportSolutionResponse.ExportSolutionFile
Dim filename As String = solution.UniqueName & ".zip"
File.WriteAllBytes(outputDir & filename, exportXml)
Console.WriteLine("Solution exported to {0}.", outputDir & filename)
Installare o aggiornare una soluzione
In questo esempio viene illustrato come installare o aggiornare una soluzione con il messaggio ImportSolutionRequest.
È possibile utilizzare entità ImportJob per acquisire i dati relativi all'esito dell'importazione.
Nell'esempio seguente viene illustrato come importare una soluzione senza registrare l'esito.
// 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);
' Install or Upgrade a Solution
Dim fileBytes() As Byte = File.ReadAllBytes(ManagedSolutionLocation)
Dim impSolReq As New ImportSolutionRequest() With {
.CustomizationFile = fileBytes
}
_serviceProxy.Execute(impSolReq)
Console.WriteLine("Imported Solution from {0}", ManagedSolutionLocation)
Registrare l'esito dell'importazione
Quando si specifica ImportJobId per ImportSolutionRequest, è possibile utilizzare il valore per eseguire una query sull'entità ImportJob per lo stato dell'importazione.
ImportJobId può essere utilizzato inoltre per scaricare il file di registro dell'importazione utilizzando il messaggio RetrieveFormattedImportJobResultsRequest.
Recuperare i dati del processo di importazione
Nell'esempio seguente viene illustrato come recuperare il record del processo di importazione e il contenuto dell'attributo 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);
}
}
' Monitor import success
Dim fileBytesWithMonitoring() As Byte = File.ReadAllBytes(ManagedSolutionLocation)
Dim impSolReqWithMonitoring As New ImportSolutionRequest() With {
.CustomizationFile = fileBytes,
.ImportJobId = Guid.NewGuid()
}
_serviceProxy.Execute(impSolReqWithMonitoring)
Console.WriteLine("Imported Solution with Monitoring from {0}", ManagedSolutionLocation)
Dim job As ImportJob =
CType(_serviceProxy.Retrieve(ImportJob.EntityLogicalName,
impSolReqWithMonitoring.ImportJobId,
New ColumnSet(New String() {"data", "solutionname"})),
ImportJob)
Dim doc As New System.Xml.XmlDocument()
doc.LoadXml(job.Data)
Dim ImportedSolutionName As String = doc.SelectSingleNode("//solutionManifest/UniqueName").InnerText
Dim SolutionImportResult As String = 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.
Dim optionSets As System.Xml.XmlNodeList = doc.SelectNodes("//optionSets/optionSet")
For Each node As System.Xml.XmlNode In optionSets
Dim OptionSetName As String = node.Attributes("LocalizedName").Value
Dim result As String = node.FirstChild.Attributes("result").Value
If result = "success" Then
Console.WriteLine("{0} result: {1}", OptionSetName, result)
Else
Dim errorCode As String = node.FirstChild.Attributes("errorcode").Value
Dim errorText As String = node.FirstChild.Attributes("errortext").Value
Console.WriteLine("{0} result: {1} Code: {2} Description: {3}", OptionSetName, result, errorCode, errorText)
End If
Next node
Il contenuto della proprietà Data è una stringa che rappresenta un file XML. Di seguito è riportato un esempio acquisito tramite il codice nell'esempio. Questa soluzione gestita conteneva un singolo set di opzioni globale denominato 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/en-us/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>
Eliminare una soluzione
In questo esempio viene illustrato come eliminare una soluzione. Nell'esempio seguente viene illustrato come recuperare una soluzione utilizzando la soluzione uniquename ed estrarre l'elemento solutionid dai risultati. Utilizza solutionid con IOrganizationService. Metodo 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);
' Delete a solution
Dim queryImportedSolution As QueryExpression =
New QueryExpression With {
.EntityName = solution.EntityLogicalName,
.ColumnSet = New ColumnSet(New String() {"solutionid", "friendlyname"}),
.Criteria = New FilterExpression()
}
queryImportedSolution.Criteria.AddCondition("uniquename", ConditionOperator.Equal, ImportedSolutionName)
Dim ImportedSolution As Solution =
CType(_serviceProxy.RetrieveMultiple(queryImportedSolution).Entities(0), Solution)
_serviceProxy.Delete(solution.EntityLogicalName, CType(ImportedSolution.SolutionId, Guid))
Console.WriteLine("Deleted the {0} solution.", ImportedSolution.FriendlyName)
Rilevare le dipendenze delle soluzioni
In questo esempio viene illustrato come creare una report che indica le dipendenze tra i componenti di soluzione.
Con questo codice sarà possibile:
Recuperare tutti i componenti per una soluzione.
Recuperare tutte le dipendenze per ogni componente.
Per ogni dipendenza trovata, visualizzare un report che descrive la dipendenza.
// 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);
}
}
' Grab all Solution Components for a solution.
Dim componentQuery As QueryByAttribute =
New QueryByAttribute With {
.EntityName = SolutionComponent.EntityLogicalName,
.ColumnSet = New ColumnSet("componenttype", "objectid",
"solutioncomponentid", "solutionid")
}
componentQuery.Attributes.Add("solutionid")
componentQuery.Values.Add(_primarySolutionId)
' In your code, this value would probably come from another query.
Dim allComponents As IEnumerable(Of SolutionComponent) =
_serviceProxy.RetrieveMultiple(componentQuery).Entities.Cast(Of SolutionComponent)()
For Each component As SolutionComponent In allComponents
' For each solution component, retrieve all dependencies for the component.
Dim dependentComponentsRequest As RetrieveDependentComponentsRequest =
New RetrieveDependentComponentsRequest With {
.ComponentType = component.ComponentType.Value,
.ObjectId = component.ObjectId.Value
}
Dim dependentComponentsResponse As RetrieveDependentComponentsResponse =
CType(_serviceProxy.Execute(dependentComponentsRequest),
RetrieveDependentComponentsResponse)
' If there are no dependent components, we can ignore this component.
If dependentComponentsResponse.EntityCollection.Entities.Any() = False Then
Continue For
End If
' 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
For Each d As Dependency In dependentComponentsResponse.EntityCollection.Entities
DependencyReport(d)
Next d
Next component
Il metodo DependencyReport è nel seguente esempio di codice.
Report di dipendenza
Il metodo DependencyReport fornisce un messaggio più semplice da usare in base alle informazioni disponibili nella dipendenza.
Nota
In questo esempio il metodo è solo parzialmente implementato. Vengono visualizzati messaggi solo per i componenti di soluzione di un set di opzioni e di attributo.
/// <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);
}
''' <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 Sub DependencyReport(ByVal dependency As Dependency)
'These strings represent parameters for the message.
Dim dependentComponentName As String = ""
Dim dependentComponentTypeName As String = ""
Dim dependentComponentSolutionName As String = ""
Dim requiredComponentName As String = ""
Dim requiredComponentTypeName As String = ""
Dim requiredComponentSolutionName As String = ""
'The ComponentType global Option Set contains options for each possible component.
Dim componentTypeRequest As RetrieveOptionSetRequest =
New RetrieveOptionSetRequest With {
.Name = "componenttype"
}
Dim componentTypeResponse As RetrieveOptionSetResponse =
CType(_serviceProxy.Execute(componentTypeRequest), RetrieveOptionSetResponse)
Dim componentTypeOptionSet As OptionSetMetadata =
CType(componentTypeResponse.OptionSetMetadata, OptionSetMetadata)
' Match the Component type with the option value and get the label value of the option.
For Each opt As OptionMetadata In componentTypeOptionSet.Options
If dependency.DependentComponentType.Value = opt.Value Then
dependentComponentTypeName = opt.Label.UserLocalizedLabel.Label
End If
If dependency.RequiredComponentType.Value = opt.Value Then
requiredComponentTypeName = opt.Label.UserLocalizedLabel.Label
End If
Next opt
'The name or display name of the compoent is retrieved in different ways depending on the component type
dependentComponentName = getComponentName(dependency.DependentComponentType.Value,
CType(dependency.DependentComponentObjectId,
Guid))
requiredComponentName = getComponentName(dependency.RequiredComponentType.Value,
CType(dependency.RequiredComponentObjectId,
Guid))
' Retrieve the friendly name for the dependent solution.
Dim dependentSolution As Solution =
CType(_serviceProxy.Retrieve(Solution.EntityLogicalName,
CType(dependency.DependentComponentBaseSolutionId, Guid),
New ColumnSet("friendlyname")),
Solution)
dependentComponentSolutionName = dependentSolution.FriendlyName
' Retrieve the friendly name for the required solution.
Dim requiredSolution As Solution =
CType(_serviceProxy.Retrieve(Solution.EntityLogicalName,
CType(dependency.RequiredComponentBaseSolutionId,
Guid),
New ColumnSet("friendlyname")),
Solution)
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)
End Sub
Rilevare se un componente di soluzione potrebbe essere stato eliminato
Utilizzare il messaggio RetrieveDependenciesForDeleteRequest per identificare tutti i componenti di soluzione che impedirebbero a un componente di soluzione specificato di essere eliminato. Il seguente esempio di codice cerca gli attributi tramite un noto set di opzioni globale. Qualsiasi attributo che utilizza il set di opzioni globale impedirebbe al set di opzioni globale da essere eliminato.
// 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);
}
}
}
' Use the RetrieveOptionSetRequest message to retrieve
' a global option set by it's name.
Dim retrieveOptionSetRequest_Renamed As RetrieveOptionSetRequest =
New RetrieveOptionSetRequest With {.Name = _globalOptionSetName}
' Execute the request.
Dim retrieveOptionSetResponse_Renamed As RetrieveOptionSetResponse =
CType(_serviceProxy.Execute(retrieveOptionSetRequest_Renamed), RetrieveOptionSetResponse)
_globalOptionSetId = retrieveOptionSetResponse_Renamed.OptionSetMetadata.MetadataId
If _globalOptionSetId IsNot Nothing Then
'Use the global OptionSet MetadataId with the appropriate componenttype
' to call RetrieveDependenciesForDeleteRequest
Dim retrieveDependenciesForDeleteRequest_Renamed As RetrieveDependenciesForDeleteRequest =
New RetrieveDependenciesForDeleteRequest With
{
.ComponentType = CInt(Fix(componenttype.OptionSet)),
.ObjectId = CType(_globalOptionSetId, Guid)
}
Dim retrieveDependenciesForDeleteResponse_Renamed As RetrieveDependenciesForDeleteResponse =
CType(_serviceProxy.Execute(retrieveDependenciesForDeleteRequest_Renamed),
RetrieveDependenciesForDeleteResponse)
Console.WriteLine("")
For Each d As Dependency In retrieveDependenciesForDeleteResponse_Renamed _
.EntityCollection.Entities
If d.DependentComponentType.Value = 2 Then 'Just testing for Attributes
Dim attributeLabel As String = ""
Dim retrieveAttributeRequest_Renamed As RetrieveAttributeRequest =
New RetrieveAttributeRequest With
{
.MetadataId = CType(d.DependentComponentObjectId, Guid)
}
Dim retrieveAttributeResponse_Renamed As RetrieveAttributeResponse =
CType(_serviceProxy.Execute(retrieveAttributeRequest_Renamed),
RetrieveAttributeResponse)
Dim attmet As AttributeMetadata = retrieveAttributeResponse_Renamed.AttributeMetadata
attributeLabel = attmet.DisplayName.UserLocalizedLabel.Label
Console.WriteLine("An {0} named {1} will prevent deleting the {2} global option set.",
CType(d.DependentComponentType.Value, componenttype),
attributeLabel, _globalOptionSetName)
End If
Next d
End If
Vedere anche
Comprimere e distribuire estensioni con soluzioni
Introduzione alle soluzioni
Pianificare per lo sviluppo di soluzioni
Traccia delle dipendenze dei componenti di soluzione
Creare, esportare o importare una soluzione non gestita
Creare, installare e aggiornare una soluzione gestita
Disinstallare o eliminare una soluzione
Entità soluzione
Esempio: utilizzare le soluzioni
Esempio: rilevare le dipendenze delle soluzioni
Microsoft Dynamics 365
© 2017 Microsoft. Tutti i diritti sono riservati. Copyright