无法在.NET MAUI for Android上获取CSharpCompilation的MetadataReference

uwopmtnx  于 2024-01-04  发布在  Android
关注(0)|答案(1)|浏览(172)

我想要在执行阶段编译某些类别,但若要这样做,我必须指涉某些组件,例如System.Linq.dll或System.Collections.dll。
问题是我不能使用MetadataReference.CreateFromFile,因为在发布模式下构建解决方案时,Assembly.Location只返回程序集名称,而不返回文件路径。
还有别的选择吗?
我已经尝试了一些在网上找到的解决方案,但都不起作用,例如:

  1. var methodInfo = assembly.GetType().GetMethod("GetRawBytes", BindingFlags.Instance | BindingFlags.NonPublic);
  2. byte[] assemblyBytes = (byte[])methodInfo.Invoke(assembly, null);
  3. var reference = MetadataReference.CreateFromImage(assemblyBytes);

字符串
这个问题是GetRawBytes在较新的.NET版本github.com/dotnet/runtime/issues/28132#issue-558436811中不再存在

  1. var hash = new Hash(assembly);
  2. var dllAsArray = (byte[])hash.GetType().GetMethod("GetRawData", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(hash, new object[0]);
  3. var reference = MetadataReference.CreateFromImage(dllAsArray);


这一个的问题是Hash()只在Windows上工作。

  1. var formatter = new BinaryFormatter();
  2. var ms = new MemoryStream();
  3. formatter.Serialize(ms, assembly);
  4. var reference = MetadataReference.CreateFromImage(ms.GetBuffer());


这一个的问题是BinaryFormatter已经过时,并在编译时引发错误。
我还发现了这个repo on github,它似乎有在Android上工作的解决方案,但当试图在我的应用程序中重现这个问题时,我得到了一个NotImplementedException,调用TryGetRawMetadata()扩展方法。

mzillmmw

mzillmmw1#

我找到了一个变通办法。虽然不是最好的办法,但很有效。
首先,我添加了一个post-build事件来将生成的DLL复制到项目目录中:

  1. xcopy "$(ProjectDir)obj\$(Configuration)\$(TargetFramework)\android\assets\*.dll" "$(ProjectDir)Resources\Libraries" /Y

字符串
然后,我在.csproj文件中将所需的DLL定义为Maui Asset。例如:

  1. <ItemGroup>
  2. <None Remove="Resources\Libraries\System.Linq.dll" />
  3. </ItemGroup>
  4. <ItemGroup>
  5. <MauiAsset Include="Resources\Libraries\System.Linq.dll" />
  6. </ItemGroup>


最后,我用下面的代码加载引用:

  1. using var stream = await FileSystem.OpenAppPackageFileAsync("Resources/Libraries/System.Linq.dll");
  2. using var ms = new MemoryStream();
  3. stream.CopyTo(ms);
  4. var reference = MetadataReference.CreateFromImage(ms.GetBuffer());

展开查看全部

相关问题