Discovering the PublicKeyToken of Your Assembly

For many reasons, I often need the PublicKeyToken of a signed assembly, such as creating custom controls or working with a product like SharePoint. Typically this information ends up in a .config file, but in my case I’m exploring Custom Data Generators for Visual Studio 2010 and need this info for an XML file Visual Studio uses. In the past, I’ve always used Reflector to figure out the PublicKeyToken. But in reading the MSDN docs about Custom Data Generators, I stumbled upon a way to do it right in Visual Studio from the Command Window.

Open a Command Window (View menu –> Other Windows –> Command Window). At the prompt type something like this:

? System.Reflection.Assembly.LoadFrom(@"<path>").FullName

where the path is obviously the path to your own DLL (like C:\Users\dtruxall\Documents\Visual Studio 2010\Projects\DemoGenerator\DemoGenerator\bin\Debug\DemoGenerator.dll). If you get the path correct, the Command Window gives output like this:

"DemoGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=22402068dd2dab84"

That’s exactly what I need for my XML.

Posted: Friday, July 30, 2010 9:45:42 AM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
Visual Studio

Install SharePoint 2010 Without a Domain on a Single Server

I was trying to create a virtual machine for development with SharePoint 2010, but I wanted to have a full SQL Server available instead of using the standalone installation with SQL Express. Unfortunately, this situation is not supported unless you are using domain accounts. My VPC is not part of any domain, so the install won’t proceed (which is by design apparently). There is a well-documented workaround using the New-SPConfigurationDatabase PowerShell script, so I tried that.  That seemed to work, it ran for a while, but then I ended up with an error:

User does not exist or is not unique

I found a post on the MSDN Forums that had the right answer. When the script prompted me for credentials, I put in a local username and password, and this was accepted. Until later when the script crashed. It turns out that I needed machinename\username and password. Even though the authentication prompt accepted the credentials without the machinename, somewhere down the line the script needed the machinename and it wasn’t there. Another important item to note was that once the PowerShell script crashed, it would no longer work even if you got all the prompts correct. I needed to exit the script shell and start again.

Posted: Tuesday, July 27, 2010 12:53:11 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
SharePoint | Strange Problems

A 64-bit 32-bit Dilemma

I recently ran into an interesting situation that I was able to solve through code. The project was to create a document migration tool, something I’ve done many times, so it seemed pretty straightforward. I was moving documents and metadata from a 3rd party content management system to SharePoint 2007. I was developing on a 32-bit OS on a machine provided by my client. The source system had an API, albeit 32-bit COM. There was some example code in their SDK for VB6, so at least there was something. It was easy enough to create a .Net wrapper to that COM DLL and figure out the API. The SharePoint code was not too difficult either, something I’ve done before. In this case I had to use the API, not the web services because I wanted to keep the original file created/modified dates from the source system. You can’t set those using the web services. Therefore, the tool is forced to run on the SharePoint server (this is important factor for the upcoming dilemma). Luckily the source system was accessible remotely.

Works on My Machine

Of course, in my dev environment everything works great. So I copy my app to a SharePoint server to test in an environment more like production. It crashes immediately with a COM exception:

 Retrieving the COM class factory for component with CLSID {FDD9199A-1BB4-4433-B9E1-D550D3118676} failed due to the following error: 80040154.

What?? After a little research I determine the problem: the SharePoint server is 64-bit. My .Net code was compiled for any CPU, so it ran as 64-bit on the server, while it was 32-bit on my dev box. When compiled for 64-bit, it can’t access the 32-bit COM DLL (there might be a solution for this, I didn’t find it). I went back, and forced the code to compile for 32-bit. The app soared right past the error for the COM DLL, but came to a screeching halt when trying to access the SharePoint API. If SharePoint is installed on a 64-bit server, the code has to run compiled for 64-bit in order to access the API. Now you see the dilemma. I have to use a 32-bit only COM DLL and a 64-bit app for accessing SharePoint. I can’t skirt the issue using the SharePoint web services because I need functionality only available in the API.

My Solution

I decided on using two applications, one compiled for 32-bit which accesses the source system and fetches the data, and a second one compiled for 64-bit to access the SharePoint API. Five years ago I probably would have done the same thing, and write the data to an XML file from the first app, and then launch the second app and read the data from the file. There were hundreds of thousands of documents to migrate, all that disk access would be a performance killer. But now that I have WCF, I could do this much more elegantly.

32-64solution[1]

The 32-bit app contained the UI, and was able to use the 32-bit COM DLL to fetch documents and metadata. Once it had a logical set of data in memory, it used WCF with named pipes as the transport protocol to pass the data structure to the second app. The second app was 64-bit, and launched by the first app as a process using the System.Diagnostics namespace. It communicated just fine with the SharePoint API. The second app had no GUI, but I kept the console window for writing messages and to provide a way to manually exit the app in case things went awry. The first app kept a handle on the process that launched the second app, so that when a user closed the first app, it could close the second app for  the user.

WCF was a good fit for this dilemma. The only issue I encountered was managing the message size, because WCF expects you to configure a maximum size for that. Of course configuring WCF is not that easy, but you only have to do it once. I was pleased that I could make a mex endpoint in the 64-bit app, and then use Visual Studio to make a Service reference to it from the 32-bit app, and the configuration comes out for named pipes even though the mex endpoint was http. Another feature I didn’t know but managed to discover. In the end, the process is seamless to the user, and does what I need without much disk access to slow it down.

Posted: Tuesday, July 13, 2010 10:12:05 AM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 3.5 | SharePoint | WCF

Connecting to TFS 2010 with Visual Studio 2008

I got error TF31002 when trying to connect to TFS 2010 with Visual Studio 2008:

TF31002 The Team Foundation Server name, port number or protocol is incorrect The Team Foundation server is offline Password is expired or incorrect.

The basic problem is that in Team Explorer, before Visual Studio Service Pack 1, you can’t enter a valid URL in the Add Team Foundation Server dialog, only a server name or IP address. Unfortunately TFS 2010 changed the URL of the server to this format: http://<servername>:<port>/tfs/, adding a virtual directory that TFS 2008 does not have. Pre sp1 this syntax is not allowed in the dialog box. Just putting in the server name produces the above error, which, in the irritating way that error messages work, is completely correct since the services can’t be found because they now reside in a virtual directory.

To get Visual Studio 2008 to connect to Team Foundation Server 2010, there are definitely some steps you need to follow. I found a bunch of mostly correct information, but nothing exactly right (beta and RC were widely available) so I figured I’d post it here.

To begin with, you need to install the following, in this order to Visual Studio 2008:

  1. Team Explorer for TFS
  2. Visual Studio 2008 sp1
  3. Visual Studio Team System 2008 Service Pack 1 Forward Compatibility Update for Team Foundation Server 2010

If you already installed Service Pack 1 and need install Team Explorer, you will need to re-apply the service pack.

Enter the URL like this:

http://<servername>:<port>/tfs/

Add a TFS Server

Now you should be good to connect to the server.

Posted: Wednesday, June 09, 2010 10:10:10 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
Strange Problems | TFS | Visual Studio

Using Linq Against a Custom ConfigurationElementCollection

By default, ConfigurationElementCollections don’t implement IEnumerable<T>, so if you are using custom configuration sections you can’t query them with linq. I found a casting solution, but I figured I could do better because the custom configuration classes are under my control, so it would be cleaner to implement the required functionality instead of using the clunky cast in the code consuming the collection. I implemented IEnumerable<T> against the ConfigurationElementCollection. It’s pretty straightforward, just calling the base class BaseGet function and casting the result properly using the As keyword. Now I can execute linq queries against my collection.

using System;

using System.Collections.Generic;

using System.Configuration;

 

namespace Config.Demo

{

    public class MapConfig : ConfigurationSection

    {

        [ConfigurationProperty("fields")]

        public MapConfigCollection Fields { get { return this["fields"] as MapConfigCollection; } }

    }

    public class MapConfigElement : ConfigurationElement

    {

        [ConfigurationProperty("server")]

        public string Server { get { return this["server"] as string; } }

 

        [ConfigurationProperty("name")]

        public string Name { get { return this["name"] as string; } }

 

        [ConfigurationProperty("id")]

        public int Id { get { return (int)this["id"]; } }

    }

    public class MapConfigCollection : ConfigurationElementCollection, IEnumerable<MapConfigElement>

    {

        public MapConfigElement this[int index]

        {

            get { return base.BaseGet(index) as MapConfigElement; }

            set

            {

                if (base.BaseGet(index) != null)

                {

                    base.BaseRemoveAt(index);

                    this.BaseAdd(index, value);

                }

            }

        }

 

        protected override ConfigurationElement CreateNewElement()

        {

            return new MapConfigElement();

        }

 

        protected override object GetElementKey(ConfigurationElement element)

        {

            return ((MapConfigElement)element).Id;

        }

 

        #region IEnumerable<MapConfigElement> Members

 

        public new IEnumerator<MapConfigElement> GetEnumerator()

        {

            int count = base.Count;

            for (int i = 0; i < count; i++)

            {

                yield return base.BaseGet(i) as MapConfigElement;

            }

        }

 

        #endregion

    }

}

Posted: Wednesday, June 02, 2010 4:58:09 PM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
.Net 3.5 | Linq

Staying with the Fire Hose

At the recent Ann Arbor Day of .Net, my colleague David Giard arranged an excellent panel discussion with Jim Holmes, Mike Eaton, Jay Harris, Patrick Steele, and Jason Follas, about keeping current with the stream of constantly evolving technology with which we work (aka the Fire Hose). I felt this was one of the best sessions of the day, the audience was very engaged with the panel. It definitely ended too soon. *Update* David Giard posted a video of the discussion on his Technology and Friends webcast.

One of the discussion points revolved around training. I think a couple points were pretty clear from the discussion:

  1. Companies don’t provide enough or the right training
  2. You own your career, it’s up to you to get the training you need.

One of the discussion points that I wanted to contribute, was that the existence of Day of .Net is partly driven as a reaction by the community to the two points above. We attend these conferences to learn (among other things) just enough about new technologies so we can effectively evaluate them and see if they fit into our day-to-day jobs or personal interests. Traditional training methods (books, classroom training, CTBs) seem to be falling further and further behind as the fire hose continues to flow faster and faster. We are at the conference to get some of the training we need, because it’s not available any other way.

Technical Books

For me, books have always been part of my learning, but more and more they are falling short. Technology is changing faster than publishers can respond. More often than not the book I need isn’t going to be published for a while. Even today (May 2010), look at the number of new developer technologies that are hot in my circles:

  • Silverlight 4
  • Windows Azure
  • Windows Phone 7
  • Android
  • SharePoint 2010
  • .Net 4.0

These are by no means niche technologies. You would be hard pressed to find many books published on them (maybe some around beta releases, those get stale fast and are often of dubious quality due to the rushed nature of the title). I completely understand the lag time, but I think the publishers need to step up and start paying authors as full-time employees so they can commit full time to a book and get it released sooner. Typically book authors are doing this on the side, I am sure that slows down time to market. There are some Microsoft technologies, like Commerce Server, that haven’t seen a new book since 2002. Arguably that’s a much more niche technology (and certainly not as popular as SharePoint for instance), but if a company as large as Microsoft is investing money to develop the product, they have users of the software so there must be some kind of market for those books.

I know lots of folks don’t work on the cutting edge (I spoke to a group of VB6 developers yesterday that didn’t even have Visual Studio installed), so this is less of a problem for them. As a consultant, this is a constant problem for me. Maybe I am am the minority and there isn’t as much market for these books so early? That’s hard for me to say. Either way, I know the publishers are losing my money, because I end up digging up blog posts and finding online articles to meet my need long before the book hits the shelves for me to purchase it.

Posted: Thursday, May 27, 2010 9:48:25 AM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
Programming | Reviews | Speaking | Tools

Loveletter Worm

Yesterday was the tenth anniversary of the Loveletter (ILOVEYOU) worm. This was the first real virus/worm that I ever experienced that actually took down a mail server. It was also an early, widespread, damaging worm. At the time, I was in my colleague’s office (he was the network guy), and he got an email. He looked at me and said “Why would Gary send me a message saying ‘I Love You’”? A few seconds and 5 similar messages later it dawned on him what was going on, he ran down the hall to the server room and hard-powered off the Exchange Server. Later we determined only 79 accounts got the email before he stopped it. It still took two days to get the mess cleaned up.

What really struck me about this was the code of the worm. I was doing classic ASP programming at the time, so I was pretty conversant with VBScript. I printed it off the code to check it out (see a description of what the code does). I was really struck by the fact that I understood what they were doing, and it didn’t even seem that hard. It was a real watershed moment for me as a developer, I had reached a point of understanding with that technology; it validated my progress as a developer.

The Love Bug: A Retrospect

Posted: Wednesday, May 05, 2010 10:37:35 AM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
None | Programming

Day of .Net Slides

I posted my slide deck from my talk (The Demise of Xcopy Deployment) at the terrific Ann Arbor Day of .Net 2010 on SlideShare. Thanks to everyone who attended both my talk and the event. A special thanks to the event organizers for doing a great job.

Posted: Monday, May 03, 2010 8:47:50 AM (Eastern Standard Time, UTC-05:00)  #    Comments - Trackback
ASP.NET | IIS | MSDeploy | Speaking | Tools