【问题标题】:Impossible to embed WPFToolkit into my executable?无法将 WPFToolkit 嵌入到我的可执行文件中?
【发布时间】:2014-07-22 21:38:45
【问题描述】:

我不久前发了一篇关于此的帖子,但没有找到有效的解决方案。 没有人说这是不可能的,但有些人认为错误来自其他东西。 所以我创建了一个简单的新解决方案,只是添加了一个通过 XAML(命名空间导入)调用 DLL 的工具包控件 - 我认为这是问题所在。

我添加了一些代码来加载我作为资源嵌入的 DLL。

我的项目可以从这里下载:

https://onedrive.live.com/redir?resid=B293BA834310C42A%21108

对于那些没有时间的人,这里是代码:

MainWindow.xaml:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit" x:Class="WpfAppTest1.MainWindow"
        Title="MainWindow" Height="350" Width="525">
    <Grid>

        <chartingToolkit:ScatterSeries HorizontalAlignment="Left" Margin="63,85,0,0" VerticalAlignment="Top"/>

    </Grid>
</Window>

MainWindow.xaml.cs

namespace WpfAppTest1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

还有我的 App.xaml.cs

namespace WpfAppTest1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public App()
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        }
        private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            var execAssembly = Assembly.GetExecutingAssembly();
            string resourceName = execAssembly.FullName.Split(',').First() + ".Resources." + new AssemblyName(args.Name).Name + ".dll";
            Console.WriteLine(resourceName);
            using (var stream = execAssembly.GetManifestResourceStream(resourceName))
            {
                byte[] assemblyData = new byte[stream.Length];
                stream.Read(assemblyData, 0, assemblyData.Length);
                return Assembly.Load(assemblyData);
            }
        }

    }
}

这 2 个 DLL 是: system.windows.controls.datavisualization.toolkit.dll WPFToolkit.dll

两者都作为资源添加,构建操作设置为嵌入式资源。

这 2 个引用是本地复制到 False。

查看 EXE,这两个文件都内置在其中。 我添加了一个控制台写行来打印正在加载的 DLL 的路径...

但我仍然收到错误消息。如果我确实将本地副本设置为 true,它会起作用。

我真的被困在那里,不得不使用这个工具包,我需要 DLL 作为 EXE 的一部分。如果不可能,那么我想从你们中的一位专业人士那里阅读它:)

谢谢 史蒂夫

编辑:有没有解决方案来实现我所需要的? :(

编辑:到今天为止我还没有找到解决方案:/

编辑:我想知道这是否可能。

【问题讨论】:

    标签: wpf dll wpftoolkit


    【解决方案1】:

    经过相当多的努力,我似乎​​有了这个工作。

    由于system.windows.controls.datavisualization.toolkit 的资源全部为小写,请确保对其的所有 XAML 引用也是,例如:

    xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=system.windows.controls.datavisualization.toolkit"
    

    这确保Assembly.GetManifestResourceStream 能够找到资源而不会出现任何大小写问题。

    然后将您的程序集解析方法更改为以下:

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var requestedAssemblyName = new AssemblyName(args.Name).Name;
    
        const string resourcesExtension = ".resources";
        if (requestedAssemblyName.EndsWith(resourcesExtension, StringComparison.Ordinal))
        {
            requestedAssemblyName = requestedAssemblyName.Remove(requestedAssemblyName.Length - resourcesExtension.Length);
        }
    
        var resourceName = "WpfAppTest1.Resources." + requestedAssemblyName + ".dll";
        var appAssembly = typeof(App).Assembly;
        using (var stream = appAssembly.GetManifestResourceStream(resourceName))
        {
            // Check the resource was found
            if (stream == null)
                return null;
    
            var assemblyData = new byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            var loadedAssembly = Assembly.Load(assemblyData);
    
            return loadedAssembly;
        }
    }
    

    要注意的关键点是删除 .resources 扩展名,有时在解析程序集时会出现这种情况

    这足以从资源中加载程序集,但是不会将隐式样式应用于图表控件(我假设这与 WPF 在运行时发现其主题的方式有关)。

    为了解决这个问题,我在 App.xaml 中添加了以下内容:

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/system.windows.controls.datavisualization.toolkit;component/Themes/generic.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
    

    这会合并默认图表样式,然后隐式应用这些样式。

    为了测试,我在MainWindow.xaml中使用了如下内容:

    <chartingToolkit:Chart Title="Some Chart" Background="Blue">
        <chartingToolkit:Chart.Series>
            <chartingToolkit:ScatterSeries Title="Series 1" />
        </chartingToolkit:Chart.Series>
    </chartingToolkit:Chart>
    

    【讨论】:

    • 哦,我的上帝,非常感谢 - 我今晚和明天要试试这个,并将返回我的结果!我很兴奋,再次感谢您!
    • @user3617652 这个解决方案成功了吗?
    • 嗨 Luka,到目前为止,它已与我的“测试”应用程序一起工作,我正在修改实际项目!完成后我会尽快通知您!再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2014-05-24
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    相关资源
    最近更新 更多