从WPF应用程序创建的Runnable Dll没有找到引用的ResourceDictionary

时间:2017-02-16 10:00:32

标签: c# wpf xaml dll resourcedictionary

我现在已经搜索了一段时间,但没有找到具体问题的解决方案。

首先,我在多个项目中使用相同的ResourceDictionary开发了一个带有多个Projects和UserControl的WPF应用程序。所以我在一个只持有dictionary.xaml:

的Porject中输出了资源字典
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:WPFGlobalResources;assembly=WPFGlobalResources"
                >

<!--Here are placed some styles I use globally -->    

在我的许多Windows和UserControls中,我引用了Project中的WPFGlobalResources并添加了

<Window.Resources> or UserControl.Resources <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/WPFGlobalResources;component/GlobalWpfResources.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Window.Resources>

在xamls的开头。

只要我使用可执行应用程序,一切正常,所有资源都可以加载。

现在我需要一个可运行的此应用程序的Dll版本才能在Windows注册表中注册它。为此,我将App.xaml从我的项目中删除并将其转换为类库,正如我在许多googlesites中所描述的那样。

在那里注册我可以用CAD程序调用它 - 在这个程序中它使用调用DLL MainApplication.exec 1,我需要在我的DLL-Project中使用以下方法来获取一个新的EntryPoint(我使用了额外的类)对于它):

public class Exec
{
    public short vcExtStartUp(ref string Directory, string ExtensionName)
    {   //I dont use this method
        return 1;

    }

    public short vcExtMenuExec(ref int MenuID)
    {   //this is what I need to run a WPF Application
        Application app = new Application();

        app.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative); ;

        app.Run(new MainWindow());
        return 1;
    }
}

在这里,我只需要第二种方法,如您所见。我原来的项目在这里抛出了一些错误所以我尽可能地减少了我的问题,只使用包含WPFGlobalResources的Project和一个包含几乎空的MainWindow的Project包含一个按钮,使用字典中的样式,以及对项目的引用我的字典。

只要我在MainWindow.xaml的开头注释出mergedDictionary的调用,一切正常(当然我没有按钮式)。 如果我尝试使用ResourceDictionary,我的CAD程序在调用DLL时崩溃,调试器导致我错误:(希望我正确翻译它)

  

IOException - 附加信息:Assembly.GetEntryAssembly()返回NULL。定义Application.ResourceAssembly-Property或使用语法&#34; pack:// application:,,, / assemblyname; component /&#34;定义应从中加载资源的程序集。

好的,然后我在新的Application()后面添加了Application.ResourceAssembly = typeof(MainWindow).Assembly;。现在调试器向前推进了一点,但是再次停止并出现错误:

  

MainWindow.xaml中的例外情况:linenumer12 ... - &gt; InnerException {&#34;文件或汇编\&#34; WPFGlobalResources,Culture = neutral \&#34;或者无法找到它的依赖关系。系统无法找到指定的文件。&#34;:&#34; WPFGlobalResources,Culture = neutral&#34;} System.Exception {System.IO.FileNotFoundException}

我也尝试添加

System.Uri resourceLocater = new System.Uri("/MainApplication;component/VisiDockedMainWindow.xaml", System.UriKind.Relative);

System.Windows.Application.LoadComponent(resourceLocater);

但没有成功,仍然是同样的错误。

现在我无法找到解决方案让它发挥作用。是否有可能pack:// application ...现在将我的CAD程序作为应用程序而不是我的DLL的Loaction,WPFGlobalResources.dll(和其他所有dll)所在的位置?我怎么能改变它,我无法在MSDN中找到这个用例的URI。

我必须尝试的另一件事是转储我的WPFGlobalResources并将样式添加到每个Window / Usercontrol,但我希望这不是唯一的解决方案???产生大量冗余代码......

1 个答案:

答案 0 :(得分:0)

好的,经过多次尝试后我找到了一个解决方案:

关键是,在执行MainWindow的xaml-Code时,似乎没有加载引用。解决方案只是添加一个:

Assembly resAssembly = Assembly.Load("WPFGlobalResources");

使用app.Run之前。 这似乎预先加载了外部引用,然后就可以找到它。

有趣的提示:在这种情况下,最好不要对WPF-Application进行任何更改(仍然可以使用App.xaml的东西执行),并添加一个额外的Classlibrary-Project来创建dll。然后你可以添加一个开始你的WPF-Application的类(当然你必须首先引用WPF-Projekt和ResourceDictionary-Projekt):

public class Exec
{

    public short vcExtStartUp(ref string Directory, string ExtensionName)
    {
        return 1;

    }

    public short vcExtMenuExec(ref int MenuID)
    {
        Thread thread = new Thread(() =>
        {
            WpfTestAppl.App app = new WpfTestAppl.App();

            // Loading of ResourceAssemblys                
            Assembly resAssembly = Assembly.Load("WPFGlobalResources");


            app.Run(new WpfTestAppl.MainWindow());

        });
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();

        return 1;
    }
}

现在终于可以了: - )