What is the difference between application manifest and assembly manifest? Where is each one used? Which one of the two is found in .dll or .exe resources? (or both can be there? ).
Sorry if its too many questions at once, but if anyone can explain this to me it would be really helpful. The reason i'm asking this is that i want to be able to extract information from manifests embedded in PE files. I found these descriptions of manifests, but there are two and i'm not sure which one to follow:
Application manifest description
Assembly manifest description
EDIT: and no, i do not want to use any API calls. I'm writting it all myself.
In brief, the two are completely separate concepts with unfortunately similar names.
An application manifest is an XML file embedded in, or distributed along with, a PE binary (managed or native), giving instructions to the OS loader about things such as SxS assembly dependencies, required elevation, OS version compatibility, etc.
An assembly manifest is a section in a CLI assembly, stating the managed assembly's dependencies, the files making up the assembly, the assembly's public key, type exports, CLR flags, and so on. You can inspect an assembly's manifest using ILDASM.exe or most .NET decompilers.
A relevant excerpt from ECMA 335 (the CLI specification), section I.9.6:
Manifests: Every assembly has a manifest that declares which files
make up the assembly, what types are exported, and what other
assemblies are required to resolve type references within the
assembly. Just as CLI components are self-describing via metadata in
the CLI component, so are assemblies self-describing via their
manifests. When a single file makes up an assembly it contains both
the metadata describing the types defined in the assembly and the
metadata describing the assembly itself. When an assembly contains
more than one file with metadata, each of the files describes the
types defined in the file, if any, and one of these files also
contains the metadata describing the assembly (including the names of
the other files, their cryptographic hashes, and the types they export
outside of the assembly).
Note that:
all managed assemblies must have assembly manifests, executables and libraries alike;
all native binaries, executables and libraries, may have application manifests.
It seems that i will have to follow both:
As a resource in a DLL, the assembly
is available for the private use of
the DLL. An assembly manifest cannot
be included as a resource in an EXE.
An EXE file may include an application
manifest as a resource.
(Information found here). So it seems that executables have application manifests embedded in resources and libraries (DLL) have assembly manifests. Since both of them are PE (portable executable), i will need to parse both types.
Application manifests are typically embedded in EXEs and, ironically, Dlls, and specify which assemblies the EXE or DLL is dependent upon.
Assembly manifests can be embedded in DLLs, or be on disk as a separate file, and give an assembly an identity, and a list of resources: being dll's, activation free com objects, and window classes.
If the name of the assembly is the name of a dll, then the same manifest ends up being used as both an application manifest to determine the dependencies of the dll, and an assembly manifest to see what the assembly exports. This option really just seems crazy for native assemblies, its usually better to create an assembly with a complicated name along the lines of company.product.module, and then just have a simple module.dll as its one entry.
Related
OK, so I have successfully set up my Private Assembly for my plugins of my executable, like described here: (This is just an example, my use case is technically the same, but not for plugins as such.)
Executable uses application manifest to declare dependentAssembly on plugins assembly
plugins subdirectory contains plugins.manifest
plugins.manifest declares assemblyIdentity with files listing the plugin DLL(s) (say, easyplug1.dll and xplug2.dll)
What I don't quite get, and haven't yet found any direct explanation, is what about DLLs that the DLLs in the Private Assembly depend upon? Where should they be located, how are they found?
Example: The xplug2.dll, which is 3rd party itself needs the 3rd party dll xbase.dll. Naturally, xbase.dll is simply also deployed in the plugins directory. Is this enough? Does the Private Assembly need to list DLLs that are only used transitively by the (executable) module declaring its dependency on the plugins assembly?
Partial answer so far by trial and error:
(A) It seems all DLLs, also those only used from other "plugin" DLLs must be listed in the Private Assembly manifest -- i.e. essentially one should list all DLL files in the plugins assembly directory.
(A.1) Any not-listed DLL will not be found in the directory, even if it's referenced from a DLL within the same subdirectory.
(A.2) I assume this to be due to all the DLL loading machinery using the (only) custom Activation Context from the executable, and if the DLL is not found there, it seems to search from within the executable directory.
(A.3) I tried looking at the dependency chain with the latest version of Dependency Walker (2.2.10011), but it seems it can't handle this transitive scenario at all: Primary dependencies are are shown correctly, but transitive secondary dependencies are not resolved from the manifest, but relative to the base directory. (Seems it follows plain LoadLibrary semantics for the transient ones.)
File layout:
...\base\app.exe
// - contains Application Manifest declaring dependency on `plugins`
// - Loads xplug2.dll
...\base\plugins\xplug2.dll
// - Loads xbase.dll (which is only used by xplug2.dll internally)
...\base\plugins\xbase.dll
...\base\plugins\plugins.manifest
// - lists xplug2.dll (for sure)
// - *seems* to need to list also xbase.dll
The simple answer is, any "raw" dlls that are not part of an assembly, will be searched for using the applications activation context and/or default dll search rules. And the dll search path includes the application folder, but not any folders that dll's were found in (i.e. a dll can never expect to load another dll that is incidentally in the same folder).
So, for example, if a dll in your assembly required openssl.dll, then it would search first in the application.exe's folder, NOT your private assembly folder unless you specifically, explicitly, added openssl to your private assembly.
the answer is to explicitly add openssl.dll to the private assembly (which incidentally helps protect the integrity of the application should a different dll - in a different assembly - require a different version of openssl.dll)
In your case, you could have two different private assemblies, each using a private version of xbase.dll - where the two different xbase.dlls could be quite incompatible.
Are there any tools or methods for renaming a DLL's dependencies?
I'm working with a large program that uses a significant number of third party dependencies. I'm able to compile nearly all of these dependencies into DLLs with a specific naming convention (i.e. libSomething_x86.dll). However, there is one dependency (FFmpeg) that I can't easily compile, but pre-compiled DLLs are available. So far, I've renamed the DLL files and recreated the import libraries to use the new names. My application compiles, but fails to run because FFmpeg is composed of multiple DLLs and they reference each other (with the original names). Since the new DLL names are longer than the original DLL names, I can't simply hex edit the DLL files. I can't use side-by-side redirection, manifest tricks, or "wrapper"/"dummy" DLLs because the fact the DLLs are pre-compiled and renamed must be completely transparent to the other application developers.
I was hoping to find a method of unlinking the DLL, editing the dependency list, and then relinking the DLL. Is this possible?
Thank you.
Whatever I download, source code, e.g. NHibernate, or .dll file, e.g. NHibernate.Caches.SysCache, there are the .snk file.
What does this mean?
For source code, I just delete the snk file and compile them directly, it works. But is there anything I do wrong? I don't use the snk file.
For dll file, I found problem on version.
Assemblies can be assigned a cryptographic signature called a strong name, which provides name uniqueness for the assembly and prevents someone from taking over the name of your assembly (name spoofing). If you are deploying an assembly that will be shared among many applications on the same computer, it must have a strong name.(msdn)
With snk file included in a project, you can able to generate PublicToken for your dll.
I've been told to create a 'manifest' to achieve Reg-Free-Com between a VB6 .EXE and a .NET DLL.
What is a 'manifest' in this context?
What does it mean to 'embed' a manifest?
From: http://msdn.microsoft.com/en-us/library/ms973913.aspx#rfacomwalk_topic2
Registration-free COM uses manifest to refer to text files with the .manifest extension containing XML, which either defines the identity of an assembly (assembly manifest), together with the binding and activation details of its classes, or defines the identity of an application (application manifest), together with one or more assembly identity references.
To 'embed' a manifest means the text information is embedded in the dll as a Win32 resource rather than sitting on disk as a standalone text file.
Background
I'm maintaining a plugin for an application. I'm Using Visual C++ 2003.
The plugin is composed of several DLLs - there's the main DLL, that's the one that the application loads using LoadLibrary, and there are several utility DLLs that are used by the main DLL and by each other.
Dependencies generally look like this:
plugin.dll -> utilA.dll, utilB.dll
utilA.dll -> utilB.dll
utilB.dll -> utilA.dll, utilC.dll
You get the picture.
Some of the dependencies between the DLLs are load-time and some run-time.
All the DLL files are stored in the executable's directory (not a requirement, just how it works now).
The problem
There's a new requirement - running multiple instances of the plugin within the application.
The application runs each instance of a plugin in its own thread, i.e. each thread calls functions exported by plugin.dll. The plugin's code, however, is anything but thread-safe - lots of global variables etc..
Unfortunately, fixing the whole thing isn't currently an option, so I need a way to load multiple (at most 3) copies of the plugin's DLLs in the same process.
Option 1: The distinct names approach
Creating 3 copies of each DLL file, so that each file has a distinct name. e.g. plugin1.dll, plugin2.dll, plugin3.dll, utilA1.dll, utilA2.dll, utilA3.dll, utilB1.dll, etc.. The application will load plugin1.dll, plugin2.dll and plugin3.dll. The files will be in the executable's directory.
For each group of DLLs to know each other by name (so the inter-dependencies work), the names need to be known at compilation time - meaning the DLLs need to be compiled multiple times, only each time with different output file names.
Not very complicated, but I'd hate having 3 copies of the VS project files, and don't like having to compile the same files over and over.
Option 2: The side-by-side assemblies approach
Creating 3 copies of the DLL files, each group in its own directory, and defining each group as an assembly by putting an assembly manifest file in the directory, listing the plugin's DLLs.
Each DLL will have an application manifest pointing to the assembly, so that the loader finds the copies of the utility DLLs that reside in the same directory. The manifest needs to be embedded for it to be found when a DLL is loaded using LoadLibrary. I'll use mt.exe from a later VS version for the job, since VS2003 has no built-in manifest embedding support.
I've tried this approach with partial success - dependencies are found during load-time of the DLLs, but not when a DLL function is called that loads another DLL.
This seems to be the expected behavior according to this article - A DLL's activation context is only used at the DLL's load-time, and afterwards it's deactivated and the process's activation context is used.
Edit: Works with ISOLATION_AWARE_ENABLED as expected - runtime loading of DLLs uses the original activation context of the loading DLL.
Questions
Got any other options? Any quick & dirty solution will do. :-)
Will ISOLATION_AWARE_ENABLED even work with VS2003? Edit: It does.
Comments will be greatly appreciated.
Thanks!
ISOLATION_AWARE_ENABLED is implemented by the Windows SDK header files and thus probably wont worth with VS2003 at all. However, it is possible to download the latest Windows 7 SDK and use that with VS2003.
You don't need to use MT to link in manifests. Manifests can be embedded as resources in environments that dont have explicit knowledge.
Add the following to a dll's .rc file to embed a manifest. (With a recent enough platform sdk RT_MANIFEST should already be defined):
#define RT_MANIFEST 24
#define APP_MANIFEST 1
#define DLL_MANIFEST 2
DLL_MANIFEST RT_MANIFEST dllName.dll.embed.manifest