【问题标题】:Runnable Dll created from WPFapplication doesn't find referenced ResourceDictionary从 WPFapplication 创建的可运行 Dll 找不到引用的 ResourceDictionary
【发布时间】:2017-02-16 10:00:31
【问题描述】:

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

起初,我在多个项目中使用相同的 ResourceDictionary 开发了一个包含多个项目和用户控件的 WPF 应用程序。因此,我在一个仅包含 dictionary.xaml 的 Porject 中获取了 Resource 字典:

<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 和用户控件中,我在项目中引用了 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 项目中使用以下方法来获得一个新的入口点(我为它使用了一个额外的类):

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 的项目和一个包含几乎空的包含按钮的 MainWindow 的项目,使用字典中的样式和对项目的引用我的字典。

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

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

好的,然后我在 new Application() 后面添加了Application.ResourceAssembly = typeof(MainWindow).Assembly;。现在调试器稍微向前一点,但又因错误而停止:

MainWindow.xaml linenumer12 中的异常 ... -> InnerException {"File or Assembly \"WPFGlobalResources, Culture=neutral\" or a dependency of it can't be found. System can't find specified file.": "WPFGlobalResources, Culture=neutral"} 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 并将样式添加到每个窗口/用户控件,但我希望这不是唯一的解决方案???产生大量冗余代码...

【问题讨论】:

    标签: c# wpf xaml dll resourcedictionary


    【解决方案1】:

    好的,在尝试了很多之后,我同时找到了解决方案:

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

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

    在使用 app.Run 之前。 这个好像是预加载了外部引用,然后就可以找到了。

    有趣的提示:在这种情况下,最好保留 WPF 应用程序而不做任何更改(仍然可以使用 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;
        }
    }
    

    现在它终于可以工作了:-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      相关资源
      最近更新 更多