Tuesday, February 05, 2008

this == null

This is an actual screenshot... I don't know how (seemingly it does have to do with some lightweight generated code) but I managed to get an NullReferenceException because this was equal to null... Go figure.

Wednesday, January 30, 2008

CompositeUI Application Block: TypeLoadException GetExportedTypes in ModuleLoaderService

(Don't mind the title, I put all the necessary keywords to help others having the same problem to find this post :)).

Have you ever tried loading un-loadable assemblies with CAB? Like, the ones that have unresolvable references or something similar. You won't get a normal assembly binder (or whatever it's called) error... No, the exception you will get will be a TypeLoadException that is thrown by a call to GetExportedTypes() in the ModuleLoaderService. With a cryptic message saying that some type (probably the first one in the assembly) couldn't be loaded. if this happens, go back and check if your assemblies have valid references.

Thursday, October 11, 2007

How to terminate a work item when its smart part closes?

I've been google-ing around for a solution to this, but had no luck. It seems that either the designers of the Composite UI Application Block (CAB) have entirely overlooked a pretty common situation or I am missing something obvious... The problem is quite simple: you have a WorkItem with a single view. When the WorkItem is run, it displays its view control (a smart part) in an MDI workspace - which means the control is automatically put inside an mdi child window. So, when the window is closed, you'd naturally want the WorkItem terminated.

Well, CAB doesn't do this for you, and rightly so because the WorkItem is not a part of the window even though its SmartPart is. You have to do this yourself. The most logical solution could be to handle the SmartPartClosed event on the MDI workspace and close your WorkItem at the moment the smart part is closed... Yeah, but there is no SmartPartClosed event, only SmartPartClosing! You could add it yourself, as John Luif did, or you could look for a workaround...

Since I don't like changing code published by others, I tried the latter option. If I try to terminate my work item from the SmartPartClosing event, the WindowWorkspace throws an exception because terminating the WorkItem kills everything inside it, probably including the smart part and maybe even the workspace itself. So when the SmartPartClosing event handler returns to the workspace, the workspace is not in its previous state anymore... (Note that I'm assuming that this behavior is not a bug - which it could be). But wait, there's a workaround for this one also: the SmartPartClosing event is cancelable. So, if I cancel the smart part close and terminate the WorkItem instead... Like this:

void containerWorkspace_SmartPartClosing(object sender, WorkspaceCancelEventArgs e)
{
if(e.SmartPart == mySmartPart)
{
// cancel the closing operation and terminate the workitem instead
e.Cancel = true;
this.Terminate();
}
}

Nice one: that is, ugly but working. Or is it? When the user tries to close the main MDI form, this triggers closing of all child forms, but this gets canceled at the first window. What now?

Well... I did this -
 protected override void OnClosing(CancelEventArgs e)
{
//base.OnClosing(e);
WorkItem.Terminate();
}

- in the MDI form. Even uglier, but it seems to work. Now, if I could figure out the reason why CAB works this way (there may well be one) I'd know if this solution is right.

Tuesday, May 29, 2007

CAB error: A circular control reference has been made. A control cannot be owned by or parented to itself.

I've stumbled upon an interesting issue that nicely illustrates how the Composite UI Application Block requires you to change the way you think. It would seem a logical procedure to create your SmartPart control first (call WorkItem.Items.AddNew to do it) then add it to a workspace. But what if your control contains an embedded workspace by the same name? You'll get a circular reference exception ("A circular control reference has been made. A control cannot be owned by or parented to itself.") This is because CAB completely ignores the control hierarchy and has its own system of tracking components. When you add a SmartPart control to the WorkItem, all of its child SmartParts also get registered with the WorkItem, regardless of the fact that your SmartPart hasn't been added to the container control. So when you look for a workspace in the WorkItem, CAB will also detect workspaces inside the SmartPart.

Yeah, but what happens if you use the dependency injection instead of the AddNew method to create your SmartPart? You'd probably be stuck...

Monday, May 28, 2007

Metadata and misunderstandings

A great number of software development problems arises from the fact that the whole philosophy of current development languages and environments is about programs doing something, but without any effort to explain what they're doing. I will give you an example: if you disable a button in a windows form, do you ever give the user a way to find out why the button is disabled? If you perform some database operation in one or another way, will anybody (except a developer armed with a debugger) know what - and more importantly, why - was done?

The answer to my questions would probably be: yeah, so how would you expect me to do it? Log everything? Show message boxes (not exactly useful for disabled buttons) or tooltips? There isn't a standard way to do this and the user would never expect nor find the information. We lack a user- as well as developer- friendly mehanism. If I could write a piece of code like -

btnDelete.Enabled = false -> explain "You don't have enough permission to delete this record";

... the user could possibly be able to see somewhere the list of available explanations (marked with, say, glyphs visible under certain conditions) and review what interests him at that moment. Of course, there's another problem with what I've written here - the framework should somehow be intelligent enough to understand that the explanation should be attached to btnDelete. Or we would have to tell it - in which case we get the following code:

btnDelete.Enabled = false;
btnDelete.StateExplanation = "You don't have permission for this.";

This explanation mechanism is now nothing more than a more intelligent and somewhat differently standardized tooltip. Of course, if the button was completely hidden, we'd display its state somewhere else (for example after a click on some kind of a "what's going on" button).

How about explaining to user the performed operation? We'd need to have a standardized way of buffering explanations and then possibly displaying them as a glyph on a message box that says "The operation was successfully performed. Click here to see what it did and why".

So, in this case it's a relatively simple matter and all that is lacking is a standardized infrastructure. But it would make the application's logic and inner workings much clearer to the user and rapidly drive the learning curve down.

Yeah, but this is not enough, is it? The explanation data cannot be examined by another program, for example. There's no metadata in string explanations. We cannot determine programmatically what the application has done or what it's currently doing, or why has it done something. Why would we need this, you ask? Well, if an application opens a confirmation message box while you are shutting down Microsoft Windows, Windows will say that the application is not responding and ask you if you want to kill it. If the windows could find out what the application is currently doing, it would (or at least could) behave much more intelligently. The "I'm busy, come back later" or "I'm waiting for the user" metadata explanations could be a standard way for the applications to communicate and could probably be built at a higher level into various interprocess communication mechanisms or remote procedure calls. So you wouldn't have to have an "out errorMessage" parameter in each one of your web service methods.

Ok, so does this mean we'd have to write metadata to explain every single method the application can perform? The answer is of course - god forbid, because our development speed would suffer greatly. Not to mention the security issues. But we could start somewhere, try attaching metadata to a minimal set of standard procedures and go from there. Today we are witnessing the convergence of metadata and procedural programming: there are more and more tools that can generate an application from a rich model or execute code based on metadata (.Net attributes), and the programming languages have increasingly richer metadata content. Soon enough the applications will start talking to each other, and at that point C# could be replaced (or more probably extended) with some kind of a metadata language. Look at dependency injection frameworks: the components are already learning how to talk to each other :).

Monday, April 30, 2007

How to not waste your time on stupid mistakes?

Ayende made an interesting light-hearted post concerning developers that spend hours chasing a bug in an application only to find out they forgot to do some utterly trivial thing. Well, stuff like that is maddening. The solutions to these kind of mistakes are utterly nonsensically simple yet we don't know the proper way to prevent them but instead lose time debugging.

The contradiction we have today is that we get these all-encompassing frameworks that do a lot of things by themselves, but are so big we almost always miss something when using them. And instead of losing time writing intelligent stuff we get the stuff ready-made but lose time on trivial mistakes :). But how to solve this time-wasting issue? Microsoft's answer is - guidance. It sounds promising as I believe it would generally be helpful to generate more code (at least skeleton code), but that's not so easy. Also, we should be careful when designing APIs, make them as obvious as possible (even if we have to make dozens of method overloads). And validate and assert everything we can... But that's still not enough. And the stuff we are talking about is ridiculously simple to describe: if you use a TransactionScope you should commit it. How to protect ourselves from this simple mistake? Use FxCop to validate code? Use a higher-level language? Stop coding alltogether and use an AI to generate applications?

Wednesday, April 18, 2007

Silverlight picks on Flash

... as Microsoft attacks Adobe's piece of the cake.

Microsoft has announced the official release of WPF/E under the official name of Silverlight.  The list of announced features is quite interesting (here's Tim Sneath's post), and it seems consistent with the philosophy we already saw with other .Net technologies: borrow everything that's good from the competitors, improve their weaknesses, integrate with .Net and make it develop-able in Visual Studio. If you know how C# stands compared to Java or ASP.Net compared to JSP, you know the answer... It's similar but not the same as SWF. Silverlight looks like a more technologically advanced version of Shockwave/Flash, it has some new ideas (like embedding XAML directly into the html page - which Flash player cannot do because it's SWF format is binary). But this is all on paper. For years Microsoft developers have been victims of unfulfilled promises: features were delivered as broken or incomplete or just silently dropped.

The real question is, will Microsoft Expression Whateveritsname be a better tool than Adobe Flash? If you compare feature lists, this is almost certain. But how will this features be implemented? There are already reports that the even the present Expression version, the Web Designer is far from complete. The other tool that could be WPF/Silverlight compatible, Visual Studio Orcas, is also in the making but if the previous Visual Studio .Net versions are anything to go by, it won't be a high quality or stable tool. For example, a major killer-feature of VS 2005, data binding, is still very much broken, even after service pack 1... And visual inheritance - present but unstable in previous versions - was just dropped in 2005's first release.

There was also some stir because the official announcement failed to mention a Linux Firefox plug-in for Silverlight. Well, I'm quite sure it had been announced at MIX 06: I remember one of the presenters declared that developing a Linux Firefox plug-in was (quite understandably) a great technological challenge for Microsoft people. I may be mistaken, it may have been just Firefox, without Linux :)... One thing should be clear, though: Microsoft's is going cross-platform not because they like Mac or Firefox but because of the antitrust case and because Adobe's already there. So, a Linux plug-in shouldn't be a big surprise at all.

There's also another interesting twist: with Silverlight, Microsoft is essentially entering an arena in which Adobe/Macromedia was the only fighter - seemingly, a benign monopolist. It's somehow strange to see Microsoft actually boosting competition instead of trying to destroy it.

Wednesday, April 04, 2007

Visual Studio project references

Replacing one project in a Visual Studio 2005 solution with another one is not as simple as it sounds. Partially because of Visual Studio playing smart and/or dumb but partially because of project file structures.

Let's say you have made a new branch for one of projects in your solution. It's in a separate folder than the version you're currently using and you want to change all projects in the solution to reference the new one. If you remove the old project from your solution the smartypants Visual Studio will remove references to it from every single project in the solution. Even if you could save only this changed solution and discard changes to project files (don't know if you can), it wouldn't work. Even if you open the solution file in notepad instead, and change it to include the new project, it's a no-go. The solution would probably build fine and the project references in visual studio would seem ok (no exclamation marks, paths shown in the properties window pointing to the new version) but still the wrong dll will be used.

Why is this? The project file (*.csproj) stores its own path to the referenced project and uses it instead of the solution's (this actually makes sense). It doesn't matter if the referenced project is included in the solution or not: Visual Studio will find the referenced project's dlls and use them without building the project. Only if you go to the old project's bin folder and delete everything will you get build errors for projects referencing this old version. And the curios thing is that again if you inspect the culprit project's references, Visual Studio will still insist that it references the new dll's.

So, in the end, you will use compiler errors to detect which projects reference the wrong version, and then remove-add references to change them. You probably would have saved time if you let Visual Studio remove all references in the first place.

Friday, March 02, 2007

Mind over Microsoft: curing DataSet autism

The deeper I dig into Visual Studio 2005 the more I get the impression that it contains more obstacles than features. It isn't enough to just think something over and figure out how to do it: each step of the implementation may hide a showstopper - either a bug or a crippled feature. You have to check very carefuly if all you thought of can really be implemented.

Here's a good example on how you can get sucked into "Visual Studio does everything by itself" Microsoft agitprop. I wanted to work out a simple solution for a non-creative task which is making search forms for my windows application. You know, search: enter what you want to search for and you get a list of records from the database. A form with a data grid in the center, some text and combo boxes above it for the user to enter search criteria into, and a SEARCH button.

What would be the best way to implement this kind of component, to make mass production as fast as possible? Let's see... I'd have to utilise the design-time functionality to the maximum. There could be a base class containing most of the logic and all common components: say, an empty DataGridView which the user could configure from inside a derived component to add columns etc. The dataGrid would be bound to a BindingSource which is in the base class, but its DataSource type (the DataSet used for search operation) should be set from the derived component so the designer could know what properties exist in it.

Then, in the derived component, a developer would add a new data source for the BindingSource - i.e. create a DataSet, modify its sql query and voila, the grid's columns are automatically initialized and prepared for customization. The base class would pick up the DataSet type being used and wire up the logic (i.e. SearchButton_Click handler) for filling the DataSet - after all, the DataSet has a generated TableAdapter configured and ready to go.

Now, how to enter search criteria? This one could be interesting: write the DataSet SQL with prepared parameters in the WHERE part, like "SELECT something FROM something WHERE (column1 = @param1 OR @param1 IS NULL) AND (column2 etc.)". Next, create a separate BindingSource in the base class for search criteria. In the derived class, bind it to the table adapter's parameters, then add text and combo boxes to your liking and bind them to individual parameters. Ok, this could be problematic, but an ICustomTypeDescriptor wrapper class or something could help turn the adapter parameters into something bindable. So, using high-tech Visual Studio designer components, the user gets to make a complete search form in half an hour. Wow!

Um, I hope you didn't read this post from the middle? Because you could have gotten the wrong impression that this could be done. The cruel reality is that most of the abovementioned doesn't work. Let's start from the beginning.

Have you ever looked at the generated DataSet source in VS 2005? I don't know if it's the same as in VS 2003, but it's not just ugly, it's absolutely hideous. I thought that if I notify my component of the type of DataSet being used, it could somehow detect the proper DataAdapter from it. Not likely: not only there is no property on the DataSet that could point to the DataAdapter type (let's say this is ok, there could be more than one DataAdapter for a given DataSet), but the DataAdapter is not even in the same namespace! Why isn't it a class embedded in the DataSet? Nobody thought of that. It doesn't seem there was a lot of thinking invested here anyway.

But this is not the end of it: the generated TableAdapter is not a table adapter at all, it's a class derived directly from Component - in other words, a nobody! The real DataAdapter is in its private property. (Aarrggh, ok, we'll use reflection to access it then). Yeah, but the real adapter is not initialized when the quasi-TableAdapter is instantiated. It's initialized only when you call the Fill method... And since there is no base Fill method (remember, the base class is a Component), the only option is to call the generated Fill method and feed it parameter values. So, if I'm going to use reflection anyway to get the private property, why not call the Fill method directly.

Ok, never mind: use reflection to get the adapter, call all the proper initialization methods using reflection and hope their names don't change in future versions. (Fat chance, I'd bet this code survived from the VB days. I tried finding the DataSet designers using Reflector and stopped when at some point the .Net code jumped through the interop mirror over into the COM world... Well, that's true at least for the sql designer - which is the most useful part of it anyway).

Now, to make an ICustomTypeDescriptor to bind to the sql query parameters. Well, it can't be done: BindingSource doesn't support ICustomTypeDescriptor. Just think of it: what do you get when you add two cool technologies together? Nothing, because they've been made by Microsoft. Do the guys over there talk to each other at all?

So, I resorted to a brute-force solution: created a new wrapper class complete with a VS.Net designer that detects parameters from a given TableAdapter and creates an accessor property for each of them. So I can bind to the wrapper and the wrapper will then call the TableAdapter.

Have you started wondering why I haven't chosen to abandon DataSets and create my independent components? I did think about it - but at this point it is pure bloody-mindedness that drives a man to beat the damn technology. It's a challenge.

Yeah, right. Next step: the DataGrid. In the derived class, we configure the BindingSource to use the generated DataSet and then get the DataGrid to automatically configure its columns from it. Then we just reposition and format the columns and -

Well, surprise surprise: visual inheritance is turned off in VS 2005. (I know it's old news, this is a story that was a long time in the making: just look at the sheer volume of text above). So - man, do you still want to beat the technology?

I had to make my own templating mechanism (an extender provider, actually: these are very useful) so one can put the controls into the derived class and then set their "extender-ed" property that says into which area of the template it should be placed. So the base class picks up thusly marked controls and knows which is which.

Next? Binding issues: the pre-SP1 data binding designers in VS 2005 are extremely fiddly (the post-SP1 ones are just fiddly). You can bind controls to datasources but you aren't sure you'll be able to open the designer again in the future. The class properties don't always appear in the data sources toolbox. And the ones that do, don't appear when you try to bind from the properties window. If you want to bind to a property's property, you'll have to write the path manually. Jesus Christ! Today they'd give you Visual Studio .Net instead of a cross.

Wait, there's more: the DataSet designer resets most of the manually set properties (like parameter or column types or their AllowDbNull property) every time you reconfigure it. Before you start modifying a DataSet, you have to memorize its properties' values first. If you forget a single detail, you either won't be able to compile or you'll introduce a bug you'll waste some more time fixing (possibly at a later time when you forget what you did).

And more: I'm not quite sure how connection strings are supposed to be handled in VS 2005 SP2. If I try adding a new connection string to the project, it doesn't show up in the dataset designer. I suppose the designer caches existing connection strings in the XSD files but never seems to refresh them. If I try to rename one of the connection strings, I either get a refactoring error (the refactoring engine somehow destroys a property in the dataset's Designer.cs file) or I end up with crippled XSD files (half of its XML simply goes missing). Sometimes, for reasons unknown to me, a one of connection string names gets a full path with a namespace, and XSD starts reporting errors until you fix it (turns out it cannot stand dots in connection string names).

I'd already lost enough time battling with Visual Studio 2005 that any productivity improvements from using it - and after all this I seriously doubt there will be any surprises any time in the future - cannot compensate for it. It did sound like a good solution before I started implementing it, but that is because it was based on wishful thinking fueled by Microsoft marketing. One has to be very careful about these things: for any such adventure, multiply your time estimate by three.

Wednesday, January 24, 2007

How to get the containing folder for a ProjectItem in a Visual Studio 2005 designer

It was a long search, and I must say that the item in question was very well hidden (congratulations to whoever put it there :)). The problem was this: how do you, from inside a Visual Studio designer or add-in, get a reference to the current ProjectItem's containing folder? And I don't mean the folder on the disk, but the Visual Studio project folder that may not be the same.

You'd never find it... It's in ProjectItem.Collection.Parent! Here's some sample code (the idea is to put the code into a component designer: I haven't tried this actual code, but the basic idea is the same as what worked for me):

public ProjectItem FindActiveDocumentsSibling(string fileName)
{
// we need the DTE to get the active document
DTE dte = (DTE)Component.Site.GetService(typeof(DTE));

Project ret = null;

// try-catch is necessary because Item() throws an exception if no item is found
try
{
((ProjectItem)dte.ActiveDocument.ProjectItem
.Collection.Parent).ProjectItems.Item(fileName);
}
catch { }

return ret;
}


So, what's this for? Well, I'm trying to put an NHibernate *.hbm.xml file next to a code class. (Look at a previous post as to why it isn't a child item but a sibling). Now if I could only figure out how to (or whether I should) open it using Visual Studio mechanisms - but without showing it to the user...

How to restore/reset lost Visual Studio 2005 menu items

For some strange reason, installation of various add-ins and add-ons for Visual Studio 2005 causes it to reset its menus - and possibly other settings. But they don't get reset to installation defaults: rather, Visual Studio goes into some kind of minimalistic state where you don't get a "Macros" item in the "Tools" menu anymore, the "Attach To Process" and "Exceptions" commands get lost etc. At first I resorted to going into the Customize dialog and bringing back the items each time (although I never was quite able to figure out how to correctly get back the "Build [project name]" item: occasionally it either appears twice or disappears). I did so much installing/reinstalling of various CTP's that eventually I gave up on customization and started using keyboard shortcuts instead of menus. Now, finally, I found out that there actually is a simple way to reset settings to "normal" instead of "obscure" (seems I hit the right magic word with Google: my searches for "reset Visual Studio 2005 menu" and such led nowhere, but once I asked it how to restore the Macros menu, I struck gold :)). The solution is as follows: go to Tools -> Import and Export Settings and choose Reset all settings.

The original link:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1114019&SiteID=1

Monday, January 15, 2007

Fix for the CAB sample visualiser bug

The Composite UI Application Block has a very useful feature called "visualisers". It's purpose is to give the developer an overview of what is going on inside a CAB application, which, due to a large amount of various mappings and automated dependencies, could othewise become an overwhelming task.

Great idea - but how about an implementation? Well, there is some documentation (very obscure, just like the rest of the CAB docs) and a single sample visualisation. The sample could be useful were it not buggy: it shows you a treeview with WorkItems and SmartParts in your application, but holds a strong reference to them (or something like that) which prevents them from being disposed. So, in effect you don't get a real overview of your application's state. I didn't know about this bug and wouldn't have noticed it were it not kindly pointed out by the CAB people themselves. But it seems it was too much for them to fix it (strange because the sample visualisation consists of a single windows control).

Or they waited for the community to do it - which at the end someone did. This seems to be the philosophy Microsoft is toying with these days. They seem to want to copy IBM's success with supporting open source projects like Eclipse, but are loath to give anything to open source. Microsoft, like always, wants it all - commercial software supported by a free community. Is the lacking documentation for CAB also supposed to be supplemented by community posts on CodePlex? Come on, people, it's been a year since CAB was released and all we have is a package of hands-on labs and a MSHelp file compiled from XML documentation in the source code.

Thursday, January 04, 2007

Visual Studio 2005 Service Pack 1, part four: recovery

How to recover from a failed Visual Studio 2005 service pack 1 installation (or how I did it, in any case).

It seems that with a failed setup there is a hung instance of msiexec left running (it can be seen in the task manager) and some files are kept locked in the c:\Config.msi folder and cannot be deleted even when this msiexec is killed. I didn't have the time to fool around restarting the installer service but restarted the whole windows instead. I wouldn't be too surprised if the installation error was actually caused by the installer encountering a locked file.

So, these are the steps I made to recovery:
  • Made some more space on the C: partition. In the end it totalled 2.7 GB, but it could be possible to succeed with less. This is not counting the TEMP folder which I moved to another partition (you do this by setting the environment variable in control panel -> system). Note that you can free up a lot of space by going to c:\windows\installer and deleting the previously copied SP1 packages - look for files of 466 MB with recent time of creation.
  • Went to the c:\WINDOWS\WinSxS folder and deleted files with "8.0.50727.762" in their name, like it was mentioned in this post (scroll way down). Note that the post says I should delete files named like "8.0.50727.163" but I was unable to find any.
  • Restarted windows. I believe this is important - at least find and kill the hung msiexec process and restart the windows installer service.

Wednesday, January 03, 2007

Visual Studio 2005 Service Pack 1, part three: check that!

Waitwaitwaitwait...

BEFORE you start installing the VS 2005 SP1, make absolutely sure you have enough disk space... Otherwise, you will surely regret it: if the installer runs out of space, it will mess up your .Net installation and not only Visual Studio will stop working but an assortment of other applications. I had the same problem on two installations, after the two mentioned successful ones.

The installer dumps a 460+ MB installer package into your c:\windows\installer folder and names it differently every time. So if you cancel an installation (e.g. to uninstall the damn web applications add-in that I always forget to remove) you could end up with multiple copies of the same half-gigabyte package and thusly short of disk space. The installer then reports that insufficient space is available and even if you clean up your disk and click retry it will eventually die with error 2908 and leave your system in a demented state.

So what do you do? Some say you need 4 gigs on your hard disk to make it work. I personally redirected the TEMP environment variable to another disk with lots of space, but that is only part of the solution because only part of the files go into the temporary folder. There is a batch file (see links further down) that turns off some kind of caching (haven't had time to go into details) that could save space and make things somewhat faster.

I'm trying as we speak (well, sort of) to repair a destroyed VS installation so stay tuned for results. In the meantime, some useful links:

How to disable the patch cache and make the installation somewhat faster (so you can retry more times in 24hrs :)):
http://weblogs.asp.net/jgalloway/archive/2006/12/19/things-i-wish-i-d-known-before-i-installed-vs-2005-service-pack-1.aspx

A sum-up on what goes on and how to get yourself out of the mess if you got into it:
http://asztal.net/2006/12/and-the-prize-for-worst-installer-of-2006-goes-to/

How to get a debug log from the installer (hopefully you won't need it):
http://blogs.msdn.com/astebner/archive/2005/03/29/403575.aspx

Wednesday, December 20, 2006

Visual Studio 2005 Service Pack 1, part two: installation

Ok, I've installed the bugger... (Umm, bugger? This is actually an interesting attribute for anything related to software development :))

First try: installation on a "clean" machine (no SP1 beta, no CTPs and the like). Forced me to uninstall Web Application Projects add-in: the installation package claims the add-in is included in the SP (although there have been controversies about this on the net). The installation takes a bit more than an hour. I don't remember how much it took to install Visual Studio, but compared to SP1 beta's 3-4 hours, this is nothing.

Upon first installation, I tried randomly opening several forms, controls and our components with our own custom-made designers. Either I was (un)lucky or Visual Studio really started behaving much better, but I couldn't get any of the errors I kept getting earlier (like "path is not a legal form"). I did find one bug from earlier though, and it was the first one I tried: if you try to "Open containing folder"while you're in a exception-breakpoint, Visual Studio will freeze until you force-close your application.

Second try, over a SP1 beta installation. Well, it's also not true that you have to uninstall SP beta, at least on Windows XP. At least in my case... Once again, no problems.

As for the quality of the service pack, it seems satisfactory. Visual Studio does seem to run more smoothly. I haven't experienced any slowdowns, component loading errors don't pop up as often etc. I even noticed that marking of container foreach statements when you type "break;" into the C# editor once again works.

So, the conclusion? Visual Studio works better with SP1 than without. It almost seems to behave nicely, but it's early to say. In any case - recommended.

Tuesday, December 19, 2006

Visual Studio 2005 Service Pack 1

The Visual Studio Service Pack 1 is here, hooray... We'll see what it brings, but I won't be surprised if its installation disclaimer contains a phrase like "don't expect it to solve any of your problems". According to some bloggers, you should uninstall May LINQ CTP before you install this one... Now, I'm sure I do have some of LINQ CTP's installed, but I haven't the faintest which one it is since LINQ is in its own brand of chaos with various plugins, addins and designers all being of different versions (so, is the september designer CTP the one that works with may LINQ CTP? I think I have a september CTP of something...)

But that's OK, LINQ is a pre-release software and you're expected to have some trouble with it. On the other hand, Service Pack 1 is kind of a post-release, so... We'll see. For the time being, I heard that its installation takes longer than the initial Visual Studio installation. This is because it -- according to Microsoft -- does more tasks than the original installation which just copies files. Makes sense when you say it that way. The Beta 1 had a different explanation, they said it was slow because it's beta. Some guys say you have to uninstall SP1 beta before you install this one, this could mean even more wasted time. Not cool if it's true.

And, last but not least, I'm almost looking forward to having this installation reset my Visual Studio UI again. I've lost my Debug/Exceptions, Attach To Process and various Build menu commands so many times just thinking about it happening again makes me laugh (I haven't restored them this time, so go hide them if you can!) I don't think I care anymore.

Wednesday, November 22, 2006

Under the hood of Microsoft applications

Several blog posts ("Ankh and AccessViolationExceptions", "Ankh and Exclude From Project", "Losing faith", and others) from Arild Fines, one of AnkhSVN authors, reminded me how peeking under the hood of Microsoft applications can be a horrific experience. Anyone who has ever tried to create a non-trivial plug-in for Office or Visual Studio can confirm this. You work with events that don't get fired or get fired at the wrong moment (like Document.BeforeSave, among many), undocumented features and bugs that will slow your brain to a crawl, let alone your development, and force you to use workarounds so ugly you'll end up hating yourself :). Of course, doing it in C# brings additional interop-related problems and you have to resort to reflection for many operations that would otherwise be straightforward. That is why I'm always suspicious of Visual Studio plug-ins, especially the ones that replace Visual Studio features that didn't work well in the first place, like source control. AnkhSVN is probably a case in point: these guys are struggling to get this thing working, but there's always a danger of triggering a ridiculous bug in the environment that will make a feature unusable. Of course, if AnkhSVN blows, people will blame AnkhSVN, not Visual Studio. It's a bit like the endless argument between Microsoft and device driver makers about whether unstable drivers caused Windows to fail or bad quality of Windows caused instability in drivers. It is sobering, though, once you see how much trash is hidden under the surface of Microsoft applications and how much effort was invested into hiding bugs rather than eliminating them.

Tuesday, November 14, 2006

Codename whirligig

People inventing codenames at Microsoft had finally gone mad. Microsoft's implementation of AJAX, formerly codenamed ASP.Net Atlas has now been renamed to ASP.Net AJAX. What an original idea! I have a hunch that the same guys named Microsoft Expression, formerly codename Acrylic, formerly Fractal Expression. It's a pity that court order prevents them from renaming Microsoft's implementation of Java to "Microsoft Java (formerly codenamed C#)" :).

Saturday, August 05, 2006

Subversion support in Visual Studio 2005

Oh, while we're at it... I've been experimenting with Subversion support for Visual Studio 2005. Tried these:

AnkhSVN
- the "official" plugin, and probably the most advanced of the bunch. Open source, too. Works nicely with two caveats: if you create a new file, it won't allow you to delete it or rename it until you've committed it to SVN. Which is either stupid or I'm unaware of SVN rules (and I am). The second one is that if you rename a file, it will get irretrievably lost, and you'll have to juggle around with SVN just to get the previous version back. I understand that SVN is trying to make the best of its capability of tracking files across renames, and that the error is due to a bug in Visual Studio, but I'd be satisfied to lose the rename capability in order not to lose any files. Also, you should be aware that this is a beta version: you have to use the beta in order to get the plugin working in VS 2005. http://ankhsvn.tigris.org/.

Update (2006-11-22): the cleaning up of bugs in AnkhSVN has gotten into the RC4 phase. It works considerably better, but still has bugs. I'll be keeping an eye on this one for sure.

Visual SVN - this is a proxy between Visual Studio 2005 and TortoiseSVN, and costs $19. It's not very integrated in the Visual Studio. While AnkhSvn shows status icons on all of the files in solution view, VisualSVN does no such thing. And once you click on Commit or Update or whatever you want, it just opens TortoiseSVN with the requested command. So you still have to work with folders, not projects, and add new project files manually to the repository (AnkhSvn does this from the IDE, although I'm not sure whether it behaved strangely or I don't know how to work with SVN). http://www.visualsvn.com/

PushOK's SVN SCC proxy - this one is a bridge between the Sourcesafe API and SVN, so it looks to Visual Studio just like another SourceSafe. I couldn't get it to work, though: it said there has to be a windows service for making the files under source control read-only (I suppose Visual Studio expects that) and that the service should reindex my files in order for the plugin to work. I let the service do its magic, but nothing happened. The other PushOK's plugin, CVS for VS 2003 worked nicely for me, though, so I guess this is not a general quality issue (come to think of it, I haven't checked if the plugin was VS 2005 compatible at all). Oh yeah, this one is not free but almost: it's around $20. http://www.pushok.com/soft_svn.php

Visual Studio .Net: long-forgotten features

It's an absolute beauty how Microsoft can pleasantly surprise you when you find out that a feature you'd given up long ago has actually started working in a new version. We on the Microsoft platform are humble persons. And we learned to be like that the hard way.

For instance, who other than Microsoft can give you a mail client that doesn't allow you to send or receive any attachment you like? So gradually you give up on even trying to send EXE's, when one day you find out there's a configuration parameter that lets you turn this "feature" off. By then, it's too late, you've already set up your FTP server for sharing files, or whatever ;).

Of course, I'm exaggerating a bit, but it's much worse in Visual Studio world. For example, when you walk through the call stack, does the debugger in VS 2005 display the correct line of code instead of displaying the next one? I haven't noticed: stopped paying attention long ago. Don'trust that mangy debugger no more since the time it used to enter both the if and the else branch (it actually did, in VS 2002).

Hey, there are even new features in this version: press F1 in Visual Studio 2005 and you'll be doomed to biting your nails down to the bone while you watch MSDN explorer reindexing the gigabytes of its documentation for the umpteenth time. I'm stumped as to how they managed to screw up a simple document viewer, at least this should be easy to get right? Nevermind, I'm now using my Firefox for .Net class reference: Google is much better at finding stuff on the MSDN site than MSDN is. I don't know if the MSDN site also reindexes it's contents on every access (it probably does, but they have helluva fast machines there in Redmond, they're high-tech guys). Oh, while we're at it, the MSDN search is one of the dumbest search engines in the universe. I hear they're working on a new super intelligent version. If it will be super intelligent compared to the previous version, then don't bother guys. I'm used to living without it, anyway.

What else is new in Visual Studio 2005. Well... The tool windows sometimes refuse to auto-hide. But that's not new, we had that in VS 2002 beta, only it seemed to have been fixed. How about user-defined controls still not showing up in the toolbox? I don't use the toolbox anymore, just go to the InitializeComponent method and add two lines: new MyControl() and this.Controls.Add(myControl). I don't have time to "Customize toolbox" and wait while VS scans all dll's on my hard drive and do it again when I recompile. Does VS lock the DLL's when you Get Latest from SourceSafe? Glad to say I don't know. I'm using Subversion now. It even has a Visual Studio plug-in which is somewhat buggy (alergic to file renames) but I don't really need it because there's always TortoiseSVN which is great (I'm probably not being fair to Ankh plug-in here, to get something to work right with the Visual Studio add-in API, you need extraterrestrial or para-abnormal capabilities).

So, where's the light at the end of the tunnel? We had Visual Studio 2003 service pack 1 scheduled for june and coming out in august (hopefully), and we had Visual Studio 2005 SP1 scheduled for august (you already guess where this is heading), then scheduled for sometime in the late summer, then not scheduled at all. There's a page at MSDN that says "This service pack is currently targeted for final release in Q3 of 2006. A more detailed schedule of external interim milestones (e.g. customer beta period) will be posted when it has been finalized." Which means there will soon be a beta. Or maybe not. Who cares, by then we'll get used to working without Visual Studio ;).