Files
SzmediTools/Szmedi.RvKits/RvScript/ScriptRunnerCmd.cs
2025-09-16 16:06:41 +08:00

197 lines
7.2 KiB
C#

using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Threading;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Nice3point.Revit.Toolkit.External;
using RoslynPad.Roslyn;
using Szmedi.RvKits.Assists;
namespace Szmedi.RvKits.RvScript
{
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class ScriptRunnerCmd : IExternalCommand
{
//public override void Execute()
//{
// if (WinIntPtr.IsVisible("C#脚本执行"))
// {
// WinIntPtr.ShowAndActive("C#脚本执行");
// }
// else
// {
// try
// {
// ShowNoModel();
// }
// catch (Exception ex)
// {
// MessageBox.Show(ex.ToString(), "错误");
// }
// }
//}
private void ShowNoModel()
{
var handler = new ScriptRunnerHandler();
var externalEvent = ExternalEvent.Create(handler);
var assembliesToRef = new List<Assembly>
{
typeof(object).Assembly, //mscorlib
//typeof(Uri).Assembly, // System
//typeof(Enumerable).Assembly, // System.Core
//Assembly.Load("Microsoft.CodeAnalysis.Workspaces"),
//Assembly.Load("System.Numerics.Vectors"),
typeof(UIApplication).Assembly,
typeof(Document).Assembly,
Assembly.Load("RoslynPad.Roslyn.Windows"),
Assembly.Load("RoslynPad.Editor.Windows"),
};
var roslynHost = new RevitRoslynHost(
assembliesToRef,
RoslynHostReferences.NamespaceDefault
.With(
typeNamespaceImports: new[]
{
typeof(UIApplication),
typeof(Document),
typeof(Dictionary<,>),
typeof(Enumerable),
typeof(ScriptGlobals)
}),
ImmutableArray.Create("CS1701", "CS1702", "CS0518"));
var document = new RoslynEditorViewModel(roslynHost, externalEvent, handler);
try
{
var scriptEditor = new RoslynEditor(document)
{
WindowStartupLocation = WindowStartupLocation.CenterScreen
};
_ = new WindowInteropHelper(scriptEditor) { Owner = Process.GetCurrentProcess().MainWindowHandle };
handler.Progress = new Progress<string>(message => document.Result += $"{message}{Environment.NewLine}");
scriptEditor.Show();
}
catch (Exception ex)
{
MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}");
}
finally
{
//因为是非模态窗口,所以会直接执行取消订阅。
//如果运行过程中会报错,会导致在运行过程中出现未加载程序集时,
//无法加载程序集,需要在窗口关闭后才执行移除订阅
//AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
}
}
public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
//Assembly.Load("System.Runtime.CompilerServices.Unsafe");
var dllName = args.Name.Split(',')[0];
Debug.WriteLine(dllName);
//Directory.GetFiles(GlobalVariables.DirAssembly, "*.dll", SearchOption.AllDirectories).ToList().ForEach(f =>
// {
// if (Path.GetFileNameWithoutExtension(f) == dllName)
// {
// Assembly.LoadFrom(f);
// }
// });
var collection = Directory.GetFiles(GlobalVariables.DirAssembly, "*.dll", SearchOption.AllDirectories);
foreach (var f in collection)
{
if (Path.GetFileNameWithoutExtension(f) == dllName)
{
return Assembly.LoadFrom(f);
}
}
return null;
//Directory.GetFiles(GlobalVariables.DirAssembly, "*.dll", SearchOption.AllDirectories).ToList().ForEach(f =>
// {
// if (Path.GetFileNameWithoutExtension(f) == dllName)
// {
// Assembly.LoadFrom(f);
// }
// });
//foreach (var f in collection)
//{
// if (Path.GetFileNameWithoutExtension(f) == dllName)
// {
// return Assembly.LoadFrom(f);
// }
//}
//return null;
//if (args.Name.StartsWith("AvalonDock.resources"))
//{
// string resourcePath = Path.Combine(GlobalVariables.DirAssembly, "zh-Hans", "AvalonDock.resources.dll");
// return File.Exists(resourcePath) ? Assembly.LoadFrom(resourcePath) : null;
//}
//if (args.Name.StartsWith("AvalonDock"))
//{
// string assemblyFile = Path.Combine(GlobalVariables.DirAssembly, "AvalonDock.dll");
// return File.Exists(assemblyFile) ? Assembly.LoadFrom(assemblyFile) : null;
//}
//var collection = new List<string>
//{
// "System.Memory",
// "System.Runtime.CompilerServices.Unsafe",
// "System.Numerics.Vectors",
//};
//foreach (var item in collection)
//{
// string services = Path.Combine(GlobalVariables.DirAssembly, $"{item}.dll");
// Assembly.LoadFrom(services);
//}
//string services = Path.Combine(GlobalVariables.DirAssembly, "System.Memory.dll");
//if (File.Exists(services))
//{
// Assembly.LoadFrom(services);
//}
//var dll = Directory.GetFiles(GlobalVariables.DirAssembly, "*.dll")
// .Where(f => Path.GetFileNameWithoutExtension(f) == dllName).FirstOrDefault();
//return File.Exists(dll) ? Assembly.LoadFrom(dll) : null;
}
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
if (WinIntPtr.IsVisible("C#脚本执行"))
{
WinIntPtr.ShowAndActive("C#脚本执行");
}
else
{
try
{
ShowNoModel();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "错误");
}
}
return Result.Succeeded;
}
}
}