WPF control throwing 'resource identified by the URI missing' exception
On loading the plugin and trying to create 'XYZ' control, the application throws the following exception:
"The component 'XYZ' does not have a resource identified by the URI '/The开发者_运维百科PluginAssembly;component/XYZ.xaml'" on the InitializeComponent() method in the UserControls constructor.
The key points are:
The user control is located in the plugin assembly
I am trying to create the usercontrol from inside the plugin assembly
The plugins are located in the same directory as the main application
The user controls only have problems when they are created through XAML. I have a couple of other usercontrols in the same assembly but I instantiate these using code. I only receive the error message when I attempt to create a UserControl in XAML.
On doing some google, i realized that this happens when two instances of my plugin are loaded in the application. When i removed my plugin from one of the folders ( I allow this plugin to be loaded from two locations) this exception stopped recurring.
My questions:
1) What is the reason behind WPF trying to resolve a URI to load my control?
2) Isn't there a way by which i could have two instances of my plugin loaded in the application and somehow get rid of this exception? or some way to create a unique URI for each instances (if this exception is caused by a conflicting URI).
Any comment or reference would be of help.
Thanks for your interest.
Edit: Same problem as posted by Phil : How to force WPF to use resource URIs that use assembly strong name? Argh!
The only way to do this would be to include the version information in your URI, so the XAML loader can distinguish the correct type. This MSDN article explains the Pack URI format, and the Version portion has this description:
;Version [optional]: the version of the referenced assembly that contains the resource file. This is used when two or more referenced assemblies with the same short name are loaded.
So you'd want to use one of the following:
/ThePluginAssembly;v1.0.0.0;component/XYZ.xaml
/ThePluginAssembly;v1.1.0.0;component/XYZ.xaml
try to use Assembly.LoadFrom()
instead of Assembly.Load()
or Assembly.LoadFile()
.
I had the same problem: I used to load assemblies with Assembly.LoadFile()
. After searching for days, I found out that Assembly.LoadFile()
and Assembly.Load()
are deprecated. Both methods create problems in the runtime. So I used Assembly.LoadFrom()
and it worked.
The following directions are relevant for both the plugin's assembly and any non-System assembly referenced by the plugin (duplication could be at any level of references).
Since the plugin's assembly is located in the application's executable directory,
if you added your assembly to the GAC, remove it from there.
Check all references to the assembly from your solution and set "Version Specific" to false.
If the plugin assembly is from another solution and you use different versions of the assemble for debug/release or for x86/x64 then edit the .csproj files that reference the assembly and set a reference path like in this example.
Consider canceling reference to plugin assemblies and using reflection to load them instead - this will remove dependencies of solution upon plugins.
To do this, you will need to move any code that looks for specific elements in plugins to the plugin assemblies themselves and from original solution only access types exposed by plugin that support interfaces defined outside the plugin (by assemblies in original solution or in an assembly referenced by both original solution and plugin).
- While accessing assembly via reflection, make sure that you load the assembly from the application's executable directory.
Make sure the Pack URIs to resources are of the form: "pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"
So far, the best solution i have reached to, is modifying the name of my plugin dll in the project properties, and make it version specific.
So, if initially it was "prod.myplugin" now i have made it "prod.myplugin_300d3". After modifying the project properties when i rebuild my project then the compiler regenerates .g.cs files, and now it has a version in the URI (it appears as /prod.myplugin_300d3;component/XYZ.xaml ) and thus makes my URI uniquer across different versions.
I am still looking for a better, automated solution where i could be able to modify the MSBuild:Compile configuration.
Copy all the files from bin folder into a separate folder from all the projects that are in your solution and remove the debug and release folder from the bin folder of each project. This has solved the designer problem for me.
Remember that when you will compile next time all the files will come back again. So you have to have some script in post build in order to copy to another folder and delete the files under bin folder.
I had same problem, my UserControls
all referenced same Assembly as main app xaml.
Removing resource link from UserControls
resolve this problem.
精彩评论