【发布时间】:2019-12-25 03:03:36
【问题描述】:
我需要能够在我的 Xamarin Forms C# 应用程序中执行一些小脚本,我很高兴看到 Microsoft.CodeAnalysis 库中实现的“Roslyn”技术。但我无法让脚本工作。请注意,我试图在我的应用程序中运行一个脚本,与 Visual Studio 无关。我对生成一个外部 DLL 并以某种方式从我的应用程序调用它犹豫不决,但如果我必须这样做。
我能够解析函数(使用 CSharpSyntaxTree.ParseText),但是当我尝试创建尽可能小的脚本(“1 + 2”)时,它每次都会抛出异常:
Exception TypeInitializationException: The type initializer for 'AppContext' threw an exception.
Source: Microsoft.CodeAnalysis.Scripting
Stack trace: at Microsoft.CodeAnalysis.Scripting.Hosting.RuntimeMetadataReferenceResolver.ResolveTrustedPlatformAssemblyCore (System.String name, Microsoft.CodeAnalysis.MetadataReferenceProperties properties) [0x00007] in /_/src/Scripting/Core/Hosting/Resolvers/RuntimeMetadataReferenceResolver.cs:169
at Microsoft.CodeAnalysis.Scripting.Hosting.RuntimeMetadataReferenceResolver.ResolveReference (System.String reference, System.String baseFilePath, Microsoft.CodeAnalysis.MetadataReferenceProperties properties) [0x000d0] in /_/src/Scripting/Core/Hosting/Resolvers/RuntimeMetadataReferenceResolver.cs:154
at Microsoft.CodeAnalysis.Scripting.Script.GetReferencesForCompilation (Microsoft.CodeAnalysis.CommonMessageProvider messageProvider, Microsoft.CodeAnalysis.DiagnosticBag diagnostics, Microsoft.CodeAnalysis.MetadataReference languageRuntimeReferenceOpt) [0x000ac] in /_/src/Scripting/Core/Script.cs:276
at Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScriptCompiler.CreateSubmission (Microsoft.CodeAnalysis.Scripting.Script script) [0x00021] in /_/src/Scripting/CSharp/CSharpScriptCompiler.cs:38
at Microsoft.CodeAnalysis.Scripting.Script.GetCompilation () [0x00008] in /_/src/Scripting/Core/Script.cs:142
at Microsoft.CodeAnalysis.Scripting.Script`1[T].GetExecutor (System.Threading.CancellationToken cancellationToken) [0x00008] in /_/src/Scripting/Core/Script.cs:359
at Microsoft.CodeAnalysis.Scripting.Script`1[T].RunAsync (System.Object globals, System.Func`2[T,TResult] catchException, System.Threading.CancellationToken cancellationToken) [0x0001b] in /_/src/Scripting/Core/Script.cs:463
at MyCompany.MyApp.AppViewModel.TryScript () [0x002d3] in C:\Workspace\Mobile\Apps\MyApp\MyApp\AppViewModel.cs:1067
Exception ArgumentNullException: Value cannot be null.
Parameter name: type
Source: mscorlib
Stack trace: at System.Reflection.IntrospectionExtensions.GetTypeInfo (System.Type type) [0x00009] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.14.0.114/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Reflection/IntrospectionExtensions.cs:14
at Microsoft.CodeAnalysis.CoreClrShim+AppContext..cctor () [0x0000f] in /_/src/Compilers/Shared/CoreClrShim.cs:28
有很多人试图做同样的事情并遇到问题:
- This site 建议添加对 mscorlib 的引用,但是 没有帮助。
- This site 没有任何建议
- This site 没有建议
- 什么都没有here
- 没有人回复this one
- 我最喜欢的是this page,其中有问题的人被告知 Roslyn 不适用于 .NET Core,这是 .NET Core 的错。
这是我现在在我的应用程序中得到的,作为执行非常简单的脚本“1+2”的尝试:
using (var loader = new InteractiveAssemblyLoader())
{
loader.RegisterDependency(typeof(object).Assembly);
loader.RegisterDependency(typeof(AppContext).Assembly);
loader.RegisterDependency(typeof(Enumerable).Assembly);
var script = CSharpScript.Create<int>("1 + 2", assemblyLoader: loader);
var result = await script.RunAsync();
Debug.WriteLine(" Script returned " + result);
}
【问题讨论】:
-
请注意,Apple 明确禁止在 iOS 应用中使用动态代码
-
我们不使用 App Store,所以我们不必担心。
-
只是一个建议......使用更简单的 c# 脚本,直到你让它工作。一旦它工作,使用上面的脚本。像声明一个整数,分配给它。
-
我已经编辑了我的帖子,以明确上面的代码是我在我的应用程序中拥有的,作为执行脚本“1+2”的尝试
-
啊,我看错了。我假设你的脚本是整个 using 块。