Example #1
0
        /// <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);
        }
Example #3
0
        /// <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);
            }
        }
Example #4
0
 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();
 }
Example #6
0
        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();
        }
Example #7
0
 /// <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);
         }
     }
 }
Example #8
0
        /// <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);
                }
            });
        }
Example #9
0
        /// <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;
            }
        }
Example #10
0
 /// <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);
        }