How can I identify the client using a DLL from within the DLL?

  • Thread starter Thread starter AA2e72E
  • Start date Start date
I found the answer, I think.

System.Reflection.Assembly.GetCallingAssembly().GetModules()[0].FullyQualifiedName;

I have another question: Is there some way to have a function run
automatically upon an instance of a DLL being created?
 
AA2e72E said:
I found the answer, I think.

System.Reflection.Assembly.GetCallingAssembly().GetModules()[0].FullyQualifiedName;

I have another question: Is there some way to have a function run
automatically upon an instance of a DLL being created?

Define "created". In my dictionary, that would mean when you compile
the DLL. But I'm guessing you really mean "a DLL being loaded".

I'm not aware of a DLL entry point being exposed in managed code the way
they are for unmanaged DLLs (i.e. DllMain). Typically, instead in C#
you would use a static constructor. Depending on how the DLL gets
loaded, that may or may not get executed at _load_ time, but it will
definitely get executed before any other member of the class containing
the static constructor is accessed.

Note that the static constructor is per-class, so if your DLL has
multiple classes, you either would need to have a static constructor in
each class, or have only one class in the DLL be public. That said,
depending on why you feel you need this, it may make more sense to
follow the per-class convention and only initialize things in the
class(es) where the initialization is actually needed.

Pete
 
AA2e72E said:
I have another question: Is there some way to have a function run
automatically upon an instance of a DLL being created?

Assuming you mean when the DLL is being loaded by the
application (and not when it is created by the compiler):
Yes, by adding an assembly load event handler.

See (long) example below.

Arne

=====================================

C:\e\ass>type A.cs
using System;

namespace AHelper
{
public class AssHandler
{
public void AssLoad()
{
Console.WriteLine("A loaded");
}
}
}

namespace A
{
public class A1
{
}
public class A2
{
}
}

C:\e\ass>csc /t:library A.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.1
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.


C:\e\ass>type B.cs
using System;

namespace BHelper
{
public class AssHandler
{
public void AssLoad()
{
Console.WriteLine("B loaded");
}
}
}

namespace B
{
public class B1
{
}
public class B2
{
}
}

C:\e\ass>csc /t:library B.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.1
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.


C:\e\ass>type std.cs
using System;

using A;
using B;

namespace E
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("starting main");
A1 oa = new A1();
B2 ob = new B2();
}
}
}

C:\e\ass>csc /r:A.dll /r:B.dll std.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.1
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.


C:\e\ass>std
starting main

C:\e\ass>type refl.cs
using System;
using System.IO;
using System.Reflection;

namespace E
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("before A load");
Assembly a =
Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, "A.dll"));
Console.WriteLine("after A load");
object oa = a.CreateInstance("A.A1");
Console.WriteLine("before B load");
Assembly b =
Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, "B.dll"));
Console.WriteLine("after B load");
object ob = b.CreateInstance("B.B2");
}
}
}

C:\e\ass>csc refl.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.1
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.


C:\e\ass>refl
before A load
after A load
before B load
after B load

C:\e\ass>type tracer.cs
using System;
using System.Reflection;

public class Tracer
{
public static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyLoad += H;
Assembly.Load(args[0]).GetType(args[1]).InvokeMember("Main",
BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
null, null, new object[1] { null });
}
public static void H(object sender, AssemblyLoadEventArgs args)
{
string ns = args.LoadedAssembly.GetName().Name + "Helper";
object o = args.LoadedAssembly.CreateInstance(ns + ".AssHandler");
o.GetType().InvokeMember("AssLoad", BindingFlags.Public |
BindingFlags.Instance | BindingFlags.InvokeMethod, null, o, new object[0]);
}
}

C:\e\ass>csc tracer.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.1
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.


C:\e\ass>tracer std E.Program
A loaded
B loaded
starting main

C:\e\ass>tracer refl E.Program
before A load
A loaded
after A load
before B load
B loaded
after B load
 
Arne said:
Assuming you mean when the DLL is being loaded by the
application (and not when it is created by the compiler):
Yes, by adding an assembly load event handler.

See (long) example below.

Note that if you prefer to put attributes on the classes
and methods to cal during load instead of using magic
names, then that is just a matter of reflecting over the
assembly.

Arne
 
Back
Top