Monday, November 26, 2007

Moving Day for VSTO

I have been working on a Microsoft Office Business application sporadically with the Beta 2 version of Visual Studio.NET 2008. Once I got my hands on the RTM version of 2008, I tried to bring the project across. It did not immediately compile. I clocked in at about 20 build errors. A number of the assembly references were not recognized – apparently there was some renaming between Beta 2 and the real thing.I did a Google search on one of the unrecognized assembly references:

Microsoft.VisualStudio.Tools.Office

… and I was pointed towards the Visual Studio 2008 Readme file. But of course. That’s a handy place to put it, but I gave up reading readme files years ago – when they stopped being pithy descriptions of important issues and started becoming dumping grounds for any minutiae that the developer had in mind.

But this particular readme file had some good information. It began like this:

You may experience build and runtime errors when you build and run Beta 2 Office projects in the release version of Visual Studio 2008. Changes have been made to a number of VSTO reference assemblies.

Bingo. Then we got a nice little table:


Old Reference New Reference
Microsoft.VisualStudio.Tools.Applications.ServerDocument.dll Microsoft.VisualStudio.Tools.Applications.ServerDocument.v9.0.dll
Microsoft.VisualStudio.Tools.Office.dll Microsoft.Office.Tools.v9.0.dll
Microsoft.VisualStudio.Tools.Office.Common.dll Microsoft.Office.Tools.Common.v9.0.dll
Microsoft.VisualStudio.Tools.Office.Excel.dll Microsoft.Office.Tools.Excel.v9.0.dll
Microsoft.VisualStudio.Tools.Office.Outlook.dll Microsoft.Office.Tools.Outlook.v9.0.dll
Microsoft.VisualStudio.Tools.Office.Word.dll Microsoft.Office.Tools.Word.v9.0.dll


The main change seemed easy enough to follow: The Microsoft.VisualStudio.Tools.Office.* assemblies had become Microsoft.Office.Tools.*

I added the references noted above, and got it down to 9 compile errors. I then noticed that the table was not comprehensive. My suspicions fell on one of the last remaining missing assemblies --Microsoft.VisualStudio.Tools.Applications.AddInBase. I made the mistake of picking the namespace that looked the most like the old one to take up the slack -- Microsoft.VisualStudio.Tools.Applications.AddInManager. Wrong.

So I applied the formula that seems to be implied by the conversion table and looked for the following assembly: Microsoft.Office.Tools.Applications.AddInBase. Nope. Didn’t exist.

Back to Google:

Microsoft.VisualStudio.Tools.Applications.AddInBase

No hits. Wow. It’s not often your search term goes for 0-for-internet. Surely, the assembly name will be found somewhere within MSDN. Nope. I’m starting to wonder where that came from. Let’s try deleting it from the references. Boom. No effect on the number of errors.

All right, then. Put that one aside and see where the errors are coming from. I started to suspect this namespace:


Microsoft.VisualStudio.Tools.Applications.Runtime


…it seems to be giving the compiler heartburn. I look closer at one of the errors:

The type 'Microsoft.VisualStudio.Tools.Applications.Runtime.IEntryPoint' is defined in an assembly that is not referenced. You must add a reference to assembly 'Microsoft.VisualStudio.Tools.Applications.Runtime.v9.0, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

Isn’t that interesting? It’s telling me what assembly is missing… and I didn’t seem to have that reference in the project before. Taking the tip that the compiler gave me, I added that assembly reference (Microsoft.VisualStudio.Tools.Applications.Runtime.v9.0) And now we’re down to one compiler error.

The final error concerns the Ribbon Add-In that I created for my beta project. This was what drew me to use VS.NET 2008 in the first place. It was the only environment where you could use the designer to create a ribbon add-in that was specific to one document. (You could get to the same end result in VS.NET 2005 + VSTO, but there was a whole lot of rolling your own.)

In this case, I used the designer to build the Add-In, so the code was generated. That’s always fun to debug, because it’s sprinkled with warnings about how you should not touch the code under any circumstances. But let’s see if we can hone in. First, the compiler takes exception to the parent class – WordRibbon. So. If the shipping version of VS.NET2008 doesn’t like the way Beta 2 generated code, the next step is to see how the shipping version does it.

For comparison’s sake, I create a new Office project – a Word document. I add a new item to the project: Visual C# Items -> Office -> Ribbon (Visual Designer) The parent class that it generates in this case is OfficeRibbon. Otherwise, the method calls look fairly similar. So I simply change the WordRibbon to OfficeRibbon… and this time, the project compiles. Hit debug… and it fails on a SQL permission error. Vista’s new security paradigm strikes again – I’ll blog about that another day. I clean up that error, and now the application runs in debug mode… except my Ribbon Add-in does not show up. It does not throw an error, but neither does it show up.

Back to the test project I created to see how VS.NET 2008 RTM creates the Ribbon Add-In. That one works just fine – it shows up on the Ribbon where it’s supposed to. I launch another instance of VS.NET 2008, so that I can have both projects open simultaneously. I hone in on the generated code, which mainly consists of InitializeComponent() method. Other than the specific buttons and so forth, the code looks awfully similar.But I find one class in the *.Designer.cs file that’s not in the beta version

    partial class ThisRibbonCollection : Microsoft.Office.Tools.Ribbon.RibbonReadOnlyCollection
{
internal TestRibbon TestRibbon
{
get { return this.GetRibbon<TestRibbon>(); }
}
}







So I add that block of code to my new project (changing the class names). Why not? But that has no effect whatsoever.





This is an opportunity to dig into the internals of how the Ribbon Add-Ins generate code… but, then again, it’s not like I’m ever going to go back to the beta version of VS.NET 2008. It’s probably easier to add a new item to my new project – recreate the Ribbon Add-In with VS.NET 2008 RTM’s designer. That gives me the straightest line between where I am and where I want to go.





Recreating the Ribbon Add-In is pretty straightforward, mainly consisting of dragging and dropping a number of buttons. All the functionality behind the buttons resides in other classes, so I just have to wire simple method calls to the buttons’ click events.





One mildly interesting thing did come out of the exercise. Whereas the previous iteration of Add-In allowed me to create a reference to my Word document when the class is initialized:







IMPWriteFactorFour.ThisDocument _wordDoc = Globals.ThisDocument;




… which I then referenced within the Add-In class to execute methods:







        private void nextLineButton_Click(object sender, RibbonControlEventArgs e)
{
_wordDoc.advanceLine();
}







This caused a null reference error in the RTM version. It did not recognize the _wordDoc variable as a reference to the current Word document. I had to change the methods to explicitly set that variable.







        private void nextLineButton_Click(object sender, RibbonControlEventArgs e)
{
_wordDoc = Globals.ThisDocument;
_wordDoc.advanceLine();
}




… and it was happy. Apparently, something about the order of loading Ribbon Add-Ins changed between Beta 2 and RTM.





And now I can proceed, from the point I left off on Beta 2.





Lessons Learned?





I found it interesting that I had to change a number of assembly references, but the actual namespaces within the code did not have to change. Once I added the correct assembly, the code compiled. In looking at the assembly naming, I'm guessing that the dev team wanted to standardize the naming in the final release to conform to the naming conventions in the previous versions of VSTO. It was also interesting to see the differences in functionality between the beta and final releases of the Ribbon Add-Ins.

Sunday, November 25, 2007

The Climb to Visual Studio.NET 2008

So I was on the road when I heard the announcement that the RTM version of Visual Studio.NET 2008 had been released to MSDN subscribers. It caught me unaware – I hadn’t been keeping up with the timeline for the release. I tried to download it from my hotel room, but if you’ve tried to download anything bigger than, say, a text file on a hotel’s free WiFi, you know the folly of trying to grab a 4 Gigabyte file.


When I got back home and finally got my hands on it, the game was on. I had been playing with the beta 2 release of VS.NET 2008 for some months, so it was cool to get the real thing. To get that program, I had downloaded the Virtual PC from MSDN that had VS.NET 2008 beta 2 and SQL Server 2005 pre-installed. Being a Virtual PC junkie, I was touched by MSDN’s gesture of making that available to everyone.


Seriously, though. I'm deep with virtual machines. Since my work involves multiple clients, and my interests range far afield, I tend to organize through Virtual PCs. So if I go to one client, I’ll use one VPC with all the relevant programs and files, then when I go to another, I have a different VPC. My personal stuff is contained on other VPC’s still. I keep the whole shooting match synchronized through the excellent and underrated program Groove (which I will undoubtedly blog about later). The only downside is that I have about 15 Petabytes worth of VPC’s.


Naturally, then, I decided to install the RTM version of VS.NET 2008 on a VPC. Some interesting things came out of the exercise. Because of the nature of this blog, I’ll tell you about the problems.


I started with a base VMWare image that was running the Vista operating system. It also had the Microsoft Office 2007 Ultimate suite, which I considered vital, since developing Office Business Applications is one of my current interests. I cloned the virtual machine, and then installed programs in the following order:

1. Visual Studio.NET 2008 Team Edition
2. SQL Server 2005 Developer Edition
3. SQL Server 2005 Service Pack 2

I had been through the painful process of trying to get VS.NET 2005/SQL Server 2005 to run on Vista, so that’s why I went straight from the base installation of SQL Server 2005 through Service Pack 2 without pause. There is a good description of that process here.

Well, this “leave the configuration up to the programs” approach caused problems. It seemingly always does, of course, but I’m a hopeful sort. The first problem was that VS.NET 2008 gave me a warning about IIS not being configured. SQL Server 2005 did the same. Worst of all, I found myself without an instance of SQL Server Management Studio 2005. And yes, I had selected Management Tools under Client Tools node in SQL Server Setup during installation. It just apparently didn’t see fit to install or give a descriptive error of what caused the installation failure.

The IIS problems were understandable after a bit of detective work. VS.NET wanted certain features to be turned on, and SQL 2005 wanted some to be turned on as well. Even if you have IIS 7.0 turned on, the installers will not necessarily recognize it. The correct configuration was hardly intuitive, but the information was available.


The lack of SQL tools was a bit more troublesome. Most of the discussion around the issue either blamed the person installing SQL for not selecting Management Tools. There was some sporadic advice about how to install the client tools on their own.


I tried to install the SQL client tools on their own. First, I went the route of changing the program through the usual Vista method: Control Panel -> Programs and Features -> Uninstall a program (I regret that when you want to change a program installation in Vista, you have to select Uninstall a program, but I digress.) That didn’t work. I ran the main SQL Server Installer, and I ran the specific MSI for the client tools (SqlRun_Tools.msi). I was unsuccessful, but the errors were ambiguous. I believe it had something to do with the fact that I had already applied Service Pack 2, and I was trying to go back to the original discs to add the client tools.


I still haven’t got a concrete answer, but I could guess at some possible problems with the initial installation. Maybe when SQL tried to install VS.NET 2005 (as part of Business Intelligence Studio), the installer recognized that a later version was installed (VS.NET 2008) and aborted the operation. Or maybe VS.NET’s installation of SQL Express gummed up the works. I just decided to attack the problem another way.


Solution abound


So. Step #1 for me was to make another clone of my base virtual machine and take another shot from the beginning. Then it was a matter of reconfiguring IIS so that the programs would recognize it. Using a variety of sources to find the requirements for both VS.NET and SQL, I ended up selecting the following settings (to get here in Vista, select Start Menu -> Control Panel -> Programs -> Turn Windows Features On or Off)

Internet Information Services
Web Management Tools
IIS 6 Management Compatibility
IIS WMI Compatibility
IIS Metabase and IIS 6 configuration compatibility
IIS Management Console
World Wide Web Services
Application Development Features
.NET Extensibility
ASP.NET
ISAPI Extensions
ISAPI Filters
Common Http Features
Default Document
Directory Browsing
HTTP Errors
HTTP Redirection
Static Content
Health and Diagnostics
HTTP Logging
Request Monitor
Performance Features
Static Content Compression
Security
Request Filtering
Windows Authentication

(The features in bold were the ones I checked).


Then I changed the order of my installation:

1. SQL Server 2005 Developer Edition
2. SQL Server 2005 Service Pack 2
3. Visual Studio.NET 2008 Team Edition

Right as rain this time. Both programs were happy with how IIS was configured. The SQL client tools appeared as expected. I now have my installation of VS.NET 2008 rocking. And there was much rejoicing.

What have we learned?

If you are going to have a full version of SQL running with VS.NET 2008, install it first. Tread carefully when configuring IIS on Vista, to work with VS.NET and SQL.

Saturday, November 24, 2007

What I'm Up To

Almost all the important things I've learned about coding have come as a result of difficulties. Don't get me wrong, I'm addicted to reference material -- technical books, blogs, and even user manuals. I read them with abandon. I can find something interesting in just about any technical topic, no matter how obscure. But training cannot substitute for the experience of sitting in front of a computer, trying to accomplish some piece of functionality. The questions start immediately. What am I trying to do? How can I accomplish it? What is the best way to accomplish it? How will this task fit into a larger picture? The questions have real consequences. If you don't find an answer, your code does not work. Reference materials help, but the fundamental process of trial and error is where learning really starts to happen.

Another enduring problem is that reference material for technology is fairly good at telling you what it can do. Finding out what it can't do is another story. It makes sense, I suppose. If every software vendor had to document every feature it does NOT have -- "support for 64-bit", "vector graphics", "toilet cleaning" -- manuals would be very long indeed. But it seems like there always comes a time where I say, "I'd like to implement feature A, surely there's a method to do that." -- but I can't find it. Then it becomes a long process of guesswork, until the envisioned solution is hit upon, an alternate method is found, or I go take a rest in the insane asylum for a while.

Most technical blogs -- and let me re-emphasize that they are invaluable to me -- take the tactic of tutorials, feature demonstrations, or product information. I've been considering writing a similar blog myself for years. But after some revelatory struggles with coding, I thought it might be more interesting to write about the challenges I face. I plan to document some of the struggle; not just the pretty end result, but the mistakes, bumps, and bruises that lead to the goal.

I have to believe that anyone who's serious about software development faces similar challenges. It's an industry where you have to keep challenging yourself to move outside your comfort zone, or you never progress. If you find a comfort zone, it generally changes.

I've been in the industry for a decent amount of time. The amount of change is staggering year-over-year. The number and variety of development tools almost defies comprehension. It's rare that I get involved with a work project that doesn't have some novel (to me) technology or technological approach. Then there are the projects that I work on for my own interest. For those, I generally choose new technologies I want to learn. So the learning curve provides innumerable opportunities to share my difficulties.


I kind of doubt that this blog will develop a consistent theme, technology-wise. Since my interests in technology and software development know almost no bounds, I'm generally all over the map. If I hear about something that sounds interesting, I will go after it. Chances are good that most posts will deal with the Microsoft stack, since my career is totally focused there, and my personal projects trend in that direction. But don't bet the farm on it.

So welcome to my blog. If some of my challenges interest you, make you laugh -- or best of all, help you, then I've done what I've set out to do.