Skip to content

Commit

Permalink
修复程序集文件被占用导致插件安装失败的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
yqzhishen committed Apr 28, 2022
1 parent 06b4de8 commit 2e9c5f7
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 31 deletions.
1 change: 1 addition & 0 deletions csharp/Framework/ConverterOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace OpenSvip.Framework
/// <summary>
/// 由 OpenSVIP Framework 提供给工程转换器的转换选项。
/// </summary>
[Serializable]
public class ConverterOptions
{
private readonly Dictionary<string, string> OptionDictionary;
Expand Down
1 change: 1 addition & 0 deletions csharp/Framework/OpenSvip.Framework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<Compile Include="Plugin.cs" />
<Compile Include="IProjectConverter.cs" />
<Compile Include="PluginManager.cs" />
<Compile Include="TaskContainer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Warnings.cs" />
</ItemGroup>
Expand Down
52 changes: 52 additions & 0 deletions csharp/Framework/TaskContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.IO;
using System.Reflection;

namespace OpenSvip.Framework
{
public class TaskContainer : MarshalByRefObject
{
private IProjectConverter _inputConverter;

private IProjectConverter _outputConverter;

private ConverterOptions _inputOptions;

private ConverterOptions _outputOptions;

private static IProjectConverter LoadConverter(Plugin plugin)
{
var assembly = Assembly.LoadFrom(Path.Combine(PluginManager.PluginPath, plugin.LibraryPath));
var type = assembly.GetType(plugin.Converter);
return (IProjectConverter) Activator.CreateInstance(type);
}

public void Init(
Plugin inputPlugin,
Plugin outputPlugin,
ConverterOptions inputOptions,
ConverterOptions outputOptions)
{
_inputConverter = LoadConverter(inputPlugin);
_outputConverter = LoadConverter(outputPlugin);
_inputOptions = inputOptions;
_outputOptions = outputOptions;
}

public void Run(string importPath, string exportPath)
{
Warnings.AddWarning("Hello!");
_outputConverter.Save(exportPath, _inputConverter.Load(importPath, _inputOptions), _outputOptions);
}

public Warning[] GetWarnings()
{
return Warnings.GetWarnings();
}

public void ClearWarnings()
{
Warnings.ClearWarnings();
}
}
}
4 changes: 3 additions & 1 deletion csharp/Framework/Warnings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;

Expand Down Expand Up @@ -27,6 +28,7 @@ public enum WarningTypes
[Description("未知")] Others
}

[Serializable]
public class Warning
{
public WarningTypes Type;
Expand Down
75 changes: 45 additions & 30 deletions csharp/GUI/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using OpenSvip.Framework;
using System.Threading;
using System.Diagnostics;
using System.Reflection;
using Microsoft.WindowsAPICodePack.Dialogs;
using System.Windows.Input;
using OpenSvip.GUI.Config;
Expand Down Expand Up @@ -197,13 +198,38 @@ private void ExecuteTasks()
}
new Thread(() =>
{
// Prepare for execution
Model.ExecutionInProgress = true;
var inputConverter = PluginManager.GetConverter(Model.SelectedInputPlugin.Identifier);
var outputConverter = PluginManager.GetConverter(Model.SelectedOutputPlugin.Identifier);
foreach (var task in Model.TaskList)
{
task.PrepareForExecution();
}
// Construct options
var inputOptionDictionary = new Dictionary<string, string>();
foreach (var option in Model.SelectedInputOptions)
{
inputOptionDictionary[option.OptionInfo.Name] = option.OptionValue;
}
var outputOptionDictionary = new Dictionary<string, string>();
foreach (var option in Model.SelectedOutputOptions)
{
outputOptionDictionary[option.OptionInfo.Name] = option.OptionValue;
}
var inputOptions = new ConverterOptions(inputOptionDictionary);
var outputOptions = new ConverterOptions(outputOptionDictionary);
// Create sandbox for tasks
var domain = AppDomain.CreateDomain("TaskExecution");
var container = (TaskContainer)domain.CreateInstanceAndUnwrap(
Assembly.GetAssembly(typeof(TaskContainer)).FullName,
typeof(TaskContainer).ToString());
container.Init(
Model.SelectedInputPlugin,
Model.SelectedOutputPlugin,
inputOptions,
outputOptions);
var skipSameFilename = Model.OverWriteOption == OverwriteOptions.Skip;
var askBeforeOverwrite = Model.OverWriteOption == OverwriteOptions.Ask;
foreach (var task in Model.TaskList)
Expand All @@ -228,45 +254,34 @@ private void ExecuteTasks()
continue;
}
}
var inputOptionDictionary = new Dictionary<string, string>();
foreach (var option in Model.SelectedInputOptions)
{
inputOptionDictionary[option.OptionInfo.Name] = option.OptionValue;
}
var outputOptionDictionary = new Dictionary<string, string>();
foreach (var option in Model.SelectedOutputOptions)
{
outputOptionDictionary[option.OptionInfo.Name] = option.OptionValue;
}
outputConverter.Save(
task.ExportPath,
inputConverter.Load(
task.ImportPath,
new ConverterOptions(inputOptionDictionary)),
new ConverterOptions(outputOptionDictionary));
// Run the container
container.Run(task.ImportPath, task.ExportPath);
}
catch (Exception e)
{
task.Status = TaskStates.Error;
task.Error = e.Message;
continue;
}
var warnings = Warnings.GetWarnings();
var warnings = container.GetWarnings();
if (warnings.Any())
{
task.Status = TaskStates.Warning;
foreach (var warning in warnings)
{
task.Warnings.Add(warning);
}
Warnings.ClearWarnings();
container.ClearWarnings();
}
else
{
task.Status = TaskStates.Success;
}
}
// Unload the domain to release assembly files
AppDomain.Unload(domain);
// Things after execution
Model.ExecutionInProgress = false;
if (!Model.OpenExportFolder)
{
Expand All @@ -279,27 +294,27 @@ private void ExecuteTasks()
}).Start();
}

public static RelayCommand<MainWindow> ImportCommand = new RelayCommand<MainWindow>(
public static readonly RelayCommand<MainWindow> ImportCommand = new RelayCommand<MainWindow>(
p => !p.Model.ExecutionInProgress,
p => p.FileMaskPanel_Click(null, null));

public static RelayCommand<MainWindow> ExportCommand = new RelayCommand<MainWindow>(
public static readonly RelayCommand<MainWindow> ExportCommand = new RelayCommand<MainWindow>(
p => p.StartExecutionButton.IsEnabled,
p => p.StartExecutionButton_Click(null, null));

public static RelayCommand<MainWindow> BrowseAndExportCommand = new RelayCommand<MainWindow>(
public static readonly RelayCommand<MainWindow> BrowseAndExportCommand = new RelayCommand<MainWindow>(
p => p.StartExecutionButton.IsEnabled,
p => p.BrowseAndExportMenu_Click(null, null));

public static RelayCommand<AppModel> ResetCommand = new RelayCommand<AppModel>(
public static readonly RelayCommand<AppModel> ResetCommand = new RelayCommand<AppModel>(
p => !p.ExecutionInProgress,
p => p.TaskList.Clear());

public static RelayCommand<MainWindow> AboutCommand = new RelayCommand<MainWindow>(
public static readonly RelayCommand<MainWindow> AboutCommand = new RelayCommand<MainWindow>(
p => true,
p => p.AboutMenuItem_Click(null, null));

public static RelayCommand<System.Windows.Controls.MenuItem> ImportPluginMenuItemCommand = new RelayCommand<System.Windows.Controls.MenuItem>(
public static readonly RelayCommand<System.Windows.Controls.MenuItem> ImportPluginMenuItemCommand = new RelayCommand<System.Windows.Controls.MenuItem>(
p =>
{
var model = (AppModel)p.DataContext;
Expand All @@ -317,7 +332,7 @@ private void ExecuteTasks()
((MainWindow)App.Current.MainWindow).Model.SelectedInputPluginIndex = index;
});

public static RelayCommand<System.Windows.Controls.MenuItem> ExportPluginMenuItemCommand = new RelayCommand<System.Windows.Controls.MenuItem>(
public static readonly RelayCommand<System.Windows.Controls.MenuItem> ExportPluginMenuItemCommand = new RelayCommand<System.Windows.Controls.MenuItem>(
p => true,
p =>
{
Expand All @@ -331,7 +346,7 @@ private void ExecuteTasks()
((MainWindow)App.Current.MainWindow).Model.SelectedOutputPluginIndex = index;
});

public static RelayCommand<AppModel> InstallPluginCommand = new RelayCommand<AppModel>(
public static readonly RelayCommand<AppModel> InstallPluginCommand = new RelayCommand<AppModel>(
p => !p.ExecutionInProgress,
p =>
{
Expand Down Expand Up @@ -419,7 +434,7 @@ private void ExecuteTasks()
}).Start();
});

public static RelayCommand<AppModel> ManagePathsCommand = new RelayCommand<AppModel>(
public static readonly RelayCommand<AppModel> ManagePathsCommand = new RelayCommand<AppModel>(
p => !p.ExecutionInProgress,
p => PathManagerDialog.CreateDialog(p).ShowDialog());

Expand Down

0 comments on commit 2e9c5f7

Please sign in to comment.