问题描述
TL;DR
如何让运行时在 .NET Core 5 中为涉及 .NET 4.7.2 代码的在运行时编译的 C# 插件选择正确的程序集?
背景
我有一个 .NET 4.7.2 应用程序,在该应用程序上,某些模块根据一些可配置的插件表现不同。我在运行时编译 C# 插件的 .NET 4.7.2 程序集中有以下代码。
import csv
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import matplotlib.pyplot as plt,mpld3
driver = webdriver.Chrome()
url = "https://www.tiktok.com/"
driver.get(url)
time.sleep(2)
soup = BeautifulSoup(driver.page_source,"html.parser")
result = soup.find_all('span',{'class' : "lazyload-wrapper"})
len(result)
trending = []
viewss = []
for item in result[0]:
for j in item:
type(item)
#print(item[0])
tak = item.find_all("a","jsx-2474431524")
a = range(len(tak))
#print(a[4])
for i in range(len(tak)):
url = "https://www.tiktok.com/"+tak[i].get("href")
time.sleep(2)
driver.get(url)
soup = BeautifulSoup(driver.page_source,"html.parser")
result = soup.find_all('div',{'class' : "share-info"})
views = result[0].h2.text
if 'B' in views:
lists = result[0].h1.text
#view = result[0].h2.text
print(lists)
print(views)
trending.append(lists)
viewss.append(views)
import matplotlib.pyplot as plt
xval=[]
lent = len(trending)
for i in range(lent):
xval.append(i)
x = trending
y = viewss
#print(trending[3],)
fig,ax = plt.subplots()
plt.plot(x,y)
plt.xlabel('trends',size = 15)
plt.ylabel('Ranking',size = 15)
#plt.title('',size = 10)
plt.xticks(rotation=-30)
plt.xticks(size = 20)
plt.yticks(size = 20)
fig.savefig('my_plot.png')
plt.show()
#mpld3.show()
我现在正在尝试将代码(缓慢地)升级到 .NET 5.0,我从 UnitTests(没有其他项目可以参考的项目之一)开始。我写了以下代码
public OperationResult<Assembly> CompileClass(string code,string[] references,string fileName,bool generateInMemory = true,bool includeDebugInformation = true)
{
OperationResult<Assembly> result = new OperationResult<Assembly> { Success = true };
try
{
string pluginsFolder = Path.Combine(InsproConfiguration.GetSettings().PluginsFolder);
bool keepSoureceFilesAfterCompiling = false;
#if (DEBUG)
keepSoureceFilesAfterCompiling = true;
#endif
if (!Directory.Exists(pluginsFolder))
{
Directory.CreateDirectory(pluginsFolder);
}
using (CSharpCodeProvider compiler = new CSharpCodeProvider(new Dictionary<string,string> { { "CompilerVersion","v4.0" } }))
{
CompilerParameters parameters = new CompilerParameters()
{
GenerateInMemory = generateInMemory,IncludeDebugInformation = includeDebugInformation,OutputAssembly = Path.Combine(pluginsFolder,fileName) + ".dll",CompilerOptions = "/debug:full",TempFiles = new TempFileCollection { KeepFiles = keepSoureceFilesAfterCompiling }
};
parameters.ReferencedAssemblies.AddRange(references);
CompilerResults compiledCode = compiler.CompileAssemblyFromSource(parameters,code);
var errors = new StringBuilder();
foreach (CompilerError error in compiledCode.Errors)
{
errors.AppendLine($"Error in line {error.Line},Column {error.Column}: {error.ErrorText}");
}
if (!string.IsNullOrEmpty(errors.ToString()))
{
result.HandleFailure(errors.ToString());
}
result.ResultObject = compiledCode.CompiledAssembly;
}
}
catch (Exception ex)
{
LogService.Current.LogError(ex);
}
return result;
}
在旧代码中,在
public OperationResult<Assembly> CompileClassWithRoslyn(string code,List<string> referenceAssemblies,string assemblyName)
{
OperationResult<Assembly> result = new OperationResult<Assembly>();
try
{
//Set file name,location and referenced assemblies
string pluginsFolder = Path.Combine(InsproConfiguration.GetSettings().PluginsFolder);
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
var trustedAssembliesPaths = ((string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")).Split(Path.PathSeparator);
if (!referenceAssemblies.Any(a => a.Contains("mscorlib")))
{
referenceAssemblies.Add("mscorlib.dll");
}
var references = trustedAssembliesPaths.Where(p => referenceAssemblies.Contains(Path.GetFileName(p)))
.Select(p => MetadataReference.CreateFromFile(p))
.ToList();
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,syntaxTrees: new[] { syntaxTree },references: references,options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var ms = new MemoryStream())
{
EmitResult emitResult = compilation.Emit(ms);
if (!emitResult.Success)
{
IEnumerable<Diagnostic> failures = emitResult.Diagnostics.Where(diagnostic =>
diagnostic.IsWarningAsError ||
diagnostic.Severity == DiagnosticSeverity.Error);
result.HandleFailure(failures.Select(f => f.GetMessage()));
}
else
{
ms.Seek(0,SeekOrigin.Begin);
Assembly assembly = Assembly.Load(ms.ToArray());
}
}
}
catch (Exception ex)
{
return result.HandleFailure(ex);
}
return result;
}
程序集由运行时自动按名称选择。在新代码中,mscorlib 无法正确解析,因为出现错误:
错误 CS0518:未定义或导入预定义类型“System.Object”
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)