Edit Metadata of Executable in VB.NET - c#

I read a lot about changing the metadata of music or images, but what about normal executable? How do I edit the comment / title of them? I am using .NET 2

You can specify various bits of metadata about a .NET assembly by simply including assembly attributes like so:
<Assembly: AssemblyTitle("ConsoleApplication9")>
<Assembly: AssemblyDescription("Blah")>
<Assembly: AssemblyCompany("My Company")>
<Assembly: AssemblyProduct("ConsoleApplication9")>
<Assembly: AssemblyCopyright("Copyright © My Company 2012")>
<Assembly: AssemblyTrademark("")>
Normally you place these in a file called AssemblyInfo.vb and compile it into your assembly (Visual Studio will generate this for you from the settings you set if you go to project settings - Application | Assembly Information. Have a look in the project folder, there is by default a sub-folder with the same name as your project and in there is the aforementioned .vb file).
If you want, however, to update a precompiled .NET assembly I think you would need to decompile it, change the attributes in the manifest you want to change and re-compile it. You can do this using the ildasm tool. If an assembly is strong named you will not be able to recompile it using the same strong name than it was compiled with of course.

Properties like comment or title are not provided for all files equally, because they are not stored by the filesystem but come from the file itself. Therefore they must be part of the file format and not all file formats provide such properties. Indeed, many file formats don't provide any properties at all (e.g. .txt). Even when the file format supports some properties, Windows needs a custom property handler installed to extract, interpret and possibly modify them.
Executables provide some read-only properties through the version information resource. However they cannot and should not be changed, because this will mess up file checksums, break digital signatures etc.

Related

c# Use dll with different versions in one directory

How can I use different dll's (other Version) with the same name in one directory?
For Example, LibA (ExternalLib.dll) has Version 1 and LibB (ExternalLib.dll) has Version 2.
I'm deploying all my programs to the same directory (this is our companys standard and I can't change this fact). The problem is if ProgramB which is using the LibB is deployed in the directory where ProgramA is using the LibA then ProgrammA would not longer work.
For my own Libs I use a Major-Version-Number (.01, .02) if there are big changes. But the Lib I'm using is an external Lib and each version of it requires different licensing-keys (which are handled by the programs itself).
I tried to rename the external libs from "ExternalLib.dll" to "ExternalLib.v1.dll" and "ExternalLib.v2.dll", but when I run my fresh compiled programm it throws an exception that says "ExternalLib.dll could not be found". The reference in my project is set to "ExternalLib.v1.dll" and compilation works fine.
Any ideas / suggestions to handle different assembly versions in the same directory?
Unfortunately, the filename of the DLL file has very little do do with how .Net is loading these types. The actual name is written into the meta data of the assembly as part of the compilation process. So at runtime, it will be probing for ExternalLib.dll regardless of what you renamed the file to. The usual way to fix this is to install to the GAC and use Strong Naming to reference the specific version.
Given you may not be able to do this, there are 4 things you could try:
Ask the vendor to produce version specific DLL's for you. They could compile such that the version name is part of the filename and included in the assembly manifest. This would be the simplest solution for you.
Handle the AssemblyResolve event and manually try and use Assembly.Load to point at the file you want such that you can specify specifically which dll to use. See http://support.microsoft.com/kb/837908 for more information, but effectively you'll be using Assembly.LoadFrom(specific_path) to choose the file where the code will load from.
If possible, you might also be able to use ildasm.exe to decompile the dll's to Intermediate Language (IL), then use ilasm.exe to recompile it to a new dll name. You would then reference this new DLL name in your project.
If the assembly is not signed, then you may be able to edit the manifest yourself; you can either use a compatible binary editor or possibly MT.exe.

Resources embedded in several Satellite Assembly's

I know there are several questions about satellite Assembly's out there, but I still have some troubles when trying to implement them
My Goal is to separate each culture in a single assembly, giving me the flexibility to only re-compile one assembly at a time when required, I wouldn't like to compile all languages if I only want to make some minor changes to just one language
I want to fully understand how satellite Assembly's work. This is my current understanding:
Satellite Assembly's can be dropped in the bin directory without the need to recompile the whole application, which means the app does not require these assemblies in order to work correctly (as long as the fallback resource is specified)
S.A. has to be linked to a single culture
Now I can generate a S.A. using the al tool or Visual Studio can do it for me if I add the .resx files, the S.A. are created (in the bin folder I can see the folder structure for the specified cultures)
Question 1. Are these dll's equivalent, the one's generated by Visual Studio and the one's generated with the al tool?
Question 2. Do all these dll's must share a common name in order to work?? (I know for consistency they should, but if they do not share the name let's say creating them with the al tool specifying different names) can they still be recognized by the .Net framework to be loaded?
Question 3. If I want to use the ResourceManager class, do I have to instantiate one instance for each assembly-culture? (and since they contain the culture in their name, they have different assembly names, do I have to manually format the embedded resource file to load to match the current culture and load that assembly manually? Since they would probably not be loaded the first time, do I have to load it manually by specifying the file path inside the culture folder?)
Question 4. Are these S.A. loaded automatically by the .Net framework or do I have to explicitly load them?
Question 5. In case I have to load them, this means if I want to specify the resources declaratively in my control tags, do I have to create and register a custom resources factory in order to load them?
Question 6. If I add several resources for several cultures in a class project in visual studio with no code, they are automatically embedded, when I compile, the satellite assemblies for each culture are created, are these dll's related? I wonder if they are related by name, namespace or something
All these questions are based on this: I thought I would be able to just add the assemblies to the bin folder and specify something like a global assembly in the ResourceManager, and it would load automatically the resources even when they'd be in a different assembly (that's why my concern about the assembly names or how several satellite assemblies are related) just like when you define resources in a single assembly, you just call the Resources.MyResourceKey and that's it
I appreciate your hellp, this topic is driving me crazy =(
I know the resgen and al tools look a bit more complicated than they ought to be, but I am pretty sure that your goal is achievable, i.e. you can build your satellite assemblies outside of a Visual Studio solution (to save you having to maintain all your translated resources in your solution) but get exactly the same results.
Question 1: Yes
Question 2: Yes, the ResourceManager depends on the naming convention to load localized resources
Question 3: No. You can use the standard ResourceManager. In fact you don't have to use ResourceManager directly at all. Include your base resources in your solution and configure it with Build Action = Embedded Resource and Custom Tool = PublicResXFileCodeGenerator, then Visual Studio will automatically generate and maintain a class (with the same name as your resx file) that lets you access resources through static properties. Depending on Thread.CurrentThread.CurrentUICulture and on what satellite assemblies are deployed, these properties will either give you localized resources from a satellite assembly or from your base assembly.
Question 4: No. The ResourceManager does that automatically.
Question 5: See Q4. Nothing to do.
Question 6: See Q2. It's based on a naming convention (folder named as per the culture, satellite assembly named as per the base dll) and metadata (e.g. culture name used when compiling using al)

.NET 4.0 to 3.0 could not find any resources appropriate for the specified culture or the neutral culture

I found a free program on the web that was .NET 4.0, but had to copy over the code to compile VS2008. I'm thinking the way cultures is handled must be different in the versions of .NET.
I'm getting this error:
System.Resources.MissingManifestResourceException: Could not find any
resources appropriate for the specified culture or the neutral
culture. Make sure "A.B.C.Resources.ExceptionMessage.resources" was
correctly embedded or linked into assembly "A.B.C.csproj" at compile
time, or that all the satellite assemblies required are loadable and
fully signed.
It's a C# .dll (class library), and I'm calling it from a Console Program.
It does have a strong-key file assigned to it.
It's blowing up on any statement like this:
return ResourceManager.GetString("XYZ");
It looks like all the resources are in English, and that's the only language I need.
I'm just looking for how to avoid the exception.
When I copied over files, and rebuilt a new VS2008 project, there was no hierarchical relationship in Visual Studio Solution Explorer for the resource file. For example, ExceptionMessage.resx and ExceptionMessage.Designer.cs were at the same level; whereas normally the Designer.cs file is indented under the .resx file. I'm not sure what that happened.
So what I did was create a new .resx file, and carefully copy over using NotePad and filemerge programs, pieces of the .resx file and .cs file. Then it worked fine.
I'm still not absolutely sure what the problem was, but I know this fixed it. Lost about 5 hours today on this issue.
It might be worth to compare the [assembly: AssemblyCulture("")] properties in the assemblies from both your version 4 and version 3 solutions.
The default is - I think - none.
MSDN documentation:
Putting this attribute on an assembly and using something other than
the empty string ("") for the culture name will make this assembly
look like a satellite assembly, [...]
Perhaps you need to define it explicitly OR it already is defined but should not be?
I've had this difficulty and found that the cause had to do with Assembly name and Default namespace from project properties. It helps to set them both the same, or something to that effect.

Help with Assembly Information File in C#

What is the Assembly Information File for in C# and how do I use it?
The AssemblyInfo file is used to document your dlls or exes to describe where the code comes from, its version etc. If your code is publicly available then its certainly good practice to make sure you add useful information too it.
http://www.codinghorror.com/blog/archives/000141.html
If you build your project with NAnt there is also a useful target that allows you to build the assembly info dynamically.
http://nant.sourceforge.net/release/latest/help/tasks/asminfo.html
Right-click on any program icon, and select 'Properties'. Navigate to the 'Version' tab. That information you see is what is contained in the AssemblyInfo.cs file, among other things.
It holds information about your assembly. Author, Company, Version Numbers (build/minor/major/etc)
Try this article:
http://msdn.microsoft.com/en-us/library/1h52t681.aspx
It's a file created by the default project templates under the "Properties" folder that has attributes defined at the assembly-level that the C# compiler and framework use to store various bits of metadata like the title of the assembly, the version, the publisher, etc. There's other framework-specific attributes that you can throw in there such as XAML namespaces, Data Contract namespaces, etc. Basically any attributes that you define at the assembly level are typically placed in here.
There's nothing special about the name though. These attributes can actually appear anywhere in any code file.
I posted a neat little tip about dealing with the issue of having multiple AssemblyInfo files in different projects in a solution that all have common attributes.

Make C# assembly attribute show in details

Is there a way to make assembly attributes show up when you right click-> Properties->details on an exe?
I know about the standard ones but I want to add my own (e.g. Email).
Edit: Also if there is a way to do this post build, that would be fine.
The information on the Version tab is retrieved from the executable's VERSIONINFO resource (we're talking native Win32 resources here, not managed resources). By default the compiler will take information from some of the Assembly attributes and put into the VERSIONINFO resource. Unfortunately you can't change which attributes the compiler uses here, so you can't include your own information this way.
But if you really want you can create your own VERSIONINFO resource and put in a .RES file and embed in your executable using the Csc.exe /win32res compiler option.
Haven't seen a pure .NET solution, but perhaps you could you combine this with this?

Categories

Resources