I am trying to get the executing assembly version in C# 3.0 using the following code:
var assemblyFullName = Assembly.GetExecutingAssembly().FullName;
var version = assemblyFullName .Split(',')[1].Split('=')[1];
Is there another proper way of doing so?
Two options... regardless of application type you can always invoke:
Assembly.GetExecutingAssembly().GetName().Version
If a Windows Forms application, you can always access via application if looking specifically for product version.
Application.ProductVersion
Using GetExecutingAssembly for an assembly reference is not always an option. As such, I personally find it useful to create a static helper class in projects where I may need to reference the underlying assembly or assembly version:
// A sample assembly reference class that would exist in the `Core` project.
public static class CoreAssembly
{
public static readonly Assembly Reference = typeof(CoreAssembly).Assembly;
public static readonly Version Version = Reference.GetName().Version;
}
Then I can cleanly reference CoreAssembly.Version in my code as required.
In MSDN, Assembly.GetExecutingAssembly Method, is remark about method "getexecutingassembly", that for performance reasons, you should call this method only when you do not know at design time what assembly is currently executing.
The recommended way to retrieve an Assembly object that represents the current assembly is to use the Type.Assembly property of a type found in the assembly.
The following example illustrates:
using System;
using System.Reflection;
public class Example
{
public static void Main()
{
Console.WriteLine("The version of the currently executing assembly is: {0}",
typeof(Example).Assembly.GetName().Version);
}
}
/* This example produces output similar to the following:
The version of the currently executing assembly is: 1.1.0.0
Of course this is very similar to the answer with helper class "public static class CoreAssembly", but, if you know at least one type of executing assembly, it isn't mandatory to create a helper class, and it saves your time.
using System.Reflection;
{
string version = Assembly.GetEntryAssembly().GetName().Version.ToString();
}
Remarks from MSDN http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getentryassembly%28v=vs.110%29.aspx:
The GetEntryAssembly method can return null when a managed assembly has been loaded from an unmanaged application. For example, if an unmanaged application creates an instance of a COM component written in C#, a call to the GetEntryAssembly method from the C# component returns null, because the entry point for the process was unmanaged code rather than a managed assembly.
Product Version may be preferred if you're using versioning via GitVersion or other versioning software.
To get this from within your class library you can call System.Diagnostics.FileVersionInfo.ProductVersion:
using System.Diagnostics;
using System.Reflection;
//...
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
var productVersion = FileVersionInfo.GetVersionInfo(assemblyLocation).ProductVersion
This should do:
Assembly assem = Assembly.GetExecutingAssembly();
AssemblyName aName = assem.GetName();
return aName.Version.ToString();
I finally settled on typeof(MyClass).GetTypeInfo().Assembly.GetName().Version for a netstandard1.6 app. All of the other proposed answers presented a partial solution. This is the only thing that got me exactly what I needed.
Sourced from a combination of places:
https://msdn.microsoft.com/en-us/library/x4cw969y(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/2exyydhb(v=vs.110).aspx
Related
I have two dotnetcore2.1 projects. First project calls a method of the second project via reflection.
using System;
using System.Reflection;
namespace experiment1
{
class Program
{
static void Main(string[] args)
{
Type _type = Type.GetType("experiment2.Program");
object _object = Activator.CreateInstance(_type);
MethodInfo info = _type.GetMethod("SecondProjectsMethod");
info.Invoke(_object, new object[]{});
}
}
}
I can't give any reference to the Second Project nor changes its code. How can I make this call successfully without adding a Reference to the First Project? I tried to add records to the first project's deps-file and execute the first program like this:
dotnet exec --depsfile experiment1.deps.json experiment1.dll
It didn't work. Is it even possible to do this by changing deps-file or any other config? Or should I manipulate .dll file somehow? Which direction I should go?
You can manually load the assembly by calling:
Assembly.Load("experiment2");
It should look for the assembly in the current folder, or use the deps file to locate it. After that, you should be able to use Type.GetType just fine.
If you want to specify the full path to the assembly, use AssemblyLoadContext.Default.LoadFromAssemblyPath instead.
You can refer to this page for more information on the different ways of loading an assembly in .net core.
I am having difficulty with using reflections dynamically eg. query a .exe file without requiring a reference to be added for every assembly which I wish to query against.
So for instance, the code below is the regular way to get a hold of a class to then be checked.
AssemblyName assembly_name = new AssemblyName( "Name" );
The issue is not adding the argument in to the code but the code requirng direct reference to the new assembly to check against.
Any suggestions are welcome.
It sounds like you're really just trying to load an assembly at execution time. Look at Assembly.Load and Assembly.ReflectionOnlyLoad.
Maybe you're looking for something like Cecil. It's a library (available on Windows and other platforms) that allows to query metadata without the need to resolve all references.
I'm not really sure what you mean by "query". If you want to know how to create an instance from an assembly using reflection, here is an example:
// From within the current assembly
public CartesianType CreateInstance(string fullyQualifiedClassName)
{
Assembly assembly = Assembly.GetExecutingAssembly();
Type target = assembly.GetType(fullyQualifiedClassName, true, true);
return (CartesianType)Activator.CreateInstance(target);
}
// From an external assembly already referenced in your project
public SomeClass CreateInstance(string fullyQualifiedClassName)
{
Assembly assembly = Assembly.GetAssembly(typeof(SomeClass));
Type target = assembly.GetType(fullyQualifiedClassName, true, true);
return (SomeClass)Activator.CreateInstance(target);
}
All other methods must use Load or LoadFile, LoadFrom etc.
C# / .net framework
What is the most reliable way to determine whether a class (type) is a class provided by the .net framework and not any of my classes or 3rd party library classes.
I have tested some approaches
The namespace, e.g. starting with "System."
The Codebase of the assembly, where the dll is located
All this "feels" a little clumsy though it works.
Question: What is the easiest and most reliable way to determine this?
You could check the assembly's public key token. Microsoft (BCL) assemblies will have the public key token b77a5c561934e089 or b03f5f7f11d50a3a. WPF assemblies will have the public key token 31bf3856ad364e35.
In general, to get the public key token of an assembly, you can use sn.exe-Tp foo.dll. sn.exe is part of the Windows SDK, which you should already have.
You can get the public key token from the assembly's full name (e.g. typeof(string).Assembly.FullName), which is just a string, or you can get the raw public key token bytes from the assembly by doing a P/Invoke into StrongNameTokenFromAssembly.
Read the Assembly Company Attribute from the assembly
[assembly: AssemblyCompany("Microsoft Corporation")]
http://msdn.microsoft.com/en-us/library/y1375e30.aspx
using System;
using System.Reflection;
[assembly: AssemblyTitle("CustAttrs1CS")]
[assembly: AssemblyDescription("GetCustomAttributes() Demo")]
[assembly: AssemblyCompany("Microsoft")]
namespace CustAttrs1CS {
class DemoClass {
static void Main(string[] args) {
Type clsType = typeof(DemoClass);
// Get the Assembly type to access its metadata.
Assembly assy = clsType.Assembly;
// Iterate through the attributes for the assembly.
foreach(Attribute attr in Attribute.GetCustomAttributes(assy)) {
// Check for the AssemblyTitle attribute.
if (attr.GetType() == typeof(AssemblyTitleAttribute))
Console.WriteLine("Assembly title is \"{0}\".",
((AssemblyTitleAttribute)attr).Title);
// Check for the AssemblyDescription attribute.
else if (attr.GetType() ==
typeof(AssemblyDescriptionAttribute))
Console.WriteLine("Assembly description is \"{0}\".",
((AssemblyDescriptionAttribute)attr).Description);
// Check for the AssemblyCompany attribute.
else if (attr.GetType() == typeof(AssemblyCompanyAttribute))
Console.WriteLine("Assembly company is {0}.",
((AssemblyCompanyAttribute)attr).Company);
}
}
}
}
A couple of ideas:
In Visual Studio, within Solution Explorer, expand References, right click a reference, then choose Properties and look at the path, example:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll
I'm guessing that most assemblies in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ are likely to be standard .NET.
Also, you could look up the assembly in MSDN library, example:
http://msdn.microsoft.com/en-us/library/system.aspx.
You say about Base Class Library?
You can consult here: http://en.wikipedia.org/wiki/Base_Class_Library
Suppose you are given a Class.dll assembly compiled from the following simple code:
namespace ClassLibrary
{
public class Class
{
}
}
And consider a different project with the above Class.dll as a project reference and with the following code:
Assembly assembly = Assembly.LoadFrom(#"Class.dll");
Type reflectedType = assembly.GetType("ClassLibrary.Class");
Type knownType = typeof(ClassLibrary.Class);
Debug.Assert(reflectedType == knownType);
The assertion fails, and I don't understand why.
The assertion succeeds if I replace the ClassLibrary.Class with, say, the System.Text.RegularExpressions.Regex class and Class.dll with System.dll, so I'm guessing it has something to do with the project properties ? some Compilation switch perhaps?
Thanks in advance
The problem is load contexts: assemblies loaded via .LoadFrom are kept in a different "pile" than those loaded by Fusion (.Load). The types are actually different to the CLR. Check this link for more detail from a CLR architect.
You're probably loading two different copies of the same assembly.
Compare knownType.Assembly to reflectedType.Assembly in the debugger, and look at the paths and versions.
I would imagine that you are not referencing the same assembly that you are loading from disk.
This example (when compiled as Test.exe) works just fine:
using System;
using System.Reflection;
class Example
{
static void Main()
{
Assembly assembly = Assembly.LoadFrom(#"Test.exe");
Type reflectedType = assembly.GetType("Example");
Type knownType = typeof(Example);
Console.WriteLine(reflectedType == knownType);
}
}
What is the best way to get the application name (i.e MyApplication.exe) of the executing assembly from a referenced class library in C#?
I need to open the application's app.config to retrieve some appSettings variables for the referenced DLL.
To get the answer to the question title:
// Full-name, e.g. MyApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
string exeAssembly = Assembly.GetEntryAssembly().FullName;
// or just the "assembly name" part (e.g. "MyApplication")
string exeAssemblyName = Assembly.GetEntryAssembly().GetName().Name;
As mentioned by #Ben, since you mention wanting to get the configuration information, use the ConfigurationManager class.
If you want to get the current appdomain's config file, then all you need to do is:
ConfigurationManager.AppSettings....
(this requires a reference to System.Configuration of course).
To answer your question, you can do it as Ray said (or use Assembly.GetExecutingAssembly().FullName) but I think the problem is easier solved using ConfigurationManager.
To get the exact name without versions, etc. use:
string appName = Assembly.GetEntryAssembly().GetName().Name;
Works with .NET v1.1 and later.
You can get the assembly through the class type...
typeof(MyClass).Assembly
If you want the name of the parent EXE and not the referenced DLL assembly - you will need to use this:
Assembly.GetEntryAssembly().GetName().Name
This will return the EXE name (minus the .EXE part).
Using GetExecutingAssembly() is not right as per the OP's question (first paragraph of it!) as it will return the DLL name.
You should never couple your libraries to a consumer (in this case Web, WinForm or WCF app). If your library needs configuration settings, then GIVE it to the library.
Don't code the library to pull that data from a consumer's config file. Provide overloaded constructors for this (that's what they are for).
If you've ever looked at the ConfigurationManager.AppSettings object, it is simply a NameValueCollection. So create a constructor in your library to accept a NameValueCollection and have your consumer GIVE that data to the library.
//Library
public class MyComponent
{
//Constructor
public MyComponent(NameValueCollection settings)
{
//do something with your settings now, like assign to a local collection
}
}
//Consumer
class Program
{
static void Main(string[] args)
{
MyComponent component = new MyComponent(ConfigurationManager.AppSettings);
}
}
If you want to read (and display) version number:
Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
AssemblyName assname = ass.GetName();
Version ver=assname.Version;
Somewhere in application (ie Title block in a Windows form)
this.Text = "Your title Version " + ver;
For the short name of an assembly from a class instance:
Me.GetType ().Assembly.GetName().Name