Friday, April 18, 2008

I Am Legend….Classic ASP and .NET COM Objects

Okay. I feel like Will Smith here. I thought I must be the last man on the planet still having to deal with classic ASP, .NET, and COM objects. After searching Google for a couple of answers, I realized I was not alone.

Does that make all of you those freaky vampires?

Well, vampire or no, I'm going to be neighborly and reveal my hard earned knowledge of creating a COM object in .NET that can be called from classic ASP. This is really fun stuff, so hold on tight.
[Ed. Note fun = miserable and mind-numbingly frustrating]

So, my task was to create single sign-on between ASP.NET applications and classic ASP sites. These all reside in a single domain. I just had to create a COM object in .NET that would handle the ticket validation between the two technologies. This took me about two hours to hammer out.

Here we are days later, and I'm just getting to test the COM object.

Why the delay? Days and days of beating my head against the monitor screaming "why me!?! For God's sake, why me!?!"

First, here are the basic steps for creating a COM-callable object in .NET:

1. Create a class library.
2. Add the namespace System.Runtime.InteropServices to your class.
3. Add an interface that defines the properties and methods of your class (aka type).
4. Have your class implement the interface.
5. Decorate your class (type) with a ClassInterface attribute that has a value equal to ClassInterfaceType.None (this tells the Type Library Exporter (tlbexp.exe) to NOT create an interface…because we've already defined one, right?)
6. Decorate both the type and the interface with the attribute ComVisible and set that equal to true. You'll also want to decorate any public property, method, enum, etc. with the same. You can also set this to false if you want a property or method to NOT be visible to COM.
7. Be sure to include a parameter-less default constructor. Sadly, I forgot this and caused myself a little grief for a while

Below is the code in action. But don't stop reading now. We aren't to the fun part (see Ed. Note above).


using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;

namespace ComIsAuthume
{
[ComVisible(true)]
interface iTokenHandler
{
bool IsAuthenticated();
}

[ClassInterface(ClassInterfaceType.None),ComVisible(true)]
public class TokenHandler : iTokenHandler
{

public TokenHandler()
{
//this needs to be here and empty for COM
}

[ComVisible(true)]
public bool IsAuthenticated()
{
return true;
}
}
}

So…after you have done all this, you can compile and then run regasm to register your object (you can't use regsvr32 for managed code), like this

Regasm dllname.dll /codebase

After this, your object should be usable by classic ASP, right? Wrong! Before December 07, we could have stopped here. Unfortunately for me (and probably for you if you are reading this), there is more to do…and I have the secret.

In December 2007, MS was kind enough to release a security patch for IE - MS07 - 45 IE update. This handy update caused our managed COM object to not be usable via IIS 6.0. Why? It keeps the anonymous user from reading the registry settings required to see the object. Nice, eh?

So, until there is yet another update, here's what you need to do. Some people claim that you can just sign your object and shove it in the GAC. This didn't work for me. If that doesn't work for you, you'll need to find the registry settings via regedit, right click on them, select permissions from the context menu, and add the your anonymous account (IUSR blah blah)to have read access to the key. There are a few places to look in the registry, so don't stop with the first one you find. Just search for your dll name (without the extension) and grant read access to that user for each key found.

I hope you found this post helpful…and early so you don't waste a lot of time!

Wednesday, April 9, 2008

What the Heck is Locking my .DLL?

This is a problem that comes up often enough to be a real PITA, but infrequently enough that you'll probably forget how to solve it. Hopefully a quick Google search will find this post and save you a little time.

Before you read on, I think it's only fair to warn you. I can only ensure that this works on Windows XP. I understand it does not on Windows 2000. I haven't tried it on any other system.

So, here' the scenario. You have a .DLL on your system that you want to delete. For stability's sake, we'll assume it's one you created. You find it via Windows Explorer, select it and hit the delete key....you wait...and then you get a message stating you can't delete the file because it's in use.

In use. What do you mean in use? It's my own .DLL and I'm not using it!

Your first step will undoubtedly be the trusty Task Manager. Your plan is to find the .DLL and kill it from there.

No joy. It's not listed. Now what?

In walks Task Manager's big brother. It's that bad boy, tasklist.exe, the command line version of Task Manager. With one simple command, you'll know exactly what is locking your .DLL. Just open a command window and type the following:

tasklist /m YourDllName.dll

This will list the "images" that have locks on your module. In addition it lists their pid.

You're most likely going to see that this is a dllhost.exe holding onto your .DLL. Armed with this information, you can now use your trusty Task Manager, find the dllhost.exe with the pid of the offender, and kill, kill, kill!

Wednesday, March 12, 2008

My Resume...

Drop me a line if you have something in which I might be interested. I really enjoy consulting and am willing to telecommute with up to 25% travel. My preferred job would be one of the following: either a dev lead in charge of a small team working on web-based applications; or an independent consultant working with a great team.

Web-based Application Developer (ASP.NET, C#, AJAX, SQL Server)
More than 12 years architecting and developing web-based applications for internal business use and consumer consumption. For the past six years I have been a lead developer for Starbucks, responsible for externally facing web-based systems (including www.starbucks.com), and internally facing web-based applications including partner(employee) portal, store portal, and a variety of stand-alone internal applications. Previous to Starbucks, I was an independent consultant for five years, and ran White Hammond Consulting for one year. Prior to that, I served as a consultant for a couple of firms local to Seattle.

Recent Experience

Team System (In Progress)
Organized online ALM assessment, coordinated consulting firm for live ALM assessment. Incorporated results of assessment to modify work items and work item work flow.
Analyzed team usage and needs to determine TFS architecture.
Installed and configured Team Foundation Server (TFS).
Monitored, assisted peers in Team Suite usage.
Identified pilot projects and assisted developers in Team Suite usage.
Trained peers in Team Suite/VS2008

Virtual Earth (October 2007)
Designed and developed store locator using Virtual Earth v6 and MapPoint. WSE 3.0, VE v6, MapPoint , ASP.NET, AJAX www.starbucks.com/retail/find. Short deadline, single developer, shifting requirements.

SharePoint (January 2007)
Developer for SharePoint v3 (MOSS) implementation for store portal. The original store portal was built on Plumtree Portal. The new store portal provided

Team Leadership
Mentor to peers. First in team to certify (MCP). Assisted others in gaining certification. Identified process improvements and acted to help team over-come these issues - error logging (rather than event viewer, db, log files, emails). Code Reviews. Design Reviews. Unit Tests. Team Organization (squads, rather than flat structure). Leadership courses include: Squadron Leadership School (CAP), Squadron Officer School (USAF via CAP), Be, Know, Do (US Army leadership book).

Interests
Civil Air Patrol - Captain in the Civil Air Patrol (USAF Aux.). Aerospace Education and Logistics officer for Overlake Squadron
Writing - blogs, travel, articles
Softball - I play four seasons a year on a Redmond Parks league
Flying - Private pilot, ground school instructor, glider rating (coming soon)

Wednesday, February 27, 2008

Visual Studio 2008 Team System Path Length

Here's a quick tip about file path lengths in Visual Studio 2008, Team System. I have been tweaking the process templates for our rollout of this system and came across a file path length limitation.

My default project location for VSTS was the typical location under My Documents/Visual Studio 2008/Projects. Well, if you keep that location, add one or two folders for organization, then you'll bump into this issue.

This is particularly annoying when attempting to upload a new process template. All the images, etc., are pathed in the XML...and that path then exceeds the length that VSTS can handle. When that happens, the upload fails and you have to scour the logs to figure out why.

So, if you are just starting out with Visual Studio 2008, be sure to create a default location for your projects under a very short root path. I prefer to use c:\action. That keeps my projects at the top of the folder structure. They are easy to find and the path length is very short.

On a related note, let's say you've created a project and added it to source control, but now you want to change the local path (similar to setting the working folder in VSS). It's easy to do, but tucked away. You need to select File --> Source Control --> Workspaces. Edit the workspace you want to move. Easy enough, but not readily apparent.

Wednesday, February 13, 2008

If it's not static and it's not dynamic, it's...

We're in the process of creating/implementing a CMS system. There is a ton of planning that needs to go into this bad boy. In the pre-design, high-level requirements chit-chat phase, the technical team was discussing the types of content that would need to be supported. We had the static content - that which rarely changes. We had the dynamic content - that which changes frequently. We then discovered that we also had mixed content - content that was static yet had a dynamic component to it.

We kept calling this mixed content type "static-dynamic" or "dynamic-static". Neither of those seemed to fit, so I coined a new word. Feel free to use it with impunity in all of your meetings. The goal here is to get management to start using it like a new buzzword.

Here it is……"stynamic". That's right, stynamic. Don't you worry that the spellchecker chokes on the word. It's not a typo. It's bleeding edge language, baby.

Shout it to the mountains! STYNAMIC…..NAMic….namic…

Use it with confidence in meetings. "You know, Becky, the stynamic nature of our organization requires flexibility with the understanding that things will never really get better for you."

Sling it casually with friends. "Dude, we always just get together and drink beer. Let's be more stynamic. Let's drink beer AND whiskey!"

Sip wine while impressing those arrogant, highly opinionated, self-righteous acquaintances with whom you are forced to occasionally dine. "You know, Archibald, I've noticed the awkward growth of this community has a very stynamic feel." You sip wine while letting the word settle in Archibald's mind. "We continue to build out, yet what is it we build? Strip malls. We get new construction. New growth. Yet, what we're building - the very nature of our growth - is, well, static." You see the wheels turn in Archibald's mind and smile knowing that he'll use stynamic at least a dozen times before the night is through.

So, there it is. My gift to you and the world. Stynamic. Use it wisely. Use it often.

Friday, January 25, 2008

the year of the LINQ

Back in the 90s, business seemed to fall in love with Microsoft Access. Homegrown applications were popping up everywhere and in the short-term they offered relief to business. IT could be slow in response, and an executive's admin could open MS Access and "develop an application" to support a business need by simply creating a couple of tables and dragging and dropping controls onto forms.

It was a quick and easy way to get the job done. These applications grew, and were shared, and eventually became relied upon to the point where they were business-critical.

These applications grew large enough that their poorly designed and developed systems failed. The lesson learned by most was that the MS Access application was good for a short-term fix or a small, personal project that would not expand in scale or scope.

This is not developer snobbery. It's simply a fact. Applications need to be designed and developed by experienced developers if you expect them to support large, business-critical needs. This is a lesson many learned in the past, and now we have the opportunity for history to repeat with the introduction of LINQ.

What is this blasphemy of which I speak? Surely LINQ is the next great development paradigm, no?

No.

Mind you, these are my first impressions of the technology, but you know what they say about first impressions.

Now with the addition of LINQ a "developer" can open Visual Studio, create tables in a database, use LINQ to create a data access layer without writing any code, then create forms and data consuming pages by simply dragging and dropping objects on a page. In minutes you can go from an idea for an application to pushing something out onto the servers for everybody to use without writing a bit of code nor contemplating design decisions.

Sounds like MS Access all over again.

So, all you consultants out there, don't ignore LINQ. Spend time learning it. LINQ will be great for prototyping. Better yet, it will also be a great revenue generator for you in 2009 or 2010. Ronstrodomous predicts you will undoubtedly be seeing a large number of projects rolling through begging you to fix a now business-critical LINQ-based application that Joe from accounting created in 2008.

Wednesday, January 16, 2008

vsts process template modifications

Here's a little tidbit that might come in handy if you find yourself modifying a process template for Visual Studio Team System. Say you're going to add a new field to a work item type. Seems simple enough. You step through it until you're faced with a dialog box for the newfield. Each required field on the dialog box seems self explanatory, except for RefName.

What the heck is a RefName?

There is no help on the dialog box. The next logical thing is to look for an example to help you out. You click cancel on the input box and look at the list of RefNames for the pre-existing fields. Those certainly look like namespaces to me. So, what is the name space to use for this new field? Is it based on field type? Is it a control namespace?

Maybe it was a lack of coffee that morning, but for some reason it stumped me for a few minutes. I'm sure you've all figured it out already, but just in case you haven't, here's the answer. The key is that it is a namespace, and just like any other namespace you create for your code, you simply create your own. YourCompanyName.FieldName is a good start. Pick a namespace that makes sense not only for this field, but one that can be used for future additions. Once you've decided on the namespace, simply type it into the text box and off you go.

Friday, January 11, 2008

disambiguation, virtual earth, and other words to impress your friends

Ah, disambiguation. It's such a great word. I'll use it frequently throughout this posting because it makes me sound smart. I suggest you use it with your friends and co-workers for the same reason.

Disambiguation is the process of narrowing your search criteria in Virtual Earth from something fairly generic or confusing to something exact. For example, if you were to search for McChord, VE wouldn't know for sure if you meant McChord AFB or something else, so VE would need you to clarify before showing you a map.

That's where disambiguation comes into play. Virtual Earth will prompt you with a list of possibilities - forcing you to disambiguate by selecting a specific location.

Disambiguation, disambiguation, disambiguation...

The easiest way to handle disambiguation is to let Virtual Earth handle it for you. The way you do that is to set the ninth argument in the Find method to true. This argument is the useDefaultDisambiguation argument and basically it tells Virtual Earth to prompt the user with a list of possibilities if their criteria isn't specific. The code for this is simple and looks like this:

<script type="text/javascript">
var map = null;
var results = null;

//called from body.onLoad
function GetMap()
{
  map = new VEMap('MapDiv');
  map.LoadMap();
}

function FindLocation()
{
var where = "McChord";
try
{
 map.Find(null,
  where,
  null,
  null,
  0,
  10,
  true,
  true,
  true, //useDefaultDisambiguation
  true,
  ProcessResults);
}
catch(e)
{
 alert(e.message);
}
}

//callback function for map.Find
function ProcessResults()
{
}
</script>


So, in the code block above, the second to last boolean value is the argument called useDefaultDisambiguation. Again, setting this to true uses the default Virtual Earth disambiguation box. The code above should pop a disambiguation box with a list of options.

"But wait," you say in your leather pants and best Zoolander accent. "My users are super smart and sexy. They would be insulted to be questioned by a simple tool such as this computer. Remove that small boxy thing from my sight."

That, my friend, is what we like to call customization. Another big word. That's right. Disambiguation customization. How is my brain so big?

If your users are too smart and sexy for disambiguation, you can set up Virtual Earth to just use the first (what it considers the "best") option from a list of disambiguated locations. In other words, if you typed in McChord, Virtual Earth would guess that you might mean McChord AFB and take you straight there.

Giving you the option to show or hide the disambiguation box allows you to customize the experience to your users. If you have a savvy user base you can probably suppress the dialog box. If you feel that some of your users would be confused or mad if they are brought to the wrong Portland or Bangor, then you will probably want to show them the disambiguation dialog box.

This post is getting long, so I'm going to save custom disambiguation for the next post. Until then, happy coding!