【问题标题】:CodeDom using WPF - error at runtimeCodeDom 使用 WPF - 运行时出错
【发布时间】:2017-06-17 05:46:30
【问题描述】:

我有一个项目,我在内存中使用 Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider 编译了很多文件

当我开始尝试使用 wpf windows 时,我的问题发生了。

我能够编译内存中的程序集,但是当我打开窗口时,我得到:

System.Exception:组件“Dynamic.DragonListForm”没有 由 URI 标识的资源 '/ScriptCode;component/wpf_ui/dragonlistform.xaml'。 在 System.Windows.Application.LoadComponent(Object 组件,Uri resourceLocator)

注意:我通过在特定文件夹中添加所有 .cs 文件的列表来编译

objCompileResults = objCodeCompiler.CompileAssemblyFromFile( objCompilerParameters, files.ToArray() );

我还添加了使其工作所需的 dll 引用。

注意:多亏了 Reed,我才能够通过以下方式使其运行良好,满足我的需求:

 List<string> bamlFiles = Directory.GetFiles( directoryPath, "*.baml", SearchOption.AllDirectories ).ToList();
 bamlFiles.ForEach( x => objCompilerParameters.EmbeddedResources.Add( x ) );

在我的项目中,这已经足够好了。我有一个用于执行语音命令的 .NET 应用程序。一般来说,我有它,所以我可以在更改语音命令时重新编译内存中的程序集更改。我想其中一些不适用于 WPF,但我现在可以在我的内存程序集中使用 WPF 窗口。

【问题讨论】:

    标签: c# wpf codedom


    【解决方案1】:

    问题在于 WPF 文件不仅仅是 C#,它们也是 XAML,然后在单独的 MSBuild 任务中编译为 BAML 资源并作为嵌入式资源包含。

    如果您想支持某个版本,则需要将所有引用的 xaml 作为资源包含在内。有关如何使用 CodeDom 执行此操作的详细信息,请参阅 this post

    完成后,您还必须确保使用兼容的机制来加载类型。 C# 编译 xaml/xaml.cs 文件的“正常”方式不适用于您的情况,因为它需要将资源预编译为 baml。您必须有效地“重写”C# 类型背后的代码以使用不同的加载 XAML 的机制 - 通常这将通过使用 XamlObjectReaderXamlObjectWriter 来读取 xaml 内容并“写入”来完成在InitializeComponent 传递期间进入对象。

    【讨论】:

      【解决方案2】:

      另一个非常有用的信息在:The component does not have a resource identified by the uri

      由此我创建了一个可以像这样调用的扩展方法:

       // https://stackoverflow.com/questions/7646331/the-component-does-not-have-a-resource-identified-by-the-uri
       this.LoadViewFromUri( @"/ScriptCode;component/wpf_ui/spywindowviewer.xaml" );
       // InitializeComponent();
      

      注意:我只是使用错误消息中显示的 uri,例如:

      组件“Dynamic.DragonListForm”没有由 URI '/ScriptCode;component/wpf_ui/dragonlistform.xaml' 标识的资源。在

      扩展方法:

      using System;
      using System.IO.Packaging;
      using System.Linq;
      using System.Reflection;
      using System.Windows;
      using System.Windows.Markup;
      using System.Windows.Navigation;
      
      namespace Extensions
      {
         public static class WpfWindowExtensions
         {
            // https://stackoverflow.com/questions/7646331/the-component-does-not-have-a-resource-identified-by-the-uri
            public static void LoadViewFromUri( this Window window, string baseUri )
            {
               try
               {
                  var resourceLocater = new Uri( baseUri, UriKind.Relative );
                  // log.Info( "Resource locator is: ")
                  var exprCa = ( PackagePart )typeof( Application ).GetMethod( "GetResourceOrContentPart", BindingFlags.NonPublic | BindingFlags.Static ).Invoke( null, new object[] { resourceLocater } );
                  var stream = exprCa.GetStream();
                  var uri = new Uri( ( Uri )typeof( BaseUriHelper ).GetProperty( "PackAppBaseUri", BindingFlags.Static | BindingFlags.NonPublic ).GetValue( null, null ), resourceLocater );
                  var parserContext = new ParserContext
                  {
                     BaseUri = uri
                  };
                  typeof( XamlReader ).GetMethod( "LoadBaml", BindingFlags.NonPublic | BindingFlags.Static ).Invoke( null, new object[] { stream, parserContext, window, true } );
               }
               catch( Exception )
               {
                  //log
               }
            }
         }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-04-02
        • 1970-01-01
        • 1970-01-01
        • 2015-10-11
        • 2020-09-18
        • 2016-07-06
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        相关资源
        最近更新 更多