I have two solutions, a solution named Server and a solution named Client. The Server contains a resources file named Server.Properties.Resources. That file is added to the Client solution as an external file.
When I debug inside Visual Studio, everything runs great. When I run the deployed version, I get the error
System.Resources.MissingManifestResourceException:
Could not find any resources appropriate for the specified culture or the neutral culture.
Make sure "Aexeo.DataLayer.Properties.Resources.resources" was correctly embedded or
linked into assembly "Core" at compile time, or that all the satellite assemblies required
are loadable and fully signed.
Is there a way to resolve this, maintaining the usage of the external file link?
I think this is what exactly you are looking for :
http://support.microsoft.com/kb/839861
The problem is caused when you manually create satellite assemblies. Satellite assemblies should be named in such a way that it could automatically be called from the application. To solve the issue you can use Assembly linker al.exe to link the assembly to the application properly.
Related
I have a Visual Studio 2015 solution which consists of an executable and a series of DLL projects. All code is managed C# and running on Windows 10 64-bit.
One of the DLLs needs to load a resource specified by the application. The app provides the full manifest resource path and the DLL uses this to load it.
The resources are set as "Embedded Resource" in solution explorer. An example path would be something like "The.DLL.Assembly.subdir.resources.image.png".
The DLL uses the below code to load the resource.
var asm = Assembly.GetExecutingAssembly();
var resStream = asm.GetManifestResourceStream(path);
This works great! Well, that is if the resource in question is stored inside the DLL assembly which is trying to load it. We'd prefer, though, not to have to locate all the resources in this DLL assembly. We'd like the freedom to let the application locate them in any of the projects and just provide the path letting the loading DLL know how to find them. This would allow the app to better organize the resources based on which project "owns" them as opposed to being forced to put them all in the assembly which will actually load them.
Where I'm stuck is being able to load the resource if it lives in another assembly.
I've tried:
GetEntryAssembly(), this returns the executable assembly, but loading the resource fails even with the full path, it appears GetManifestResourceStream() will only look in that assembly
GetEntryAssembly().GetModules(), thinking I could somehow find the other assembly this way, but this returns a single entry, just the exe itself
Any ideas? I'm thinking there must be a way to load an embedded resource which lives in another assembly, but I haven't yet found it.
I am trying to end up being able to include satellite resources with a "Plugin" component, developed in C# and distributed as a DLL. It runs in a "Host" platform, and there are certain restrictions on how I can build and distribute.
I am using Visual Studio, and would like to figure out how to leverage the standard localization features: component-specific resources for my Forms, and other plugin-wide resources. Please bear with some explanation:
The Visual Studio aspect is set up this way: the platform delivers a VS project that is the host project for all of its Plugins. I develop my Plugin by using this project in VS. The Host also has an embedded code editor and other development tools. The Plugin C# code resides in a Host source folder.
Distributing the Plugin requires a compilation from the Host; and then using Host tools to export my plugin files as a DLL. The host compiles the Plugin source against all other default Plugins, then does code obfuscation, and generates stub files for execution, and also manifest-type files. This is all bundled into a Zip file and that's the distribution assembly for the Plugin. When the user installs the Plugin, this is all actually unZipped into the user's Host folder.
I am trying to use Localization features: I cannot simply localize my forms in VS, since the resources are embedded into the VS build output, which is not bundled with the Host Plugin; and is not accessible for me to include at distribution. Also, the Host does not allow me to select the resx files when it does my build for distribution (that might have solved it; but the "Export Plugin" dialog in the Host only allows selecting the C# files that you want to bundle into a distributable Plugin).
I am aware of the ability to bundle resources into a DLL; and I believe that would be my preferred solution if it is possible; and then perhaps I could use the IDE features, then select all my resource files and generate a satellite assembly with the resources. But I cannot figure out how to reference the resources. This would result in satellite resource DLLs placed alongside the MyPlugin.dll (or in culture subfolders) as pictured above. The Host platform allows including dependent DLLs with your Plugin; and they would be unpacked alongside the MyPlugin.dll as pictured.
I have tried simply running AL, and generating a satellite assembly with resources; and placing that file in the Host folder; and also in culture subfolders. However, the resource loading is failing: it does not find the resources.
I have also tried adding the:
[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
in my Plugin source file; and that did not help.
Can anyone figure this out enough to advise me? It may be a namespace problem; which I do not understand well enough to code for. If I have to change the way resources are loaded, I would do that also; but I do not understand enough about the way the resources are managed to know where to begin at this point.
Even given an explanation about what's under the hood with the resources and files, I may figure something out: but I am just looking at the IDE features, and hoping to use them and just find out how to successfully bundle and include the resources along with the Plugin DLL. I don't understand enough about what's under the hood.
... I wound up solving this just by loading resources myself manually ... Explained here:
Building Resource-Only DLL (With al.exe) Is Raising "assembly is built by a runtime newer than the currently loaded runtime"
I am getting this error:
Could not load file or assembly, system could not find the file specified.
Images:
http://s30.postimg.org/4x936f6ch/error2.png
http://s17.postimg.org/41ta9aaj3/errro3.png
I have a solution built in .NET 4.0
In it I have projects that act as plugins. They use dlls and the issue is that one of the solutions projects dlls is being called, and that references the dll that is causing the issue.
I get no error when rebuilding etc just when the program gets to the part where it uses the dll that references this one.
I have also made sure that in the projects bin folder that it has the dll that it is complaining about.
I have opened the dll in reflector and I don't think it has any issues.
COuld someone point me to the next step to try with fixing this issue?
Thanks!
Couple of tips - hard to know if they'll help you:
Open the csproj file(s) in a text editor and see where the dlls are being referenced (GAC possibly)
If it's a signed assembly, make sure you've got a signed copy (if you've built an Open Source project yourself the signing will be lost)
Look at the references in Visual Studio - do you have Copy Local set to True and Specific Version set to False?
Look at you're App.config or Web.config - is there a binding redirect that failing to load
I remember reading a post about assemblies not being able to be unloaded - probably not an issue on this one but I think the trick was
to load the DLL in a separate AppDomain to keep it isolated - loadable
and unloadable.
I have a solution that includes several projects. A few are libs that are building dll's used in my main project in this solution.
My main project builds with output type console application.
This all works fine.
When i change the build output type to a class library (since i want to use this project as a plugin eventually). The project will still build, this time to a dll.
When i use this plugin in an application where i use it as a dll however, it will run up to a certain point where it's trying to load a type defined in an external dll (so NOT built by my solution) and throw the exception:
Could not load type 'externalinterface' from assembly 'externallib, version=3.0.0.0, Culture=neutral, PublicKeyToken=null'.
The dll's are all in the correct folder,etc.
Also worth noting, the plugin is tested in another location than where i built it. The executable still works on this location, the dll/plugin does not. Same amount of dll's in their folders etc.
EDIT: I already used ILSpy (dll inspector) to open the actual dll that is being referenced (so externallib in the errormessage) and checked if 'externalinterface' was present and it is.
EDIT2: RESOLVED! The program that loaded my plugin was loading the same dll that caused the exception. The dll it loaded was of another version than the one i loaded.
Check whether the type externalinterface is present in the referred dll.
You didn't include the details of the exception the application is throwing. However, based on the message you gave, it appears your assembly does not have a strong name. If the application attempting to load your assembly as a plugin does have a strong name, then .NET will require all assemblies loaded by it also have a strong name, so you need to configure your assembly to have a strong name before continuing.
Maybe some supported dll's which is used by the 'externalinterface' is missing in the target machine. In the target machine, check is all the necessary dll's are present in the output folder.
Or blindly copy paste all the dlls in the output folder from the machine where the code is working to the target machine where you have the problem. After this, if the code is working in the target machine, then try to analyze which supporting dll you are missed to copy.
I have created a dll that will be used by multiple applications, and have created an installer package that installs it to the program files, as well as adds it to the Global Assembly Cache.
The dll itself uses log4net, and requires a xml file for the logging definitions.
Therefore when the installer is run, the following files get copied to the install directory within program files:
The main dll that I developed
- The Log4Net.dll
- the Log4Net.xml file
I am now experiencing a problem. I have created a test console application for experimentation. I have added my dll as a reference, and set the 'local copy' flag to false.
When I compile the test console exe however, I noticed that it has copied the log4net.dll and log4net.xml files to the bin directory. And when running the test console, it appears that it will only work if the log4net.dll is in the same directory as the exe. This is dispite the fact that the test console application does not use log4net, only the dll that was added as a reference does.
Is there some way to have it so that the log4net.dll & xml files used will be the ones that were installed to the program files, rather than any application needed to copy over local copies? The applications that will be using my dll will not be using log4net, only the dll that they are referencing uses it.
Many thanks
Don't install into the Global Assembly Cache! Even if your library dll is used by multiple applications each should have it's own local copy. Otherwise you get into a whole world of pain for saving a few KB of disk space.
Always copy the required dlls locally. If you are really sure that the application won't need it you can simply delete the unnessesary dlls later or don't include them in the installer. But if your application will call ANY reference there it will crash at runtime. So best option is to leave them there (after all they WERE referenced for a reason).
No, it's not possible (at least not without much efford) to have .Net load dlls from arbitrary locations on the disk. And it should be this way (look up DLL-hell if you want to know why).
I suspect your problem is the configuration. You must use fully qualified names if you want it to work from the GAC. As per the documentation at http://logging.apache.org/log4net/release/faq.html:
"When loading an assembly from the GAC the fully qualified assembly name, including the version, culture and public key must be specified. This is in the standard syntax supported by System.Type.GetType. See the next FAQ on how to get the version and public key for an assembly."
I managed to resolve this by adding Log4net.dll to the GAC as well. It will now run without needing a local copy the dll.
It does however require a local copy of the XML file, to correctly log.