Möchte man sich den IL-Code eines .NET Assemblies anschauen, so nutzt man dafür Tools wie NET.Reflector oder ILSpy. Für den Reflector gibt es dabei ein nettes AddIn welches auf den Namen „Reflector.FileDisassembler“ hört. Mit diesem ist es möglich ganze Assemblies in Visual Studio Projekt zu übersetzen. Zu finden ist das AddIn dabei unter http://www.denisbauer.com/NETTools/FileDisassembler.aspx.
Named Pipes zur Interprozesskommunikation
Interprozesskommunikation unter .NET ist so eine Sache. Da gibt es unter anderem das relativ mächtige Remoting Framework. Leider schlägt sich die Mächtigkeit auch in der Komplexität nieder. Wesentlich einfach wird das ganze mittels Named Pipes welche sich auch zur Interprozesskommunikation eignen. Dazu benötigt man einen Server und einen Client. Der Server könnte dabei unter .NET so aussehen:
Task.Factory.StartNew(() => { NamedPipeServerStream server=new NamedPipeServerStream("halfPipe"); server.WaitForConnection(); StreamReader reader=new StreamReader(server); StreamWriter writer=new StreamWriter(server); while(true) { string line=reader.ReadLine(); if(line=="HELLO") { writer.WriteLine("Hi"); writer.Flush(); } else { writer.WriteLine("Unknown command."); writer.Flush(); } } });
Auf der Clientseite sieht die Kommunikation fast genauso aus:
NamedPipeClientStream pipeStream=new NamedPipeClientStream("halfPipe"); pipeStream.Connect(); StreamReader reader=new StreamReader(pipeStream); StreamWriterwriter=new StreamWriter(pipeStream); writer.WriteLine("HELLO"); writer.Flush(); string ret=reader.ReadLine();
Damit ist die Kommunikation zwischen den Prozessen eingerichtet. Natürlich kann man nicht nur Strings sondern auch andere Datentypen über die „Named Pipes“ verschicken.
Public Key Token eines Assemblies ermitteln
Wenn man ein .NET Assembly mit einem Strong Name versehen hat, möchte man manchmal den „PublicKeyToken“ dieses Assemblies aus einem anderen Assembly ermitteln. Im ersten Schritt wird dazu das Assembly benötigt. Wenn es bereits eingebunden ist, kann mittels:
Assembly[] assemblies=AppDomain.CurrentDomain.GetAssemblies();
das richtige Assembly gesucht werden. Alternativ ist es auch möglich ein Assembly mittels:
Assembly assembly=Assembly.LoadFile(path);
von der Festplatte zu laden. Danach geht es an die Ermittlung des Public Key Tokens:
string[] parts=assembly.FullName.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries); string publicKeyToken=parts[parts.Length-1].Trim().Replace("PublicKeyToken=", "");
Dieses könnte dann in der Applikation mit einem bestehenden Schlüssel verglichen werden um die Integrität des geladenen Assemblies zu verifizieren.
Unterschiedliche Assemblies je nach Konfiguration einbinden
Manchmal ist es nötig je nach Konfiguration ein anderes Assembly in ein .NET/Mono Projekt einzubauen. Direkt im Visual Studio funktioniert das leider nicht. Allerdings kann man die Einstellung mit einem Texteditor in der Projektdatei vornehmen:
<Reference Include="libInterval" Condition="'$(Configuration)'=='Debug'"> <HintPath>libInterval\x32-debug\libInterval.dll</HintPath> </Reference> <Reference Include="libInterval" Condition="'$(Configuration)'=='Release'"> <HintPath>libInterval\x32-release\libInterval.dll</HintPath> </Reference>
Wichtig ist dabei der „Condition“-Teil welcher festlegt das die eine DLL nur bei der jeweiligen Konfiguration genutzt wird. Durch diesen landet das richtige Assembly später im entsprechenden Buildordner.
Managed Assembly-Architektur unter .NET ermitteln
Manchmal ist es nötig zu ermitteln für welche Plattform ein Assembly konfiguriert wurde. Dies kann man dabei unkompliziert über die „GetAssemblyName“ Funktion welche sich im Namespace „System.Reflection“ befindet ermitteln:
System.Reflection.AssemblyName.GetAssemblyName(@"C:\Temp\CSCL.dll");
Aus der Ausgabe:
{CSCL, Version=1.4.1.3, Culture=neutral, PublicKeyToken=null} CodeBase: "file:///C:/Temp/CSCL.dll" ContentType: Default CultureInfo: {} CultureName: "" EscapedCodeBase: "file:///C:/Temp/CSCL.dll" Flags: PublicKey FullName: "CSCL, Version=1.4.1.3, Culture=neutral, PublicKeyToken=null" HashAlgorithm: SHA1 KeyPair: null m_siInfo: null Name: "CSCL" ProcessorArchitecture: X86 Version: {1.4.1.3} VersionCompatibility: SameMachine
ist dann unter „ProcessorArchitecture“ auch die entsprechende Architektur ersichtlich.