make use of the snk file - snk

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.

Related

Interop assembly not found in F# solution

F# newbie here, spent many painful hours trying to resolve the errors with a simple piece of code from MSDN F# tutorial.
#r "Microsoft.Office.Interop.Excel.dll"
// fails with invalid/not found errors
#r "Microsoft.Office.Interop.Excel" // works like a charm.
Any F# gurus know why?
"Microsoft.Office.Interop.Excel.dll" is the name of a file (inferred, because of the .dll suffix). When you supply a file name, #r will look for that file in the file system. Since you didn't supply a path, it'll look in your present working directory. Most likely, "Microsoft.Office.Interop.Excel.dll" isn't in your working directory. This explains why the first example fails.
"Microsoft.Office.Interop.Excel", on the other hand, is inferred to be the name of an assembly (because there's no file extension). Assemblies are libraries, and are normally distributed in .dll files. They don't have to, though; they can, for example, be dynamically emitted at run-time. Additionally, a .dll file can technically contain more than a single assembly, although I've never seen this in the wild. The most normal case is that a .dll file contains a single assembly, and that the name of the file corresponds to the name of the assembly.
When you request to load an assembly, the .NET assembly loader (called Fusion) starts looking for an assembly with the requested identity. It'll start looking in the Global Assembly Cache, and my guess is that it finds the "Microsoft.Office.Interop.Excel" assembly there. This explains why the second example succeeds.

What is the best way for multiple solutions/projects to reference a common assembly?

I have several Visual Studio solutions/projects (some VB, some C#) that all reference a common DLL at design time. This DLL does not have to be copied to the output folder as it is only needed while writing code. Every few months this DLL will be updated to a newer version and all of my projects need to reference the updated version.
What is the best way to handle this?
You have to use a Shared Assembly, shared in GAC (Global Assembly Cache).
Say, you have programmed a class, a piece of software, whatever you have, and you want to make it a shared assembly.
First you make it an assembly by creating a new Class Library Project in VS and transporting all of the code to that project. Don’t build/run it yet! Note that we just transport the code but the assembly (the .DLL file) is not actually made yet, because we have not built the project yet.
Before building the assembly, we have to create/share a key by which the assembly is known, in 2 steps:
a) create the key by executing the cmd below in VS cmd:
sn -k "C:[DirectoryToPlaceKey][KeyName].key" b) share it by adding the attribute below to the AsseblyInfo.vb/cs file in the properties folder of your Class Library project:
In VB.Net:
In C#:
[Assembly: AssemblyKeyFile("C:[directory containing the key file][KeyName].key")] (just copy and paste this into the AssemblyInfo.vb/cs file, but write your directory and file name instead).
Now, you MAKE the assembly by building the project. Just build the project (just press F5 once, at least!). By doing so, the .dll file we need (the assembly) is created in the “bin” folder in the same folder of the project.
Now we share it by Copying the .dll file into the GAC (Global Assembly Cache: it’s where all the assemblies are gathered together. The directory is: “C:\windows\Microsoft.Net\assembly\GAC_MSIL” but you don’t need to know that since the tool below does that for you~) by executing the command below in the VS cmd:
gacutil -I "C:[PathToBinDirectoryInVSProject]\myGAC.dll"
YOU'RE DONE! You may now reference and use the shared assembly from all your applications, and whenever you want to update, just update the shared assembly.
Hope that helps!
You can create nuget resources, and use Nuget Server (Lastest version of teamcity support it) - and all updates w'll be handled by nuget.
Other approach is to create common folder and all project point's to dll in this folder (relativly) in this case you need to udate dll in one folder (after rebuild solution dll'll be updated automaticly)
Ofcourse you can allways install dll in GAC (Global Assembly Cache) this is handled by tool called gacutil.exe (in net is lot of example how to handle it).

What is the best way to include references to my own assemblies in a project template?

We have developed a library in C#, and now I wish to create a project template to aid in using the library correctly.
I want new projects to include a reference to the library assembly, but would prefer not to have to deploy the assembly to the GAC, or to depend on the assembly residing in some specific location.
What I am thinking is to include the .dll in the project template .zip file. That means it will end up somewhere inside the project folder of new projects. Perhaps in a folder named Lib. Then the reference hint in the project file can point to that folder. Is that a good idea? What problems might I face down the road?
Is there perhaps some mechanism for including such 3rd party libraries in project templates that I'm not aware of? How have you tackled this? Surely I'm not the first.
I have had to address this issue in the past. In one case, it was a logging library that was installed to the GAC, which meant the Reference element simply needed the assembly name. In another case, we installed the library to the file system, created a registry key that contained the location (in case the user got cute and changed the install location on us) and used a project template wizard to look up the registry key and populate a replacement item to have the correct location in the Reference's HintPath. (Note: the template wizard approach requires you to install your wizard's assembly to the GAC, which it sounds like you're trying to avoid...)
If you don't want your library to be installed in either the GAC or a specific location, the approach of including the assembly in the project is pretty much your only remaining option. On the positive side, deployment of your project template is fairly straightforward and you don't have to muck with the GAC, custom wizards, etc. On the negative side, if you ever create a new revision of your library, your users will need to update every project's copy of the library.

Difference between application manifest and assembly manifest

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.

How to associate external files with an assembly

Let's say you have a class library project that has any number of supplemental files that also need to be included with the compiled assembly (e.g. simple text files or even a legacy unmanaged DLL that's wrapped by the assembly as an interop layer). While embedding the supplemental files into the assembly itself is relatively straightforward, we have situations where this is not possible or just undesirable. We need to have them as "sidecar" files (i.e. files alongside the assembly, potentially in subdirectories relative to the assembly)
Adding those files to the project with an appropriate value for "Copy to Output Directory" specified appears to be sufficient for projects that are completely self-contained within a solution. But if a separate project in another solution adds a reference to the assembly, it does not automatically pickup its sidecar files. Is there a way in the project to somehow mark the resulting assembly such that anything referencing the assembly will also know it needs to include the associated sidecar files? How do you do this?
You can use al.exe, but there also appears to be a C# compiler option. You want to create a multifile assembly using the /linkresource C# compiler option. Instructions are here, but the command is similar to this:
csc /linkresource:N.dll /t:library A.cs
Where N.dll is a native DLL that will go wherever the managed assembly goes (including into the GAC.) There's a very clear description at the link I provided.
Have you tried creating a setup for your solution ? There's an option of including sidecar files targeting to application installation directory.
Another option would be to include the sidecar files in the Assembly resources and un-wrap them to disk when run for the first time.
What if you create a merge module containing the library plus its dependencies? Your installer will then need to reference this module, but you will ensure all of the necessary files will be present.
Unfortunately there doesn't appear to be a lot of built-in support in Visual Studio for this, although I can definitely see the use case.
If you use Subversion for your source control, then you could link in an external reference as an externals definition. This would bring in the source code, and you'd be making a reference to the necessary assembly as a project reference instead of a DLL reference, and then the copy to output directory rules would come into play.
If that's not possible, another solution would be to include commands in the pre/post-build events of your in-solution project to copy the most up-to-date sidecar files from the remote assembly on a build. Of course this comes with the caveat that it doesn't set itself up automatically when you include the DLL in your project; you have to take manual steps to set it up.
I deal with this some time ago. Its a common problem.
You can create some postbuild actions:
http://www.codingday.com/execute-batch-commands-before-or-after-compilation-using-pre-build-or-post-build-events/
Hope this helps... :)
It appears to me that you're using the wrong type of reference. There are two types of references- Reference and ProjectReference. Reference is an explicit reference to a specific assembly. ProjectReference is a reference to another project (say .csproj).
What you're looking for is ProjectReference. VS and the default MSBuild targets are setup to do CopyLocal. If you set CopyToOutputPath true for your "sidecar" files, any ProjectReferences to this project now will also pull in the same files.
I'm not sure if you can to ProjectReferences across solutions in the IDE. I deal a lot with MSBuild where sln files are not relevant and this is how I deal with it.
What we did in our project is that we created as separate build file to do all those stuffs.
In your build file you can have tags to build your main solution, then add tags to copy files you need after build.
NAnt is also your option, but right now I'm happy using Rake as my build/debug automation.
Since this cannot be integrated within Visual Studio, what I'm doing is I create a task (either in MSBuild, NAnt or Rake), that executes vsjitdebugger.exe in the end to attach it to my Visual Studio when debugging.
These are just my styles for now, you can maybe create your own style.

Resources