2017-02-16 55 views
0

我现在搜索了一段时间,发现没有解决方案的具体问题。从WPFapplication创建的Runnable Dll没有找到引用ResourceDictionary

起初,我已经开发了一个WPF应用程序,其中多个项目和用户控件在超过1个项目中使用相同的ResourceDictionary。所以,我采购的资源在一个单一的,项目字典出只有持有dictionary.xaml:

<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-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.xaml的开头注释掉mergedDictionary的调用,一切正常(当然,我没有buttonstyle)。 如果我尝试使用ResourceDictionary中,我的CAD程序崩溃时调用的DLL和调试使我的错误:(希望我翻译正确的话)

IOException - Additional Information: Assembly.GetEntryAssembly() returns NULL. Define Application.ResourceAssembly-Property or use the Syntax "pack://application:,,,/assemblyname;component/" to define the assembly the resource should be loaded from.

好吧,那么我已经添加了Application.ResourceAssembly = typeof(MainWindow).Assembly;仅落后新的应用程序()。现在,调试程序一点点前进,但与错误再次停止:

Exception in MainWindow.xaml linenumer12 ... -> InnerException {"File or Assembly \"WPFGlobalResources, Culture=neutral\" or a dependency of it couldn't be found. System can't find specified file.":"WPFGlobalResources, Culture=neutral"} System.Exception {System.IO.FileNotFoundException}

我也tryed添加

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

System.Windows.Application.LoadComponent(resourceLocater); 

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

现在我找不到解决方案使其工作。是否有可能pack:// application ...现在将我的CAD程序作为应用程序的目标,而不是我的DLL的位置,WPFGlobalResources.dll(以及其他所有dll)所在的位置?我该如何改变这一点,我无法在MSDN中找到这个用例的URI。

接下来我要尝试的是倾销我的WPFGlobalResources并将样式添加到每个窗口/用户控件,但我希望这不是唯一的解决方案?产生大量冗余代码...

回答

0

好了,想了很多我同时找到了解决方案后:

的一点是,在执行主窗口的XAML的代码,引用似乎并没有被加载。解决方案是简单地添加一个:

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

在使用app.Run之前。 这似乎预载了外部参考,然后可以找到它。

有趣的提示:在这种情况下,离开WPF应用程序没有任何改变(仍然可执行与App.xaml的东西),并添加一个额外的Classlibrary项目来创建DLL甚至更好。然后你就可以添加一个类开始您的W​​PF的应用程序(当然你必须引用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; 
    } 
} 

而现在它终于工作:-)