コード例 #1
0
        private void Load()
        {
            var fileInfo     = new FileInfo(AssemblyFile);
            var assemblyName = fileInfo.Name.Substring(0,
                                                       fileInfo.Name.LastIndexOf(fileInfo.Extension, StringComparison.Ordinal));

            var bytes           = File.ReadAllBytes(AssemblyFile);
            var assemblyContent = Convert.ToBase64String(bytes);

            //okay this crazy stuff is to load the assembly dll in a different app domain
            //that way it may be loaded, inspected, then released (removing any lock on the assembly file)
            //when the appdomain is unloaded
            //the loading and inspection is done in an object PluginAssemblyReader
            //which is loaded in the context of the separate app domain
            var myDomain = AppDomain.CreateDomain("JosephM.XRM.VSIX.DeployAssemblyCommand", null, null);

            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
            IEnumerable <PluginAssemblyReader.PluginType> plugins;

            try
            {
                var reader =
                    (PluginAssemblyReader)
                    myDomain.CreateInstanceFrom(
                        Assembly.GetExecutingAssembly().Location,
                        typeof(PluginAssemblyReader).FullName).Unwrap();
                var loadedPlugins = reader.LoadTypes(AssemblyFile);
                plugins =
                    loadedPlugins.Select(p => new PluginAssemblyReader.PluginType(p.Type, p.TypeName)).ToArray();
            }
            finally
            {
                AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
                if (null != myDomain)
                {
                    AppDomain.Unload(myDomain);
                }
            }
            if (!plugins.Any())
            {
                throw new Exception("There are no plugin classes in the assembly");
            }

            _pluginAssembly        = new PluginAssembly();
            PluginAssembly.Name    = assemblyName;
            PluginAssembly.Content = assemblyContent;

            var preAssembly = Service.GetFirst(Entities.pluginassembly, Fields.pluginassembly_.name, assemblyName);

            if (preAssembly != null)
            {
                PluginAssembly.Id            = preAssembly.Id;
                PluginAssembly.IsolationMode = preAssembly.GetOptionKey(Fields.pluginassembly_.isolationmode).ParseEnum <PluginAssembly.IsolationMode_>();
            }

            var pluginTypes = new List <PluginType>();

            PluginAssembly.PluginTypes = pluginTypes;
            foreach (var item in plugins)
            {
                var pluginType = new PluginType();
                pluginType.TypeName = item.TypeName;
                //get the type name after "." as the name
                var startIndex = item.TypeName.LastIndexOf(".", StringComparison.Ordinal);
                if (startIndex != -1 && item.TypeName.Length > startIndex + 1)
                {
                    startIndex = startIndex + 1;
                }
                else
                {
                    startIndex = 0;
                }
                pluginType.FriendlyName       = item.TypeName.Substring(startIndex);
                pluginType.Name               = item.TypeName.Substring(startIndex);
                pluginType.IsWorkflowActivity = item.Type == PluginAssemblyReader.PluginType.XrmPluginType.WorkflowActivity;
                pluginType.InAssembly         = true;
                pluginTypes.Add(pluginType);
            }
            PreTypeRecords = preAssembly == null
                ? new IRecord[0]
                : Service.RetrieveAllAndClauses(Entities.plugintype, new[] { new Condition(Fields.plugintype_.pluginassemblyid, ConditionType.Equal, PluginAssembly.Id) });

            foreach (var item in PreTypeRecords)
            {
                var matchingItems =
                    pluginTypes.Where(pt => item.GetStringField(Fields.plugintype_.typename) == pt.TypeName);
                var matchingItem = matchingItems.Any()
                    ? matchingItems.First()
                    : null;
                if (matchingItem == null)
                {
                    //if the plugin was not loaded by the types in the assembly
                    //then create a new one
                    matchingItem = new PluginType();
                    pluginTypes.Add(matchingItem);
                    matchingItem.TypeName           = item.GetStringField(Fields.plugintype_.typename);
                    matchingItem.IsWorkflowActivity = item.GetBoolField(Fields.plugintype_.isworkflowactivity);
                }

                matchingItem.Id           = item.Id;
                matchingItem.FriendlyName = item.GetStringField(Fields.plugintype_.friendlyname);
                matchingItem.Name         = item.GetStringField(Fields.plugintype_.name);
                matchingItem.GroupName    = item.GetStringField(Fields.plugintype_.workflowactivitygroupname);
            }

            foreach (var item in pluginTypes)
            {
                var matchingItems =
                    PreTypeRecords.Where(pt => pt.GetStringField(Fields.plugintype_.typename) == item.TypeName);
                if (matchingItems.Any())
                {
                    var matchingItem = matchingItems.First();
                    item.Id        = matchingItem.Id;
                    item.Name      = matchingItem.GetStringField(Fields.plugintype_.friendlyname);
                    item.GroupName = matchingItem.GetStringField(Fields.plugintype_.workflowactivitygroupname);
                }
            }
        }
コード例 #2
0
        protected override void CompleteDialogExtention()
        {
            try
            {
                var responses = new List <PluginTypeErrors>();


                var service = Service;

                var removedPlugins = PreTypeRecords.Where(ptr => PluginAssembly.PluginTypes.All(pt => pt.Id != ptr.Id)).ToArray();
                foreach (var record in removedPlugins)
                {
                    try
                    {
                        service.Delete(record);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(string.Format("Error deleting plugin {0}", record.GetStringField(Fields.plugintype_.name)), ex);
                    }
                }

                //okay first create/update the plugin assembly
                var assemblyRecord = service.NewRecord(Entities.pluginassembly);
                assemblyRecord.Id = PluginAssembly.Id;
                if (PluginAssembly.Id != null)
                {
                    assemblyRecord.SetField(Fields.pluginassembly_.pluginassemblyid, PluginAssembly.Id, service);
                }
                assemblyRecord.SetField(Fields.pluginassembly_.name, PluginAssembly.Name, service);
                assemblyRecord.SetField(Fields.pluginassembly_.content, PluginAssembly.Content, service);
                assemblyRecord.SetField(Fields.pluginassembly_.isolationmode, (int)PluginAssembly.IsolationMode, service);
                var matchField = Fields.pluginassembly_.pluginassemblyid;

                var assemblyLoadResponse = service.LoadIntoCrm(new[] { assemblyRecord }, matchField);
                if (assemblyLoadResponse.Errors.Any())
                {
                    throw new Exception("Error Deploying Assembly", assemblyLoadResponse.Errors.Values.First());
                }
                //okay create/update the plugin types
                var pluginTypes = new List <IRecord>();
                foreach (var pluginType in PluginAssembly.PluginTypes)
                {
                    var pluginTypeRecord = service.NewRecord(Entities.plugintype);
                    pluginTypeRecord.Id = pluginType.Id;
                    if (pluginType.Id != null)
                    {
                        pluginTypeRecord.SetField(Fields.plugintype_.plugintypeid, pluginType.Id, service);
                    }
                    pluginTypeRecord.SetField(Fields.plugintype_.typename, pluginType.TypeName, service);
                    pluginTypeRecord.SetField(Fields.plugintype_.name, pluginType.Name, service);
                    pluginTypeRecord.SetField(Fields.plugintype_.friendlyname, pluginType.FriendlyName, service);
                    pluginTypeRecord.SetField(Fields.plugintype_.assemblyname, PluginAssembly.Name, service);
                    pluginTypeRecord.SetLookup(Fields.plugintype_.pluginassemblyid, assemblyRecord.Id, assemblyRecord.Type);
                    pluginTypeRecord.SetField(Fields.plugintype_.isworkflowactivity, pluginType.IsWorkflowActivity, service);
                    pluginTypeRecord.SetField(Fields.plugintype_.workflowactivitygroupname, pluginType.GroupName, service);
                    pluginTypes.Add(pluginTypeRecord);
                }

                var pluginTypeLoadResponse = service.LoadIntoCrm(pluginTypes, Fields.plugintype_.plugintypeid);

                foreach (var item in pluginTypeLoadResponse.Errors)
                {
                    var responseItem = new PluginTypeErrors();
                    responseItem.Name      = item.Key.GetStringField(Fields.plugintype_.typename);
                    responseItem.Exception = item.Value;
                    responses.Add(responseItem);
                }
                CompletionItem = new PluginTypeDeployResponse()
                {
                    Responses = responses
                };
                //CompletionItems.AddRange(responses);

                //add plugin assembly to the solution
                var componentType = OptionSets.SolutionComponent.ObjectTypeCode.PluginAssembly;
                var itemsToAdd    = assemblyLoadResponse.Created.Union(assemblyLoadResponse.Updated);
                if (PackageSettings.AddToSolution)
                {
                    service.AddSolutionComponents(PackageSettings.Solution.Id, componentType, itemsToAdd.Select(i => i.Id));
                }

                if (responses.Any())
                {
                    CompletionMessage = "There Were Errors Thrown Updating The Plugins";
                }
                else
                {
                    CompletionMessage = "Plugins Updated";
                }
            }
            catch (Exception ex)
            {
                CompletionMessage = "Fatal Error: " + ex.Message + Environment.NewLine + ex.XrmDisplayString();
            }
        }