/// <summary> /// Initializes a new instance of the <see cref="CodeToolsMainView"/> class. /// </summary> public CodeToolsMainView() : base(null) { this.Caption = "Coddee tools"; // This is the user control hosted by the tool window; Note that, even if this class implements IDisposable, // we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on // the object returned by the Content property. UISynchronizationContext.SetContext(SynchronizationContext.Current); _container = new CoddeeUnityContainer(); _container.RegisterInstance <ILogger, LogAggregator>(); BuilderHelper.RegisterLoggers(new LoggerOptions(LoggerTypes.ApplicationConsole, LogRecordTypes.Debug), _container); var modules = _container.Resolve <ApplicationModulesManager>(); _logger = (LogAggregator)_container.Resolve <ILogger>(); _vsHelper = _container.RegisterInstance <VsHelper, VsHelper>(); _container.RegisterInstance <ISolutionEventsHelper>(_vsHelper); _container.RegisterInstance <ISolutionHelper>(_vsHelper); modules.RegisterModule(CoreModuleDefinitions.Modules); modules.RegisterModule(WindowsModuleDefinitions.Modules); modules.RegisterModule(WPFModuleDefinitions.Modules); modules.InitializeAutoModules().Wait(); Application.Current.Resources.Add("ApplicationAccentColorLighter", new SolidColorBrush((Color)ColorConverter.ConvertFromString("#444F5A"))); Application.Current.Resources.Add("ApplicationAccentColor", new SolidColorBrush((Color)ColorConverter.ConvertFromString("#283645"))); Application.Current.Resources.Add("ApplicationAccentColorDarker", new SolidColorBrush((Color)ColorConverter.ConvertFromString("#151824"))); }
/// <summary> /// Called after the plugin process has been started, and connection has been made with /// this Plugin Manager instance Always call this base method if it is inherited. /// </summary> /// <param name="pluginInstance">The connected plugin instance</param> /// <param name="plugin">The connected plugin service</param> protected virtual void OnPluginConnected(TPluginInstance pluginInstance, IPlugin plugin) { LogTo.Information($"Connected {pluginInstance.Denomination} {pluginInstance.Package.Id}."); UISynchronizationContext.Send(_ => { pluginInstance.OnConnected(plugin); }, null); }
/// <summary> /// Attempts to update plugin <paramref name="packageId" />. If no /// <paramref name="version" /> is specified, the latest available version will be installed. /// </summary> /// <param name="packageId">The plugin package id to update</param> /// <param name="version">Optional version to install</param> /// <param name="allowPrereleaseVersions">Whether to include pre-release versions</param> /// <param name="cancellationToken"></param> /// <returns>Success of operation</returns> /// <exception cref="ArgumentException"><paramref name="packageId" /> is empty</exception> /// <exception cref="ArgumentException">Plugin <paramref name="packageId" /> is not installed</exception> /// <exception cref="ArgumentNullException"></exception> public async Task <bool> UpdatePluginAsync( string packageId, NuGetVersion version = null, bool allowPrereleaseVersions = false, CancellationToken cancellationToken = default) { var pluginInstance = AllPlugins.FirstOrDefault(pi => pi.Package.Id == packageId); if (await StopPlugin(pluginInstance) == false) { LogAdapter.Warning($"Failed to stop plugin {packageId}, aborting update."); return(false); } using (await PMLock.WriterLockAsync()) { var success = await PackageManager.UpdateAsync( packageId, version, allowPrereleaseVersions, cancellationToken); UISynchronizationContext.Send(() => PackageManager.FindInstalledPluginById(packageId)?.RaiseVersionChanged()); return(success); } }
private void OnSetResolutionCommand(object sender, ConsoleCommandArgs e) { UISynchronizationContext.ExecuteOnUIContext(() => { var window = Resolve <IShell>() as Window; if (!e.Arguments.ContainsKey("/r")) { e.Result.Add("You must specify the /r argument."); e.Handled = false; return; } var res = e.Arguments["/r"]; if (res.ToLower() == "fullscreen") { window.WindowState = WindowState.Maximized; } else { var resWH = res.Split('x'); window.WindowState = WindowState.Normal; window.Height = double.Parse(resWH[0]); window.Width = double.Parse(resWH[1]); } }); e.Handled = true; }
/// <inheritdoc /> public override void Start() { _systemApplication.Dispatcher.Invoke(() => { UISynchronizationContext.SetContext(SynchronizationContext.Current); }); base.Start(); }
private void DoPrint(IBackgroundTaskContext context) { try { if (_selectPresentationsInformations == null || _selectPresentationsInformations.Count == 0) { return; } Thread.Sleep(20); BackgroundTaskReportStatus(context, "Dicom打印开始", 0); Thread.Sleep(10); BackgroundTaskReportStatus(context, "开始处理图像...", 0); Thread.Sleep(10); //UISynchronizationContext.Send(DoImageProcess, null); DoImageProcess(null); if (_selectPresentationsInformations.Count == 0) { BackgroundTaskReportStatus(context, "处理图像处理结果为0", 0); return; } BackgroundTaskReportStatus(context, "开始向打印机发送图像", 0); Thread.Sleep(10); PrintScu scu = new PrintScu(); DicomPrintProgressUpdate progressUpdate = new DicomPrintProgressUpdate(); progressUpdate.dicomPrintManager = this; progressUpdate.printScu = scu; progressUpdate.Task = context; scu.ProgressUpdated += progressUpdate.Update; _dicomPrintSession = new DicomPrintSession(DicomPrinter, new SelectPresentationsInformationsCollection(_selectPresentationsInformations)); PrintScu.FilmSession filmSession = DicomPrintSession.GetFilmSession(_dicomPrintSession.SelectPresentationsCollection, _dicomPrintSession.DicomPrinter.Config); DicomState dicomState = scu.Print("MacroAETile", _dicomPrintSession.DicomPrinter.AETitle, _dicomPrintSession.DicomPrinter.Host, _dicomPrintSession.DicomPrinter.Port, filmSession); scu.Join(); if (dicomState == DicomState.Success) { //UpDicomPrintStatus(context); if (_dicomPrintComponent != null) { UISynchronizationContext.Send(_dicomPrintComponent.PrintedDeleteImage, this); } } } catch (Exception e) { Platform.Log(LogLevel.Debug, e); BackgroundTaskReportStatus(context, e.Message, 100); } if (_studyInstanceUid != null) { _studyInstanceUid.Clear(); _studyInstanceUid = null; } GC.Collect(); }
/// <summary> /// Call passed delegate in UIThread Context if available /// </summary> /// <param name="del"></param> /// <param name="value"></param> public static void CallMethodInUISynchronizationContext(SendOrPostCallback del, object value) { if (del != null) { if (UISynchronizationContext != null) { UISynchronizationContext.Send(new System.Threading.SendOrPostCallback(del), value); } else { del(value); } } }
/// <inheritdoc /> public virtual void UpdateCanExecute() { UISynchronizationContext.ExecuteOnUIContext(() => { bool canExecute = true; foreach (var property in _observedProperties) { if (!property.Validate()) { canExecute = false; break; } } if (_canExecute != canExecute) { _canExecute = canExecute; CanExecuteChanged?.Invoke(this, EventArgs.Empty); } }); }
/// <summary> /// Invokes the specified action on the UI thread. Blocking. /// Active message pump required. /// </summary> /// <param name="action">the action to run on UI thread</param> /// <param name="exclusively">avoid overlap with ExecuteOnSameThread</param> private static void InvokeOnUIThread(ThreadStart action, bool exclusively) { if (action == null) { return; } // Run directly if no UI context or if already on UI thread if (OnMainUiThreadOrNoUiContext) { action(); return; } Exception caughtException = null; bool finished = false; // Looping may be necessary to run exclusively while (!finished) { // Wait for the UI Thread UISynchronizationContext.Send(delegate { // If the action is to be run exclusively and if ExecuteOnSameThread is already running, then wait if (exclusively && inExecuteOnSameThread) { return; } try { action(); } catch (Exception exception) { SaveStackTrace(exception); caughtException = exception; } finally { finished = true; } }, null); // We can only get here if we are running exclusively and if ExecuteOnSameThread was running. // Wait for ExecuteOnSameThread to finish if (!finished) { executeOnSameThreadComplete.WaitOne(); } } if (caughtException == null) { return; } // FB25127 - if a UnhandledThreadException handler is present use that rather than // rethrowing the exception. if (UnhandledThreadException != null) { UnhandledThreadException(caughtException); } else { throw caughtException; } }
/// <summary> /// Executes and action on the UI SynchronizationContext /// </summary> /// <param name="action"></param> protected void ExecuteOnUIContext(Action action) { UISynchronizationContext.ExecuteOnUIContext(action); }
/// <summary> /// Start plugin <paramref name="pluginInstance"/> /// </summary> /// <param name="pluginInstance">The plugin to start</param> /// <param name="attachDebugger">Whether to attach the debugger to the plugin host on start</param> /// <returns>Success of operation</returns> public async Task <bool> StartPlugin(TPluginInstance pluginInstance, bool attachDebugger = false) { var pluginPackage = pluginInstance.Package; var packageName = pluginPackage.Id; try { // Make sure the plugin is stopped and can be started using (await pluginInstance.Lock.LockAsync()) { if (pluginInstance.Status != PluginStatus.Stopped) { return(true); } if (CanPluginStartOrPause(pluginInstance) == false) { throw new InvalidOperationException("A plugin with the same Package name is already running"); } OnPluginStarting(pluginInstance); } // Determine the plugin and its dependencies assemblies' information. This includes the assembly which contains the PluginHost type var packageRootFolder = Locations.PluginPackageDir.FullPathWin; var pluginAndDependenciesAssembliesPath = new List <string>(); var pluginHostTypeAssemblyName = GetPluginHostTypeAssemblyName(pluginInstance); var pluginHostTypeMinAssemblyVersion = GetPluginHostTypeAssemblyMinimumVersion(pluginInstance); if (pluginInstance.IsDevelopment == false) { using (await PMLock.ReaderLockAsync()) { var pluginAndDependenciesPackageFilePaths = new List <FilePath>(); var pluginPkg = PackageManager.FindInstalledPluginById(packageName); if (pluginPkg == null) { throw new InvalidOperationException($"Cannot find requested plugin package {packageName}"); } PackageManager.GetInstalledPluginAssembliesFilePath( pluginPkg.Identity, out var tmpPluginAssemblies, out var tmpDependenciesAssemblies); pluginAndDependenciesPackageFilePaths.AddRange(tmpPluginAssemblies); pluginAndDependenciesPackageFilePaths.AddRange(tmpDependenciesAssemblies); var pluginHostTypeAssemblyPath = pluginAndDependenciesPackageFilePaths.FirstOrDefault(a => a.FileNameWithoutExtension == pluginHostTypeAssemblyName); if (pluginHostTypeAssemblyPath == null) { OnPluginStartFailed( pluginInstance, PluginStartFailure.InteropAssemblyNotFound, $"{pluginInstance} failed to start: Unable to find the PluginHost type's \"{pluginHostTypeAssemblyName}\" dependency assembly's package"); return(false); } // Make sure the assembly version is equal or higher to the required minimum version if (pluginHostTypeMinAssemblyVersion != null) { var pluginHostTypeAssemblyInfo = FileVersionInfo.GetVersionInfo(pluginHostTypeAssemblyPath.FullPath); if (NuGetVersion.TryParse(pluginHostTypeAssemblyInfo.ProductVersion, out var pluginHostTypeAssemblyVersion) == false) { OnPluginStartFailed( pluginInstance, PluginStartFailure.InteropAssemblyNotFound, $"{pluginInstance} failed to start: Invalid interop version '{pluginHostTypeAssemblyInfo.ProductVersion}'"); return(false); } if (pluginHostTypeAssemblyVersion < pluginHostTypeMinAssemblyVersion) { OnPluginStartFailed( pluginInstance, PluginStartFailure.InteropAssemblyNotFound, $"{pluginInstance} failed to start: Outdated interop version '{pluginHostTypeAssemblyInfo.ProductVersion}'. Either update the plugin, downgrade SMA, or ask the plugin developer to publish a new version to fix the issue."); return(false); } } foreach (var pkgFilePath in pluginAndDependenciesPackageFilePaths) { string pkgRelativeFilePath = pkgFilePath.FullPathWin.After(packageRootFolder); if (string.IsNullOrWhiteSpace(pkgRelativeFilePath)) { LogTo.Warning( $"Package {pkgFilePath} isn't located underneath the package folder {packageRootFolder}. Skipping, this might cause issues with the plugin"); continue; } pluginAndDependenciesAssembliesPath.Add(pkgRelativeFilePath); } } } // Build command line var cmdLineParams = new PluginHostParameters { PackageRootFolder = packageRootFolder, PluginAndDependenciesAssembliesPath = string.Join(";", pluginAndDependenciesAssembliesPath), PluginHostTypeAssemblyName = pluginHostTypeAssemblyName, PluginHostTypeQualifiedName = GetPluginHostTypeQualifiedName(pluginInstance), PackageName = packageName, HomePath = pluginPackage.HomeDir.FullPath, SessionString = pluginInstance.Guid.ToString(), ChannelName = IpcServerChannelName, ManagerProcessId = Process.GetCurrentProcess().Id, IsDevelopment = pluginInstance.IsDevelopment, AttachDebugger = attachDebugger }; // Build process parameters var processArgs = Parser.Default.FormatCommandLine(cmdLineParams); pluginInstance.Process = new Process { StartInfo = new ProcessStartInfo( Locations.PluginHostExeFile.FullPath, processArgs) { UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, }, EnableRaisingEvents = true, }; // Setup error output logging { var pluginStr = pluginInstance.ToString(); // Avoids keeping a pointer to PluginInstance around StringBuilder pluginErrBuilder = new StringBuilder(); void LogPluginErrorOutput() { if (string.IsNullOrWhiteSpace(pluginErrBuilder.ToString())) { return; } lock (pluginErrBuilder) { LogTo.Warning($"{pluginStr} standard error output:\n--------------------------------------------\n{pluginErrBuilder.ToString().Trim()}\n--------------------------------------------"); pluginErrBuilder.Clear(); } } DelayedTask logTask = new DelayedTask(LogPluginErrorOutput, 200); void AggregatePluginErrorOutput(object _, DataReceivedEventArgs e) { lock (pluginErrBuilder) { pluginErrBuilder.AppendLine(e.Data); logTask.Trigger(750); } } pluginInstance.Process.ErrorDataReceived += AggregatePluginErrorOutput; } // Start plugin if (pluginInstance.Process.Start() == false) { OnPluginStartFailed( pluginInstance, PluginStartFailure.ProcessDidNotStart, $"{pluginInstance} failed to start: Failed to start process"); return(false); } OnPluginStarted(pluginInstance); pluginInstance.Process.EnableRaisingEvents = true; pluginInstance.Process.BeginErrorReadLine(); pluginInstance.Process.Exited += (o, e) => { UISynchronizationContext.Post(_ => { using (pluginInstance.Lock.Lock()) OnPluginStopped(pluginInstance); }, null); }; var connected = await pluginInstance.ConnectedEvent.WaitAsync(PluginConnectTimeout); if (connected && pluginInstance.Status == PluginStatus.Connected) { return(true); } if (pluginInstance.Status == PluginStatus.Stopped) { OnPluginStartFailed( pluginInstance, connected ? PluginStartFailure.ProcessDidNotConnect : PluginStartFailure.Unknown, $"{pluginInstance} failed to start: process stopped unexpectedly."); pluginInstance.ConnectedEvent.Set(); return(false); } } catch (Exception ex) { LogTo.Error(ex, $"{pluginInstance} failed to start: An unknown exception occured during startup"); return(false); } try { LogTo.Warning( $"{pluginInstance.ToString().CapitalizeFirst()} failed to connect under {PluginConnectTimeout}ms. Attempting to kill process"); pluginInstance.Process.Refresh(); if (pluginInstance.Process.HasExited) { LogTo.Warning($"{pluginInstance.ToString().CapitalizeFirst()} has already exited"); return(false); } pluginInstance.Process.Kill(); } catch (RemotingException ex) { LogTo.Warning(ex, $"StartPlugin '{pluginInstance} failed."); } catch (Exception ex) { LogTo.Error(ex, $"An error occured while starting {pluginInstance}"); } finally { try { using (await pluginInstance.Lock.LockAsync()) OnPluginStopped(pluginInstance); } catch (Exception ex) { LogTo.Error(ex, "Exception thrown while calling OnPluginStopped"); } } return(false); }