private Guid _CreateAssembly(byte[] assemblyData, bool sandbox) { UpdateStatus("Creating assembly ... ", 1); var assemblyInfo = AssemblyHelper.GetAssemblyInfo(typeof(IPlugin).FullName); var assembly = new PluginAssembly { Name = DteHelper.GetProjectName(), IsolationMode = (sandbox ? PluginAssembly.Enums.IsolationMode.Sandbox : PluginAssembly.Enums.IsolationMode.None).ToOptionSetValue(), Content = Convert.ToBase64String(assemblyData), SourceType = PluginAssembly.Enums.SourceType.Database.ToOptionSetValue(), Culture = assemblyInfo.CultureInfo.LCID == CultureInfo.InvariantCulture.LCID ? "neutral" : assemblyInfo.CultureInfo.Name }; Context.AddObject(assembly); UpdateStatus("Saving new assembly to CRM ..."); Context.SaveChanges(); Id = assembly.Id; AddNewTypes(GetExistingTypeNames()); //UpdateStatus("Saving new types to CRM ..."); //Context.SaveChanges(); UpdateStatus("Finished creating assembly. ID => " + Id, -1); OnRegActionTaken(RegistrationEvent.Create); return(Id); }
private void AddNewTypes(ICollection <string> existingTypeNames) { UpdateStatus("Adding new types ... ", 1); var pluginClasses = AssemblyHelper.GetClasses <IPlugin>(); var wfClasses = AssemblyHelper.GetClasses <CodeActivity>(); pluginClasses.Where(pluginType => !existingTypeNames.Contains(pluginType)).ToList() .ForEach(pluginType => { var className = pluginType.Split('.')[pluginType.Split('.').Length - 1]; UpdateStatus($"Adding plugin '{className}' ... ", 1); var newType = new PluginType { PluginTypeId = Guid.NewGuid(), Name = pluginType, TypeName = pluginType, FriendlyName = className, PluginAssemblyId = new EntityReference(PluginAssembly.EntityLogicalName, Id) }; Service.Create(newType); //Context.AddObject(newType); UpdateStatus($"Finished adding plugin '{className}'.", -1); }); // create new types wfClasses.Where(pluginType => !existingTypeNames.Contains(pluginType)).ToList() .ForEach(pluginType => { var className = pluginType.Split('.')[pluginType.Split('.').Length - 1]; UpdateStatus($"Adding custom step '{className}' ... ", 1); var newType = new PluginType { PluginTypeId = Guid.NewGuid(), Name = pluginType, TypeName = pluginType, FriendlyName = className, PluginAssemblyId = new EntityReference(PluginAssembly.EntityLogicalName, Id), WorkflowActivityGroupName = string.Format(CultureInfo.InvariantCulture, "{0} ({1})", DteHelper.GetProjectName(), AssemblyHelper.GetAssemblyVersion()) }; Service.Create(newType); //Context.AddObject(newType); UpdateStatus($"Finished adding custom step '{className}'.", -1); }); UpdateStatus("Finished adding new types.", -1); }
private void RefreshTypes(List <string> existingTypeNames) { var wfClasses = AssemblyHelper.GetClasses <CodeActivity>(); if (wfClasses.Any()) { UpdateStatus("Refreshing custom steps ... ", 1); // create new types wfClasses.Where(existingTypeNames.Contains).ToList() .ForEach(pluginType => { var className = pluginType.Split('.')[pluginType.Split('.').Length - 1]; UpdateStatus($"Refreshing '{className}' ... ", 1); var typeId = (from typeQ in Context.PluginTypeSet where typeQ.TypeName == pluginType select typeQ.PluginTypeId).First(); if (typeId == null) { throw new Exception("Failed to get plugin type ID."); } //var updatedType = Context.PluginTypeSet.FirstOrDefault(entity => entity.PluginTypeId == typeId) // ?? new PluginType(); var updatedType = new PluginType { PluginTypeId = typeId, Name = pluginType, TypeName = pluginType, FriendlyName = className, PluginAssemblyId = new EntityReference(PluginAssembly.EntityLogicalName, Id), WorkflowActivityGroupName = string.Format(CultureInfo.InvariantCulture, "{0} ({1})", DteHelper.GetProjectName(), AssemblyHelper.GetAssemblyVersion()) }; //if (updatedType.Id == Guid.Empty) //{ // updatedType.Id = typeId.Value; //} //Context.ConfirmAttached(updatedType); //Context.UpdateObject(updatedType); UpdateStatus($"Refreshing type '{updatedType.Id}' ... "); Service.Update(updatedType); UpdateStatus($"Finished refreshing '{className}'.", -1); }); UpdateStatus("Finished refreshing custom steps.", -1); } }
/// <summary> /// This function is the callback used to execute a command when the a menu item is clicked. /// See the Initialize method to see how the menu item is associated to this function using /// the OleMenuCommandService service and the MenuCommand class. /// </summary> private async Task RegisterModifyPluginCallbackAsync(object sender, EventArgs args) { try { var session = Math.Abs(DateTime.Now.ToString(CultureInfo.CurrentCulture).GetHashCode()); Status.Update($">>>>> Starting new session: {session} <<<<<"); var selected = DteHelper.GetSelectedProjects().ToArray(); if (!selected.Any()) { throw new UserException("Please select a project first."); } foreach (var project in selected) { Status.Update($">>> Processing project: {DteHelper.GetProjectName(project)} <<<"); DteHelper.SetCurrentProject(project); AssemblyHelper.BuildProject(); await RegisterModifyPluginAsync(); Status.Update($"^^^ Finished processing project: {DteHelper.GetProjectName(project)} ^^^"); } Status.Update($"^^^^^ Finished session: {session} ^^^^^"); } catch (UserException e) { VsShellUtilities.ShowMessageBox(ServiceProvider.GlobalProvider, e.Message, "Error", OLEMSGICON.OLEMSGICON_WARNING, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); } catch (Exception e) { var error1 = "[ERROR] " + e.Message + (e.InnerException != null ? "\n" + "[ERROR] " + e.InnerException.Message : ""); Status.Update(error1); Status.Update(e.StackTrace); Status.Update("Unable to register assembly, see error above."); var error2 = e.Message + "\n" + e.StackTrace; MessageBox.Show(error2, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { Status.Update(">>>>> DONE! <<<<<"); } }
private async Task UpdatePluginAsync() { var settingsArray = Configuration.LoadSettings(); var settings = settingsArray.GetSelectedSettings(); // if no connection info, then it's a new run if (settings.ConnectionString.IsEmpty()) { await RegisterModifyPluginAsync(); } else { var connectionManager = new ConnectionManager(settings.ConnectionString); var registrationFeedback = new RegistrationFeedback(); var registrationLogger = new DefaultPluginRegLogger(m => Status.Update(m)); var assemblyPath = AssemblyHelper.GetAssemblyPath(); var assemblyName = AssemblyHelper.GetAssemblyName(); var registration = new AssemblyRegistration(settings, assemblyPath, connectionManager, registrationFeedback); registration.RegLogEntryAdded += (o, args) => { lock (registration.LoggingLock) { Status.Update(args.Message); } }; // if the assembly is registered, update if (CrmAssemblyHelpers.IsAssemblyRegistered(assemblyName, connectionManager, registrationLogger)) { registration.UpdateAssembly(null); Status.Update($"Ran update on: {Regex.Replace(settings.ConnectionString, @"Password\s*?=.*?(?:;{0,1}$|;)", "Password=********;").Replace("\r\n", " ")}."); Status.Update($"For project: {DteHelper.GetProjectName(DteHelper.CurrentProject)}."); } else { // else open dialogue await RegisterModifyPluginAsync(); } } }
private void UpdatePlugin(Project project) { DteHelper.SetCurrentProject(project); var settingsArray = Configuration.LoadConfigs(); var settings = settingsArray.GetSelectedSettings(); // if an ID does not exist and no connection info, then it's a new run if (settings.Id == Guid.Empty && (string.IsNullOrEmpty(settings.ServerName) || string.IsNullOrEmpty(settings.Username))) { CopySettings(); RegisterModifyPlugin(project); } else { using (var service = ConnectionHelper.GetConnection(settings.GetOrganizationCrmConnectionString())) { var context = new XrmServiceContext(service); var registration = new AssemblyRegistration(context, service); registration.PropertyChanged += (o, args) => { try { switch (args.PropertyName) { case "LogMessage": lock (registration.LoggingLock) { Status.Update(registration.LogMessage); } break; } } catch { // ignored } }; // if the assembly is registered, get ID and update if (CrmAssemblyHelper.IsAssemblyRegistered(context)) { var id = settings.Id == Guid.Empty ? CrmAssemblyHelper.GetAssemblyId(context) : settings.Id; registration.UpdateAssembly(id, null); Status.Update($"Ran update on: {settings.ServerName} - {settings.CrmOrg} - {settings.Username}."); Status.Update($"For project: {DteHelper.GetProjectName(project)}."); } else { // else, reset and open dialogue // reset ID settings.Id = Guid.Empty; Configuration.SaveConfigs(settingsArray); RegisterModifyPlugin(project); } } } }