Say that you are debugging a .NET application in windbg and happen to have a System.Reflection.RuntimeAssembly (the actual implementation of System.Reflection.Assembly) and you want to find out which assembly it actually references. You could try dumping the object (i'm using the sosex extension here):
That wasn't very helpful. The object is just a thin wrapper around the native object pointed to by m_assembly. So what is this object? This is what it looks like:
A good trick is to check whether the first value is a vtable pointer:
So apparently the object is a DomainAssembly object, whatever that is (you can find some of these classes in the Rotor source, but the structure of them are vastly different). Using this trick combined with the !mln sosex command we find:
The PEAssembly object:
CAssemblyName? That sounds promising, right?
There was the name. And we had a pointer to the AppDomain earlier, so that should be sufficient to uniquely identify the assembly. I haven't figured out where the actual assembly or module objects as used by !DumpAssembly and !DumpModule resides, but they are probably somewhere in there (the modules are CModule objects, the assembly objects starts with a null pointer, so I couldn't tell the C++ class from that).
Disassembling a custom attribute gives you a blob of raw bytes – what do they mean? Here is an example from the output from ildasm:
This represents a DefaultMemberAttribute(“Item”) which is autgenerated by C# when your class has an indexer. The word “Item” is definitely in there – but what does the rest of the data mean? A google search doesn’t give any useful answer from what I could find. I ended up looking in the Ecma Standard (page 267). This diagram gives an overview of the structure:
The prolog is always 0x0010 and little-endian encoded. The FixedArgs are the arguments to the constructor and the NamedArgs are properties. A string is encoded as a SerString, which is a single byte length called a PackedLen followed by a UTF8 string. NumNamed is also a little-endian encoded integer containing the number of properties being set (named arguments).
So in this case the data can be broken down as:
01 00: The Prolog (0x0010 in little-endian)
04: The string is 4 characters long
49 74 65 6d: "Item"
00 00: We have 0 properties
UPDATE: The screenshot below was lost to the big /dev/null in a server move, so you have to use your imagination.
Can you make a property in C# that you can only add to and remove from? That is what an event does, but that only works with delegates. You can (ab)use an implicit conversion to get something like this:
It works – I wouldn’t recommend using it in production code though… Maybe more interresting is what would happen if we modified the CIL for an event to accept a non delegate type. Well let’s try it and see what happens!
The original C# code:
Relevant parts of the generated CIL code:
Let us replace “System.Action” with “System.Object” and see what happens. Running ilasm:
C:\Users\poizan\Documents\Visual Studio 2010\Projects\Test>ilasm /DLL EventTest.il
Microsoft (R) .NET Framework IL Assembler. Version 4.0.30319.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembling 'EventTest.il' to DLL --> 'EventTest.dll'
Source file is ANSI
Assembled method EventTest.EventTester::get_TestList
Assembled method EventTest.EventTester::add_TestEvent
Assembled method EventTest.EventTester::remove_TestEvent
Assembled method EventTest.EventTester::.ctor
Creating PE file
Class 1: EventTest.EventTester
Emitting fields and methods:
Class 1 Fields: 1; Methods: 4;
Resolving local member refs: 7 -> 7 defs, 0 refs, 0 unresolved
Emitting events and properties:
Class 1 Events: 1; Props: 1;
Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved
Writing PE file
Operation completed successfully
So far so good. Let us try to use it:
It builds successfully. And running it:
And that is one more thing the C# compiler supports just fine but refuses to create.
How do you tell if an exception from a call to a webservice is caused by an IO error?
public static bool IsIoException(Exception e)
return (e is TimeoutException || e is CommunicationException || e is EndpointNotFoundException) && !(e is FaultException);
FaultException is derived from CommunicationException, but it occours when the server sends a SOAP fault back, so definitely not a communication problem (at least between client and webservice). I’m not sure why an EndpointNotFoundException would be thrown because of not being able to talk with the host, but I’ve seen it happen after unplugging my ethernet cable…
So why exactly can’t I just have one sort of exception to catch? Am I not supposed to handle a lost connection in a graceful way?
Oww Microsoft thou art a heartless bitch…
I haven’t tested if this only applies to forms shown with ShowDialog or to every form, but the form will always have a default (accept) button – the one receiving enter presses.
Setting the AcceptButton property to null will nevertheless select a button as the default button. Actually the AcceptButton property is complety ignored. Don’t believe anything on the MSDN page. The only thing that decides which button receives an enter press is which control has focus.
So what can you do if you don’t want a button to has focus when first showing the form? A control must have focus, and it must be visible. But nothing stops you from placing it in an invisible position such as setting Left to -1000. Set it as the form’s ActiveControl and set TabStop to false, meaning that the user won’t get back to the dummy button when tabbing around.