VB6 Win32 API Tutorial Code Has Been Found!
I know you've been waiting for it :).
I still get a request now and then for the source code to the VB6 API book I wrote before fire was discovered, but I lost that code around the time steam trains were widely used. Now someone has found that code, and I've posted it to my site. You can get it here. Enjoy!
Removing Regions Using Project Roslyn
Last week Magenic posted my article on using Roslyn to remove those pesky #region and #endregion directives from a code base. You can read about it here - enjoy!
Roslyn Samples
I recently finished up a chapter for "Metaprogramming in .NET" on Roslyn. One of the things I found most interesting about Roslyn was not the "generate and execute code on the fly" aspect. That's still really cool, and Roslyn makes it really easy to do that dynamic code execution relative to APIs like System.Reflection.Emit. But what I found pretty addictive was the Visual Studio integration portions. Being able to create code issues and refactorings with the code the user was typing was really not that hard to do. Overall, given that it's only a CTP, there's a lot to play with in Roslyn (and it's relatively stable, though it is a little slow).
If you want to take a look at the code samples I've created, you can go here. Here's a quick list of what's in "Chapter 12":
- DynamicMocks.Roslyn - A simplistic mock generator, but the possibilities can go much farther than what I've done as an example.
- Wcf.Issues - A code issue to fix
IsOneWay issues in WCF operations.
- Core.Refactorings - A refactoring that auto-arranges class members.
While it says on Roslyn's web site that the project "is a long lead project which we are considering for the post-Visual Studio 11 timeframe", I still think it's important to look at where Roslyn is going. My personal opinion is that Roslyn will have a large impact on the .NET world once it's released, and it's worth a .NET developer's time to be aware of what can be done with the functionality that's contains within Roslyn.
Using ExtendedReflection To Manage Your .NET Code at Runtime
Consider the following (bad) code:
class Program
{
static void Main(string[] args)
{
new SubClass("go");
}
}
public abstract class BaseClass
{
protected BaseClass()
{
this.Run();
}
protected abstract void Run();
}
public class SubClass
: BaseClass
{
private string data;
public SubClass(string data)
: base()
{
this.data = data;
}
protected override void Run()
{
Console.Out.WriteLine(data.Length);
}
}
The issue of calling virtual members in constructor has been discussed in depth before, so I won't cover it here (see http://blogs.msdn.com/b/scottwil/archive/2005/01/14/353177.aspx and http://msdn.microsoft.com/en-us/library/ms229060.aspx for details). It's not that you can't do it right, but it can cause issues if you're not a little careful. This issue actually bit me years ago because I'm fond of designs where my base class tells the subclasses to do something when the constructor is called. However, it's too error-prone - all it takes is for someone to subclass my class that's a little careless and then all sorts of bad things happen.
A while ago I ran into Pex (http://research.microsoft.com/en-us/projects/pex/), and I fell in love with its power and capabilities. It was kind of freaky-scary what Pex would uncover in my code - suddenly there were corner cases with a bright shining light on them and I realized that I have subtle errors that I really should fix! Pex is also interesting because of the technologies and frameworks that it uses that do all sorts of advanced, cool stuff. One in particular is called ExtendedReflection. This is basically a managed profiler - yes, you read that right. For the longest time I was under the impression that you can't write a profiler in .NET in managed code, but I was wrong, because ExtendedReflection does just that.
So what does this have to do with calling virtual members in constructors? Think of flipping around IDisposable. See, IDisposable works with the using statement in C# to automatically call the Dispose() method. Of course, this is all compiler magic; the runtime doesn't treat IDisposable-based objects any differently, so if you forget to call Dispose() in a timely manner, you could leak resources (depending on what the object used during its lifetime). Now, you could argue that the runtime should handle this for you, but that's not an easy problem to solve - in fact, it's downright difficult. But ... wouldn't it be interesting if you could have the runtime call a method on your object if it implemented a specific interface after the constructor was done but before anything else was done to the object?
Now I'm not suggesting that the .NET team do this. It's just a pie-in-the-sky idea: creating an IInitializer interface with an Initialize() method that would be called for you with the guarantees specified above. You could try and handle this with code weaving techniques, but the simple fact is, unless the runtime does this across the board, that guarantee may not be satisfied and bad things may happen. But let's try to get close by augmenting the runtime execution of code with ExtendedReflection.
The first thing you need to do is install Pex. Once you have that done, take some time to look at the ExtendedReflection examples - the code I'm about to show is just a slight modification of one of the samples. With that work out of the way, let's add the code to call Initialize() right after an object is created. The starting point is creating a console application that will set up the managed profiler and then run the target program:
public static class Program
{
[LoaderOptimization(LoaderOptimization.MultiDomain)]
static void Main(string[] args)
{
var application = args[0];
Console.Out.WriteLine("Setting environment...");
var startInfo = new ProcessStartInfo(application, null);
startInfo.UseShellExecute = false;
var environmentVariables = Program.GetMonitoringEnvironmentVariables();
foreach (DictionaryEntry environmentVariable in environmentVariables)
{
startInfo.EnvironmentVariables[(string)environmentVariable.Key] =
(string)environmentVariable.Value;
}
Console.Out.WriteLine("Starting target process, {0}...", application);
using (var process = Process.Start(startInfo))
{
process.WaitForExit();
}
}
The profiler API needs you to set up some environment variables before you launch the real program. Here's what GetMonitoringEnvironmentVariables() does:
private static StringDictionary GetMonitoringEnvironmentVariables()
{
var environmentVariables = new StringDictionary();
var userAssembly = Metadata<ExecutionMonitor>.Assembly;
var userType = Metadata<ExecutionMonitor>.Type;
ControllerSetUp.SetMonitoringEnvironmentVariables(environmentVariables,
MonitorInstrumentationFlags.All,
false, userAssembly.Location, userType.FullName,
null, null, null, null, null,
new string[] { "*" },
new string[] {
Metadata<Object>.Assembly.ShortName,
Metadata<_ThreadContext>.Assembly.ShortName,
userAssembly.ShortName },
null, null, null, null, null, null,
@"Modifier.txt",
false, null, true, false, ProfilerInteraction.Fail, null);
return environmentVariables;
}
}
Don't worry too much about what GetMonitoringEnvironmentVariables() does. If you're really curious, read the docs, but for our purposes it's sufficient to know that this gets the profiler hooks in place.
The next is to create a custom execution monitor (which is what was used to define the userType variable above). This is what will get called whenever a thread is created in the application, which is where you'll set up your hook:
internal sealed class ExecutionMonitor
: ExecutionMonitorBase
{
protected override IThreadExecutionMonitor
CreateThreadExecutionMonitor(int threadId)
{
return new ThreadExecutionMonitor(threadId);
}
}
The ThreadExecutionMonitor class is the one that does all the heavy lifting:
internal sealed class ThreadExecutionMonitor
: ThreadExecutionMonitorEmpty
{
private MethodBase initializeMethod;
internal ThreadExecutionMonitor(int threadId)
: base(threadId)
{
this.initializeMethod = typeof(IInitializer).GetMethod("Initialize");
}
public override void AfterNewobjObject(object newObject)
{
var initializer = newObject as IInitializer;
if (initializer != null)
{
initializer.Initialize();
}
}
public override void Call(Method method)
{
this.HandleCall(method);
}
public override void Callvirt(Method method)
{
this.HandleCall(method);
}
private void HandleCall(Method method)
{
var initializerType = Metadata<IInitializer>.Type;
var foundMethod = initializerType.GetMethod(this.initializeMethod);
TypeEx declaredType = null;
if (method.TryGetDeclaringType(out declaredType))
{
if ((from declaredInterface in declaredType.Interfaces
where declaredInterface == initializerType
select declaredInterface).FirstOrDefault() != null)
{
Method sourceMethod = null;
if (method.TryReverseVTableLookup(Metadata<IInitializer>.Type,
out sourceMethod) && sourceMethod != null)
{
if (foundMethod.Signature == sourceMethod.Signature)
{
throw new NotSupportedException(
"Modifier: This method can only be invoked once.");
}
}
}
}
}
}
The first thing that's done is getting a reference to the Initialize() method via a MethodBase object - I'll get back to why this is needed in a moment. Next, AfterNewobjObject() is overriden to provide the key hook to know when the newobj IL instruction was finished. At that point, you know the object has been created, but nothing else has been done to it, so that's the perfect time to see if that object implements IInitializer so you can call Initialize()! Finally, two other method are overriden: Call() and Callvirt(). This is done to add a check to ensure that Initialize() is called once, and only once by the hook added via AfternewobjObject(). If code in the application would try to call Initialize(), that would be considered an error because we don't want that setup code to run more than one time. The code within HandleCall() may look a little odd, but it's all based on the ExtendedReflection API, and it'll catch if Initialize() is invoked by code within the profiled application.
So, once everything is in place, I can create this application:
class Program
{
static void Main(string[] args)
{
Program.RunTester();
Program.RunTester();
}
private static void RunTester()
{
var tester = new Tester() { Data = Guid.NewGuid().ToString("N") };
Console.Out.WriteLine(tester.Data);
try
{
tester.Initialize();
}
catch (NotSupportedException ex)
{
Console.Out.WriteLine(ex.Message);
}
}
}
public sealed class Tester : IInitializer
{
public string Data { get; set; }
public void Initialize()
{
Console.Out.WriteLine("I have been initialized.");
}
}
When I run it under my managed profiler, this is what I get:
Setting environment...
Starting target process, Modifier.Example.exe...
I have been initialized.
7315d24e463446128897af9993703017
Modifier: This method can only be invoked once.
I have been initialized.
08c24f49a22a4bc7b720d0a4f40dd610
Modifier: This method can only be invoked once.
Press any key to continue . . .
Slick!
Again, this is just experimental code. I strongly recommend you don't just throw this on to a production machine and start adding all sorts of crazy hooks into your application via this managed profiler. But it is fun to play with code as it's executing at runtime. If you want to play with the code (and you have Pex installed), go here (http://www.jasonbock.net/JB/Code/Modifier.zip) to get it. Enjoy!
Using Any Test Framework in VS11
UPDATE: I figured out how to get code coverage working. It's the "Analyze Code Coverage" button in the Unit Test Explorer. I have to find the keystrokes to use this though as going through a UI to run tests is not fun.
For a while, I used MSTest.
It's not that I liked it. It's not that I didn't like it. And just because it was integrated with Visual Studio didn't make it an automatic choice either. But as a testing framework, it was ... OK. I know others that disagree with my view, and that's OK. It doesn't mean I didn't like NUnit or xUnit.net; quite the opposite, actually. But it was there when I installed Visual Studio, and frankly, for some of the clients I've been at, that's a win to get them to use it for testing. I'd rather have my team write tests than get hung up on using "yet another framework" and spending time over which one we should pick. (I know, that's kind of sad, but nothing's perfect in life).
With VS11, you'll be able to plug in any testing framework you like. I tried that yesterday with xUnit.net and I was pleasantly surprised at how easy it was to get it up and running. Just read Brad Wilson's blog post on it. The steps you need to take are simple:
- Nuget xUnit.net
- Install the prototype unit test plugin
- Write tests
- Execute tests
Simple. The same story either exists now for the other .NET-based testing frameworks or will in the very near future. I couldn't get code coverage working with my small sandbox solution, but I didn't look that hard either with it. I may be missing something obvious with that. I'm assuming that the unit test running will also produce code coverage results with the other frameworks (at least I hope it will).
This is a long time coming. At this point, I'm going to convert all my tests for my personal projects away from MSTest. I didn't hate it, but now I really don't see any need to use that framework. Other testing frameworks have some appealing options to them and with VS integration it's much more appealing to use those frameworks.
Minneapolis Airport and Bodyscanners
Recently I had to fly to Los Angeles to attend the BUILD conference. Flying these days is not an experience I like to make a habit of, but in relatively small doses I'll do it (especially if I get a free computer out of it :) ). However, this time it was a little disconcerting, because ... well ... let me explain.
I showed up to the airport just after lunch on Monday. I had plenty of time to get to my flight. My wife had to get back home to pick up my older son from school, and I wanted to work on some stuff before my flight, so I was in no rush. I already had my ticket and I had no bags to check, so I headed straight for the security checkpoint. I noticed that they had just constructed a new "area 6" where there were multiple body scanners (4, I believe) way down in south corner, so I naturally headed for the regular metal detectors. There was a line that had one metal detector, but again, my flight didn't leave for 3 hours, and since I still had a choice, I had no issue waiting for 10-20 minutes.
Of course, someone didn't like that option being used.
A woman kept coming over to our line and said in a very demeaning way that we should head over to "area 6" because there's 4 lines over there and there's only one line where I was. She basically made people feel guilty about standing in the line I was in, and almost made it seem like we had to go over there.
Of course, no one actually said I had to move either, so I stayed in line.
She did this about 3 or 4 times while I was waiting in line. Finally, someone asked her if we had to move. She said no, but her tone and attitute was childish at best, saying things like, "well, look, people that moved from here to there 5 minutes ago are already through security." You had to be there to hear the tone of "you're all morons for standing here" in her speech. Well, I didn't need to rush that fast either, so I stayed in line, got through security, and moved on.
I'm more than convinced at this point that every airport will eventually get converted to having nothing but body scanners.
I'm really not sure what I think about that either.
Using System.Reflection.Emit in a Windows 8 Metro style Application
I just got back from BUILD yesterday, and I wanted to spend some time going over some stuff that I worked on during the event. Essentially, I wanted to see if you use Reflection.Emit in a Metro style application. I know, that's probably not the big use case that Microsoft is looking at, but I've found throughout my career that trying to see what you can do at a lower-ish level in a given environment is a good way to understand what works (or what doesn't) and what's really going on.
So, I created a VS11 solution with a Metro style application and a .NET class library:
The reason I did this is because there is no System.Reflection.Emit in WinRT. My personal guess is that this was done as you probably don't want a Metro style application you installed from the store (when that eventually becomes available) that can generate code that wasn't analyzed via the store submission process. Therefore, you need to throw all your Reflection.Emit code in a .NET class library.
Here's what my code does:
public static class Emitter
{
public static string EmitThis()
{
var name = new AssemblyName("EmittedCode");
var builder = AppDomain.CurrentDomain.DefineDynamicAssembly(
name, AssemblyBuilderAccess.Run);
var module = builder.DefineDynamicModule(name.Name);
var type = module.DefineType("EmittedType", TypeAttributes.Public);
var method = type.DefineMethod("EmittedMethod",
MethodAttributes.Public | MethodAttributes.Static,
typeof(string), Type.EmptyTypes);
var generator = method.GetILGenerator();
generator.Emit(OpCodes.Ldstr, "I did it in emitted code.");
generator.Emit(OpCodes.Ret);
var createdType = type.CreateType();
return (string)createdType.GetMethod(
"EmittedMethod").Invoke(null, null);
}
}
It's simple, but that's good enough for demo purposes.
Now, let's add it to the Metro style application:
Whoops! You can't add a reference to assemblies from .NET projects in a Metro style application. But you can reference the assembly directly. Note that this hardcodes the assembly reference to the bin\debug directory. You could add a post-build event to put the results of compilation in a directory and reference the assembly that way, but again, for demo purposes, this works.
Now I can run the code this way:
private void OnEmitClick(object sender, RoutedEventArgs e)
{
this.EmitResult.Text = Emitter.EmitThis();
}
And when I run my Metro style application...:
It works.
Now, remember, just because you can do something doesn't mean you should. As I stated above, an application like this will probably never get in the store. It's doing something that goes beyond what Microsoft wants (or doesn't want) a Metro style application to do. It does run locally, and I'm guessing you could ship the package around to others so they could run it locally as well, but I really don't know if that would work as well. There's Metro style applications from the store and there's Windows 7 desktop applications and they both run on Windows 8; it'll be interesting to see if there will be apps "in the middle", so to speak.
I do know that you would need functionality like this for libraries like NSubstitute. They rely on code being generated on the fly from Reflection.Emit; even though System.Linq.Expressions is in WinRT, that's not full-featured enough for proxies (at least not that I can tell right now). But doing that all locally in a unit test will probably be "OK"; you just can't ship applications like that into the store.
You can get the code here. Note that this is only going to work with the VS11 Ultimate preview and Windows 8 (though you'll be able to look at the code file assets in any Windows OS). Enjoy!
The Sabbatical's Over
For the last two months, I've had the incredibly good fortune to take that time off while getting paid. Magenic gives each of their employees a 3-month paid sabbatical after 10 years of service. I decided to take 6 weeks off and cash out the rest, and I added a vacation week before and after the sabbatical time. This was truly a once-in-a-lifetime opportunity. I can't think of any other company that provides such a benefit to their employees. And it's been wonderful to spend so much time with my family. Here's a quick summary of the highlights:
- The family got to spend a week in San Diego, where we went to Legoland, the San Diego Zoo, and Sea World.
- Liz and I went out to the east coast where we spent 2 days in Vermont, and 2 days in Connecticut (fortunately before Irene ravaged the coastline). I got to take a tour of a local winery in Connecticut and for me, that was the highlight of the trip.
- I took a 4-day trip to Wisconsin to speak at a local .NET user group, golf with some friends, and I ended up playing some music on a Saturday night.
- I played a fair amount of Halo: Reach.
- I tried to keep writing more of my "Metaprogramming in .NET" book. That didn't go as well, but near the end I got back on track and finished up another chapter.
- I started playing my guitar more. I'm hoping to start another musical adventure with a friend of mine later in October so I needed to get rid of the rust.
- I didn't do a lot with programming, and I'm kind of glad I stayed away from it. Sure, I worked on my book, but I didn't dive into any new languages or anything else programming-related. Kind of happy I didn't!
I didn't get everything done that I wanted to do, but I also got to do a lot of things that I did want to do. Overall I thorougly enjoyed the time off, and I'm happy I work for a company that provides such an amazing benefit.
Truth be told, though, I'm glad I'm going back to work. The time-off was fun, but I think 8 weeks was enough. I want to get back and start working with technology again, and I'm going to be quite busy right away. In a couple of days I'm heading to HDC11 where I'm doing a talk on Pex. The week after I'm going to BUILD and ... well, we'll see what happens with that conference and its focus on Windows 8 (I'm excited and a bit cautious at the same time). Oct. 8th and 9th is Twin Cities Code Camp 11, and it's shaping up to be another amazing event. I've also submitted talks for Iowa Code Camp and Chippewa Valley Code Camp - hopefully I'll end up at those Code Camps as well. I'm also flying to Redmond in Oct. to speak at VSLive, where I'm doing two talks.
The batteries have been recharged - it's time to get back to work :).