Scott Hanselman

ASP.NET MVC Preview 3

May 27, '08 Comments [36] Posted in ASP.NET | ASP.NET MVC | Screencasts | Source Code
Sponsored By

The Gu has announced another regular drop of ASP.NET MVC. This one is Preview 3 and the goodness can be found at the http://www.asp.net/mvc/ landing page.

How does this relate to Visual Studio 2008/.NET 3.5 SP1 Beta

It doesn't. For now ASP.NET MVC is an out-of-band Web downloadable thing. It's bin deployable (meaning you don't HAVE to put them in the GAC) and you don't even need to tell your hosting/ISP. They are what they are - three DLLs in a folder. Bam. Phil has more details on his blog from last week with regard to MVC Preview 2, but the idea still holds. He says:

"MVC Preview 3 will not be affected by having SP1 installed. Preview 3 will include newer privately versioned bin deployable builds of the Routing and Abstractions DLLs. That way these assemblies will not be affected by the versions in the GAC installed by SP1, because they will have different version numbers."

Cool.

ASP.NET MVC Preview 3 Beginner Videos

I did two quick updated beginner introductory videos specific to Preview 3, but the original Preview 2 videos are still up and still mostly valid. As I've said before, there will be more videos as we get closer to release. These are safe to show your CTO and they are short - on purpose - so he or she doesn't fall asleep.

Introduction to ASP.NET MVC Preview 3
Scott Hanselman walks you through an ASP.NET MVC Hello World example in this video updated for Preview 3. He also explains the lifecycle of an ASP.NET MVC application.

Basic Application Building with ASP.NET MVC Preview 3
Scott Hanselman uses a sample database to create a basic Product Catalog management application with create, read, update and delete functionality. You can download the source for this application at Phil Haack's blog.

 

One cool new development is that my team added Rob's Storefront Videos to the http://www.asp.net site and you can check out the first ten videos here. The benefits are several, first, Rob won't have to pay for bandwidth, but we've also transcoded his videos into a bunch of formats for those of you that are passionate about your specific format. You know who you are. Me, I use just WMV or MP4 (DivX/xVid) and think that that's one too many, but you've can you choose from WMV, Zune, iPod, PSP, MPEG-4, and 3GP if it make you happy.

Updated ASP.NET MVC Preview 3 Sample

Phil has updated the Northwind MVC Sample for ASP.NET MVC Preview 3 and you can get it at Phil's Blog.

Preview 3 is also makes it way easier to test Controllers because they return ActionResults now, which gets the Controller out of the call stack and lets the Test focus on what the controller really intends to do, rather than worrying about mocking side effects of what the Controller might have done. As usual ScottGu has left me with nothing good to write about because he's already done a fine post with lots of detail on the changes. So selfish! ;)

BTW, if you're digging the Gu's black code theme, blame me for converting him and go check out the Visual Studio Programmer Themes Gallery, I believe he's still using Rob Conery's Textmate Take 2 theme.

Technorati Tags: ,

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Wii Fit Review

May 27, '08 Comments [17] Posted in Gaming | Reviews
Sponsored By

I like my Nintendo Wii, although, so far it's been basically a $200 Tennis Simulator. The most fun is watching people play it for the first time. We had some friends over last week and they mentioned the Wii, and my wife said "you HAVE to try Tennis!" And they loved it, and it was good. However, as much as I try to get into other Wii games like Metroid and Zelda, I just don't.

But, I am a glutton for punishment, and while I spend more time using my Xbox, the Wife and I thought we'd give the Wii one more try with the Wii Fii Balance Board.

Before you read this review, by all means, watch this horrifically brutal and true Wii Fit Parody.

Ok, now that that's over with, YES, I know the Wii Fit is silly and YES I know it's a waste of money and YES I know I could "just go outside." We do go outside, and we walk and hike and run as a family, so that said...

The Wii Fit is a hoot. It's a lot of fun. Ultimately it's just a scale that knows where your center of balance is because each of the 4 corners is an independent scale. It constantly "re-zeros" itself between activities as you step on and off it, so in the week I've had it I haven't had any issues with its accuracy.

It's questionable as a fitness tool as it made my little Mii Avatar quite fat because apparently 187lbs (a number I'm not proud of) on a 5'11 frame is smack in the middle of overweight. (That's 180cm and 85kilos, by the way) After I entered this info in, my little on-screen dude swelled up and will stay there until I hit 165lbs it seems.

Regardless, I can see how the Wii Fit could act as a motivator for folks, like me, who prefer to workout at home rather than at a club. I actually prefer working out while watching TV, such that I'm forcing my self to work to watch my shows. The Wii Fit is fairly cheap, about US$89, and includes the game disc.

There's "over 40 mini games" according to the box, but in reality there's 4 categories with 12 or so games per. There's strength (all isometric), yoga, balance games, and aerobics. There strength and aerobics sections are fine, but not extraordinary. The games are a blast, especially downhill skiing, but the Yoga section is really nice. I think I'll use the Yoga for 30 minutes or so each evening and see how that goes. I have a number of Yoga DVDs, but I find the balance feedback that the Wii gives you to be invaluable for finding correct posture.

A few years back, the CEO of my then company, Corillian, left and started a company that created a game called Yourself Fitness for the Xbox. I thoroughly enjoyed this program, specifically it's crazy intense aerobics sections. It had a HUGE library of exercises that dwarfs the Wii Fit's. It's like 500 to 20. I'd love to see this application ported to the Wii and supporting the Wii Fit - THAT would be something special.

Still, I'm happy with the purchase, it's not that much more than a good quality electronic scale and if your expectations are set appropriately and you remember it's neither a game nor a really good workout system, I think you'll have fun also. Don't take my word for it, go try one at one of the many locations that Nintendo is setting up as the Wii Fit goes on tour.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 114 - Website Scaling War Stories with Richard Campbell

May 27, '08 Comments [12] Posted in Podcast
Sponsored By

richard_headshot_web My one-hundred-and-fourteenth podcast is up. In this slightly unusual episode, I sit down with my good friend Richard Campbell and we share stories about scaling large websites over the years. I thought this was a really good show, if a little long and I'm thinking to have Richard on as a regular thing, if he's interested.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

If you have trouble downloading, or your download is slow, do try the torrent with µtorrent or another BitTorrent Downloader.

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Check out their UI Suite of controls for ASP.NET. It's very hardcore stuff. One of the things I appreciate about Telerik is their commitment to completeness. For example, they have a page about their Right-to-Left support while some vendors have zero support, or don't bother testing. They also are committed to XHTML compliance and publish their roadmap. It's nice when your controls vendor is very transparent.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Vista 64-bit Blue Screens with INTERNAL_POWER_ERROR Immediately After Installing VMWare Player

May 21, '08 Comments [29] Posted in Bugs | Musings
Sponsored By

I hope this helps someone because it totally freaked me out this evening. I rebooted this evening, the first reboot since March, in fact, and blue-screened (BSOD) upon startup. At this point I was in a blue screen "loop" with the ominous message "INTERNAL_POWER_ERROR" on the blue screen. I started cussing Vista out and panicking, but this machine has been exceedingly stable since I built it last year and I reboot only every few months. I built it to be stable and I trust the machine.

Working backwards, the last and only interesting thing I installed was VMWare Player for Windows. I had some trepidation at the time of the install because I am not a fan of the way that VMWare adds virtual network devices that are listed in Network Connections, but it came highly recommended from respected power users I know and I needed it to install a prepared Suse VM from the Mono folks.

However, when it's installed my 64-bit machine blue screens, and it's very difficult to get uninstalled, actually. Needless to say this scared the crap out of me.

I looked all over and checked out the VMWare Forums and no one at VMWare has acknowleded the problem in a Googl-eable way. I can tell you this, however. I am using a Quad-proc machine with an MSI motherboard with the latest BIOs and a buttload of USB devices. The only way I could get the system to boot up was to remove ALL the USB devices. ALL of them, to be clear, save one wired USB Keyboard that I used to log in and remove VMWare.

My guts says that this is a bug in the VMWare USB bridging code (the stuff in VMWare that lets you use USB devices inside a VM) or it's somewhere in the USB drivers in Windows. I have the Crash Dumps if you work for VMWare and you're interested. I'll WinDBG them later this week.

I hope this post helps someone having this same issue.

UPDATE: Installed Windows Debugging Tools (WinDbg.exe) and analyzed the crash dump and it's the VMWare Keyboard Driver, of all things. Perhaps VMWare doesn't like my Wireless USB Keyboard? Mental note, relearn WinDbg'ing.

BugCheck A0, {101, 7, fffffa6001dc8b10, 0} 

*** ERROR: Module load completed but symbols could not be loaded for VMkbd.sys
Page 9bda8 not present in the dump file. Type ".hh dbgerr004" for details
Probably caused by : VMkbd.sys ( VMkbd+15da )

Followup: MachineOwner
---------

1: kd> !analyze -v
*******************************************************************************
*                        Bugcheck Analysis                                    *
*******************************************************************************

INTERNAL_POWER_ERROR (a0)
The power policy manager experienced a fatal error.
Arguments:
Arg1: 0000000000000101, Unhandled exception occured while processing a system power event.
Arg2: 0000000000000007
Arg3: fffffa6001dc8b10, ExceptionPointer.  To debug this, in the debugger type:
    'dt nt!_EXCEPTION_POINTERS <argument>'.  Then type:
    '.cxr <value of context record from the previous command>'.
    All subsequent debugger commands will show you the actual
    source of the error.  Start with a stack trace by typing 'kb'.
Arg4: 0000000000000000

Debugging Details:
------------------
Page 9bda8 not present in the dump file. Type ".hh dbgerr004" for details
BUGCHECK_STR:  0xA0
DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT
PROCESS_NAME:  System
CURRENT_IRQL:  0
EXCEPTION_RECORD:  fffffa6001dc99a8 -- (.exr 0xfffffa6001dc99a8)
ExceptionAddress: fffff80002477af1 (nt!IofCallDriver+0x0000000000000051)
   ExceptionCode: c0000005 (Access violation)
   ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000000
   Parameter[1]: 00000000000000e0
Attempt to read from address 00000000000000e0
---------

Weird.

Technorati Tags: ,,

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

The Weekly Source Code 27 - Suck Less Libraries

May 20, '08 Comments [10] Posted in Programming | Source Code
Sponsored By
I've been getting more and more interested in how folks extend their applications using plugins and things. In my new ongoing quest to read source code to be a better developer, Dear Reader, I present to you twenty-sixth (half a year!) in a infinite number of posts of "The Weekly Source Code."

Now that I've been working with the .NET Base Class Library (BCL) for just about six years, I've got a pretty good sense of the classes I like, the ones that work well, and the ones that don't "feel" right. I'm learning LINQ and the various extension methods that can make code feel more elegant. I've got ideas on how I might fix/patch/improve the framework, but really, who has the time? Well apparently these guys. This week's Weekly Source Code is dedicated to the people who create libraries with the goal of making other libraries suck less.

Umbrella

The folks at http://www.nventive.net/ have created a project called Umbrella that is a series of helpers over the .NET BCL that aims to "reduce friction and increase predictability of the API." They plan to launch additional accelerators over Unity, the Entity Framework, WCF and the Enterprise Library.

It is exceedingly broad and includes literally hundreds of new methods and helpers. However, I don't think you're expected to "learn" Umbrella as they hope you'll stumble into it...in a good way. It's like the concept of The Pit of Success. There's little easier than just falling, and the idea is that if you've designed an API correctly folks will just fall into success. 

Do check out the project, it's really fun reading. Here's some cool examples:

Here's a few extensions to ICollection.

namespace nVentive.Umbrella.Extensions
{
public static class CollectionExtensions
{
public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> items)
{
items.ForEach(collection.Add);
}

public static void Remove<T>(this ICollection<T> collection, Func<T, bool> predicate)
{
collection.Where(predicate).ToArray().ForEach(item => collection.Remove(item));
}

public static ICollection<U> Adapt<T, U>(this ICollection<T> collection)
{
return Adapt<T, U>(collection, Funcs<U, T>.Convert, Funcs<T, U>.Convert);
}

public static ICollection<U> Adapt<T, U>(this ICollection<T> collection, Func<U, T> from, Func<T, U> to)
{
return new CollectionAdapter<T, U>(collection, from, to);
}

public static void ReplaceWith<T>(this ICollection<T> collection, IEnumerable<T> items)
{
collection.Clear();
AddRange<T>(collection, items);
}

public static IDisposable Subscribe<T>(this ICollection<T> collection, T item)
{
collection.Add(item);

return Actions.Create(() => collection.Remove(item)).ToDisposable();
}

public static void AddDistinct<T>(this ICollection<T> collection, T item)
{
AddDistinct<T>(collection, item, Predicates<T>.Equal);
}

public static void AddDistinct<T>(this ICollection<T> collection, T item, IEqualityComparer<T> comparer)
{
AddDistinct<T>(collection, item, comparer.Equals);
}

public static void AddDistinct<T>(this ICollection<T> collection, T item, Func<T, T, bool> predicate)
{
if (collection.None(collectionItem => predicate(collectionItem, item)))
{
collection.Add(item);
}
}
}
}

Ones like AddRange() are simple enough to make you wonder why there weren't there before, but ones like Remove() that includes a predicate indicating which items to remove are clever and clean, as in this example that removes numbers that are evenly divisible by two.

[Fact]
public void Remove()
{
collection.AddRange(new int[] { 1, 2, 3, 4 });

collection.Remove(item => item % 2 == 0);

Assert.Equal(2, collection.Count);
Assert.Equal(1, collection.ElementAt(0));
Assert.Equal(3, collection.ElementAt(1));
}

Another fun example is their ReflectionExtensions that make Reflection a little cleaner. Here's a test:

[Fact]
public void Instance()
{
Foo foo = new Foo();

IReflectionExtensionPoint fooReflection = foo.Reflection();

Assert.Equal(foo.I, fooReflection.Get("i"));

fooReflection.Set("i", 2);

Assert.Equal(2, foo.I);

Assert.Equal(2, fooReflection.Get("I"));

fooReflection.Set("I", 3);

Assert.Equal(3, foo.I);

Assert.Equal(3, fooReflection.Get("GetI"));

fooReflection.Set("SetI", 4);

Assert.Equal(4, foo.I);
}

Again, this just scratches the surface of Umbrella. It's huge.

Ukadc.Diagnostics

Even the team knows it as they say "Great logging, terrible name."  The Ukadc.Diagnostics library, also hosted on Codeplex, is a library of extensions to System.Diagnostics. Why? From Josh Twist:

Colleagues from Microsoft's UK Application Development Consulting (UKADC) team. The project was born out of a conversation with Morgan Skinner when I mentioned that I tended to use log4net, nlog or Enterprise Library logging over the stuff that ships out of the box (OOB) with .NET 2+.

I am the same way as I was a log4net guy for years. Check out their Reference Example or the Complete Source. The reference shows the smtpTraceListener and the sqlTraceListener. It includes a nice example of how to use the Trace.CorrelationManager to do context tracing through an entire HTTP request lifecycle.

The library includes a better base class for TraceListener, CustomTracelistener, that makes creating your own trace listeners easy with just two methods to override. I encourage you to check it out.

However, the gem I found while reading the source wasn't actually directly related to the library's purpose. Rather, it's the implementation of a Fast Property Getter. What's that you say? Well, sometimes when you're using Reflection to get properties from an object, you'll realize that asking for, then using the PropertyInfo object directly can be slow. Most folks will at least cache the PropertyInfo, which will save you from the initial hit but you'll still pay a little when using it to access the object's value.

This DynamicPropertyReader takes a CLR type as a string and a property name as a string. Rather than using Reflection each time, which would be slower, it uses this FastPropertyGetter. We did this at Corillian (my last job) in a number of places where we wanted the flexibility of Reflection but near-native speeds.

public DynamicPropertyReader(string sourceType, string propertyName)
{
if (string.IsNullOrEmpty(sourceType))
throw new ArgumentNullException("sourceType");
if (string.IsNullOrEmpty(propertyName))
throw new ArgumentNullException("propertyName");

// Attmpt to get the type, and throw a TypeLoadException if not found
Type type = Type.GetType(sourceType, true);

_fastPropertyGetter = new FastPropertyGetter(propertyName, type);

if (_fastPropertyGetter.PropertyType == typeof (string))
{
_comparator = StringComparator.Instance;
}
else if (typeof (IConvertible).IsAssignableFrom(_fastPropertyGetter.PropertyType) &&
typeof (IComparable).IsAssignableFrom(_fastPropertyGetter.PropertyType))
{
_comparator = NumericComparator.Instance;
}
else
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
Resources.DoesNotImplementRightInterfaces,
propertyName, sourceType));
}
}

What does it do? It's long, but clever. I think it could actually be tightened up a bit, but basically it generates a method at runtime that is tailored to retrieve a property from an object. That getter is then cached and called to retrieve the property. One of these DynamicMethods is generated per property. Remember that DynamicMethod is one of the magical things that enables IronPython and the DLR. I heard that this kind of technique could be WAY cleaner using the DLR in the near future. Perhaps Harry can expand on that. There's a good article on CodeProject about this kind of specialized code generation for speeding up reflection.

public class FastPropertyGetter
{
private delegate PropertyResult GetData(object data);

private GetData GDDelegate;

public Type PropertyType { get; private set; }

public FastPropertyGetter(string propertyName, Type type)
{
if (string.IsNullOrEmpty(propertyName))
throw new ArgumentNullException("propertyName");
if (null == type)
throw new ArgumentNullException("type");

PropertyInfo propertyInfo = type.GetProperty(propertyName);

if (propertyInfo == null || !propertyInfo.CanRead)
throw new ArgumentException(
string.Format(CultureInfo.CurrentCulture, Resources.NoReadableProperty, propertyName, type));

MethodInfo methodInfo = propertyInfo.GetGetMethod();
PropertyType = methodInfo.ReturnType;

DynamicMethod dm = new DynamicMethod("FastGetProperty",
typeof (PropertyResult),
new Type[] {typeof (object)}, typeof (FastPropertyGetter));

ILGenerator il = dm.GetILGenerator();

il.DeclareLocal(typeof (PropertyResult));
LocalBuilder lb = il.DeclareLocal(type);

il.Emit(OpCodes.Newobj, typeof (PropertyResult).GetConstructor(new Type[0] {}));
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ldarg_0);

il.Emit(OpCodes.Isinst, type);

// branch if IS an instance of type
Label isInstance = il.DefineLabel();
il.Emit(OpCodes.Brtrue_S, isInstance);

{
// load the GetterResult
il.Emit(OpCodes.Ldloc_0);

// Create a 'false' bool
il.Emit(OpCodes.Ldc_I4_0);

// Set result code to GetterResultCode.ObjectNotExpectedType
il.Emit(OpCodes.Callvirt, typeof (PropertyResult).GetProperty("ObjectMatched").GetSetMethod());

// reload the GetterResult and return it
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
}

// isInstance:
// object IS expected instance
il.MarkLabel(isInstance);

{
// load the GetterResult
il.Emit(OpCodes.Ldloc_0);

// load the passed object
il.Emit(OpCodes.Ldarg_0);

if (type.IsValueType)
{
il.Emit(OpCodes.Unbox_Any, type);
il.Emit(OpCodes.Stloc_1);
il.Emit(OpCodes.Ldloca_S, lb.LocalIndex);
}

if (methodInfo.IsFinal)
{
// Call the property get method
il.Emit(OpCodes.Call, methodInfo);
}
else
{
// Call the property get method
il.Emit(OpCodes.Callvirt, methodInfo);
}

// box if necessary
if (methodInfo.ReturnType.IsValueType)
{
il.Emit(OpCodes.Box, methodInfo.ReturnType);
}

// Set data to result of query
il.Emit(OpCodes.Callvirt, typeof (PropertyResult).GetProperty("Data").GetSetMethod());

// reload the GetterResult and return it
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
}
GDDelegate = (GetData) dm.CreateDelegate(typeof (GetData), null);
}

public PropertyResult GetValue(object data)
{
return GDDelegate(data);
}
}

IIS7 Hostable Web Core

CarlosAg has written a nice wrapper around IIS7's core hwebcore.dll library that lets you host your own IIS7 instance INSIDE your process. This isn't HttpListener, nor is it out-of-process. This is IIS7, running in your process. This is a really powerful thing that is as simple as:

internal class Program { 
private static void Main(string[] args) {
int port = 54321;
int siteId = 1;

WebServer server = new WebServer(@"d:\Site", port, siteId);
server.Start();
Console.WriteLine("Server Started!... Press Enter to Shutdown");

Console.ReadLine();

Console.WriteLine("Shutting down");
server.Stop();
}
}

This is a nice alternative to HttpListener and it's more powerful than Visual Web Developer/Cassini. Carlos also muses about this possibility:

"Another scenario might include something like a "Demo/Trial CD" where you can package your application in a CD/DVD that users then can insert in their machine and suddenly get a running/live demo of your Web Application without requiring them to install anything or define new applications in their real Web Server."

It's also very very simple:

namespace HWCServer {
internal class WebServer : IDisposable {

private string _appHostConfigPath;
private string _rootWebConfigPath;

public WebServer(string physicalPath, int port, int siteId) {
string appPoolName = "AppPool" + port.ToString();
_appHostConfigPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName() + ".config");
_rootWebConfigPath = Environment.ExpandEnvironmentVariables(@"%windir%\Microsoft.Net\Framework\v2.0.50727\config\web.config");

string appHostContent = Resources.AppHostAspNet;
//string appHostContent = Resources.AppHostStaticFiles;

File.WriteAllText(_appHostConfigPath,
String.Format(appHostContent,
port,
physicalPath,
@"%windir%\Microsoft.NET\Framework\v2.0.50727",
siteId,
appPoolName));
}

~WebServer() {
Dispose(false);
}

public void Dispose() {
Dispose(true);
}

private void Dispose(bool disposing) {
if (disposing) {
GC.SuppressFinalize(this);
}

Stop();
}

public void Start() {
if (!HostableWebCore.IsActivated) {
HostableWebCore.Activate(_appHostConfigPath, _rootWebConfigPath, Guid.NewGuid().ToString());
}
}

public void Stop() {
if (HostableWebCore.IsActivated) {
HostableWebCore.Shutdown(false);
}
}

#region Hostable WebCore
internal static class HostableWebCore {

private static bool _isActivated;


private delegate int FnWebCoreActivate([In, MarshalAs(UnmanagedType.LPWStr)]string appHostConfig, [In, MarshalAs(UnmanagedType.LPWStr)]string rootWebConfig, [In, MarshalAs(UnmanagedType.LPWStr)]string instanceName);
private delegate int FnWebCoreShutdown(bool immediate);

private static FnWebCoreActivate WebCoreActivate;
private static FnWebCoreShutdown WebCoreShutdown;

static HostableWebCore() {
// Load the library and get the function pointers for the WebCore entry points
const string HWCPath = @"%windir%\system32\inetsrv\hwebcore.dll";
IntPtr hwc = NativeMethods.LoadLibrary(Environment.ExpandEnvironmentVariables(HWCPath));

IntPtr procaddr = NativeMethods.GetProcAddress(hwc, "WebCoreActivate");
WebCoreActivate = (FnWebCoreActivate)Marshal.GetDelegateForFunctionPointer(procaddr, typeof(FnWebCoreActivate));

procaddr = NativeMethods.GetProcAddress(hwc, "WebCoreShutdown");
WebCoreShutdown = (FnWebCoreShutdown)Marshal.GetDelegateForFunctionPointer(procaddr, typeof(FnWebCoreShutdown));
}

public static bool IsActivated {
get {
return _isActivated;
}
}

public static void Activate(string appHostConfig, string rootWebConfig, string instanceName) {
int result = WebCoreActivate(appHostConfig, rootWebConfig, instanceName);
if (result != 0) {
Marshal.ThrowExceptionForHR(result);
}

_isActivated = true;
}

public static void Shutdown(bool immediate) {
if (_isActivated) {
WebCoreShutdown(immediate);
_isActivated = false;
}
}

private static class NativeMethods {
[DllImport("kernel32.dll")]
internal static extern IntPtr LoadLibrary(String dllname);

[DllImport("kernel32.dll")]
internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname);
}
}
}
}

What a clean wrapper class! Have fun, and keep reading source to be a better coder!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.