从 WPFApplication 创建的 Runnable Dll 找不到引用的 ResourceDictionary
Runnable Dll created from WPFapplication doesn't find referenced ResourceDictionary
我已经搜索了一段时间,没有找到针对特定问题的解决方案。
起初我开发了一个 WPF 应用程序,其中包含多个项目和用户控件,在多个项目中使用相同的 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>
在 xaml 的开头。
只要我使用的是可执行应用程序,一切都可以正常工作,并且可以加载所有资源。
现在我需要此应用程序的可运行 Dll 版本以在 Windows 注册表中注册它。为此,我将 App.xaml 从我的项目中删除并将其变成了一个 class 库,正如我在许多 google 站点中找到的那样。
在那里注册我可以从 CAD 程序中调用它 - 在这个程序中它使用调用 DLL MainApplication.exec 1
,这需要在我的 DLL 项目中使用以下方法来获取新的入口点(我使用了额外的class):
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 - 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.
好的,那么我在 new Application() 后面添加了 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}
我也试过添加
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,但我希望这不是唯一的解决方案???产生大量冗余代码...
好的,在尝试了很多之后我同时找到了解决方案:
重点是,在执行主窗口的 xaml-Code 时,似乎没有加载引用。解决方案只是添加一个:
Assembly resAssembly = Assembly.Load("WPFGlobalResources");
在使用 app.Run 之前。
这个好像预加载了外部引用然后就可以找到了
有趣的提示:在这种情况下,最好保留 WPF-Application 而不做任何更改(仍然可以执行 App.xaml 内容)并添加一个额外的 Classlibrary-Project 来创建 dll .然后你可以添加一个 class 开始你的 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;
}
}
现在终于可以用了:-)
我已经搜索了一段时间,没有找到针对特定问题的解决方案。
起初我开发了一个 WPF 应用程序,其中包含多个项目和用户控件,在多个项目中使用相同的 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>
在 xaml 的开头。
只要我使用的是可执行应用程序,一切都可以正常工作,并且可以加载所有资源。
现在我需要此应用程序的可运行 Dll 版本以在 Windows 注册表中注册它。为此,我将 App.xaml 从我的项目中删除并将其变成了一个 class 库,正如我在许多 google 站点中找到的那样。
在那里注册我可以从 CAD 程序中调用它 - 在这个程序中它使用调用 DLL MainApplication.exec 1
,这需要在我的 DLL 项目中使用以下方法来获取新的入口点(我使用了额外的class):
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 - 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.
好的,那么我在 new Application() 后面添加了 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}
我也试过添加
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,但我希望这不是唯一的解决方案???产生大量冗余代码...
好的,在尝试了很多之后我同时找到了解决方案:
重点是,在执行主窗口的 xaml-Code 时,似乎没有加载引用。解决方案只是添加一个:
Assembly resAssembly = Assembly.Load("WPFGlobalResources");
在使用 app.Run 之前。 这个好像预加载了外部引用然后就可以找到了
有趣的提示:在这种情况下,最好保留 WPF-Application 而不做任何更改(仍然可以执行 App.xaml 内容)并添加一个额外的 Classlibrary-Project 来创建 dll .然后你可以添加一个 class 开始你的 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;
}
}
现在终于可以用了:-)