Versioning a Multi-Component System

Thursday, 21 January 2010 23:05 by Haemoglobin

1  A lot of the systems that I have worked on have involved more than one component. For example, instead of just an ASP.NET website, there would also be some sort of windows service, maybe a windows forms component, or independent modules and libraries working within those components – all working together to form a final solution.

This tends to create a bit of a versioning and deployment nightmare and you need to have a good solid strategy around it before launching into things. I have tried a couple of approaches.

For one project, I had an automated build script that would go through and modify the version number of all the assemblies, build all the components and label the version from the root in source control. All components would then be redeployed for every release, regardless of whether they have changed or not. This removed human error in deployments as everything was automated, and the deployment steps were always exactly the same for each release so even those could be automated.

This worked pretty well for this project, because there were so many developers that it would have been too time consuming to do a full version to version diff to figure out which components have changed for each release and to deploy only those. Yes there would be release notes on what has changed for each of the components as written by project management or the developer, but that would be reliant on how dutiful Mr developer happened to be at the time, and it’s possible little “tidy” ups were done, or refactorings in components that do not end up appearing on release notes. So one answer is just to test and redeploy everything (this is where automated testing can be very useful also to test for regressions across the system). The only problem with it is you potentially end up deploying a lot of unchanged stuff – albeit just with updated version numbers, all for potentially one small change in one of the components.

For another project – there were far fewer developers, and it was quite easy to just know what components were being changed for each release – so it was possible to just deploy those that were being updated. I came up with the concept of a system version.

Say if you have the following structure in your source control repository for your software solution:

  • MySolution
    • ASP.NET Website
    • Windows Forms Application
    • Windows Service
    • Reporting Services Reports
    • Database Scripts

When you deployed the first version to production, imagine everything was versioned at 1.0.0. All assemblies / exe’s would have been deployed as version 1.0.0 (or using other techniques for database scripts like updating the database version row to this), and the label Version_1_0_0 (or similar) then applied to the MySolution root in source control.

This is in contrast to labelling each subcomponent separately in source control and keeping a configuration management register updated with what versions are deployed where and what versions are all working and tested with what other component versions – uggh.

Now – say that a bug in the windows forms application is reported – it makes sense to just send out a new version of just that, not everything. You make the change, and update the windows forms application’s version to 1.0.1. Now, the solution is is labelled with Version_1_0_1 from the root where 1.0.1 is effectively the new system version. Note however that the rest of the sub-components are still set at version 1.0.0 (literally within the AssemblyInfo.cs classes) – but the 1.0.1 label spans across them, effectively grouping the various current sub-component versions under the 1.0.1 system version umbrella.

Now – lets say a whole lot of work is done across all the different components to create a new feature asked for that will become version 1.1.0. During this time, another small issue is found in production – this time in the windows service. Since we are in the middle of development of version 1.1.0, which is subsequently unstable – we must branch the solution from version 1.0.1 (using the source control branching functionality). Here we make our change to the windows service, update it’s assembly version to 1.0.2 and then label the root of the branch as system version 1.0.2. We then deploy just the windows service to the client.

If we were deploying this solution to multiple clients, who for some reason were running on different versions, you can easily recreate in the development environment the version that they have running in their environment as long as you know their system version. Note that this must be recorded somewhere – but in this case it’s just one number per system deployment, as opposed to a complex set of versions of all the components installed. Pulling that label out of source control will retrieve all the subcomponents in their correct version as deployed for that system version, and consequently retrieve exactly what is running in production for each component.

The only danger with this technique is the possibility of a component being changed (maybe a developer deciding to re-factor some previous work), and not having this component deployed along with the next system version. This would effectively create a mismatch between what is deployed and running on the client’s system and the code associated with that system version in source control. This creates unreproducible bugs and other issues. To solve this, a quick and easy technique should be devised to query source control to see what components have been “touched” since the last release.

I would be interested to hear how others go about versioning in these sorts of situations. I may make a follow up post at some point about database versioning, and UAT deployment techniques.

Categories:   Development
Actions:   E-mail | Permalink | Comments

A List of My Favourite Tools

Saturday, 2 January 2010 12:01 by Haemoglobin

image In August last year – almost at the beginning of this blog I made a post about creating a “Cool Tools” page that will house links to all my favourite tools that I come across and use.

The original blog post suggested that I would be using a Wiki to manage the set of links. Even though I did develop that component in the end (which I may still find use for), my gut feeling said there was something smelly with managing these links in a wiki since I also use Delicious to store links conveniently with the Firefox Delicious Bookmarks extension – and having to then copy items across into a wiki seemed like too much of a pain and a bit of a double up (I’ve learnt that if something isn’t seamlessly easy, human nature is to put it off so much that you end up not doing it at all). 

However, at the same time I wanted to display the list of tools I bookmark in delicious on my website in a nice categorised, hierarchical view… so I got my thinking cap on of how I could have the best of both worlds. After googling around I found that there wasn’t much code out there that converts a set of delicious links with tags into a categorised hierarchy view of them all – so after some sketching I came up with a way to do it (i.e and algorithm to convert tags » hierarchy).

Long story short, my list of tools is finally up and fairly stable (I haven’t been adding huge amounts to the list for the past little while).

You can find it at:

I am also using the same tool (by filtering on a different set of delicious tags) to provide a list of my Favourite Blogs and Favourite Articles.

Each set has their own feed that you can subscribe to if you are interested, or they have a “View by Date Added” button you can use to see what was added since your last visit.

All in all, doing this is part of my “manage information overload” flow (without just shutting it off completely) that I have been trying to fine tune over the last little while which I may blog about at some point – as well as a way to share with the world things I find that I think are good enough to share! 

Categories:   Housekeeping
Actions:   E-mail | Permalink | Comments

Day to day Continual Improvement

Sunday, 27 December 2009 09:58 by Haemoglobin

Lately I have come up with a phrase that I have been experimenting with that I believe is really quite useful to frequently ask yourself.
It is:
“What am I doing, why am I doing it, the way I'm doing it and how could it be done better?”

Try it -- It's amazing how just asking yourself this at times when you least expect asking it will make a difference, makes a difference... you then think of ingenious new ways of doing something that you have been doing for a long time (in a poor way)... or alternatively decide that what you are doing really isn't that important after asking they why part and should possibly just be stopped.

It even stretches to fit with mundane things, you could ask yourself it as you are walking up the stairs and decide running up 3 at a time from now on would be better (or if it's really important to you maybe you might invest in an escalator). Or as you are making your cereal for breakfast you might have a think about it after asking the question and decide from now on that bananas on top from now on would be good for you and probably taste good too.

Stopping yourself as you are dredging through your inbox trying to sort it out... step back, ask how could it be done better, you remember that you can sort by subject or from address..sweet.

Ask yourself when someone's noisy twitter feed keeps popping up and distracting you... why? Well I still want to follow them.... but decide it would be better to download a twitter client that allows you to add that person to a special group that does not show you a popup notification (like TweekDeck).

Or you get annoyed at how you never seem to be able to reach the phone before the answer machine kicks in, actually take the 5 minutes out to find the setting to increase the number of rings instead of just not being bothered to.
 
Maybe you can never find your car keys, you could consider buying a key rack and have it installed by your front door for you to get into the habit of putting them on when you come in. 

Basically a process of continual minor improvements (the Japanese know it as “Kaizen”) - until eventually (over years) you are a sleeked well oiled productivity machine.
The process never stops - but you are reaping the benefits of all the other improvements in the mean time (which are now on autopilot).

This obviously also suits work life at an even more meta scale - applying it to a business process, for example, and of course right down to that portion of code that you are writing (being careful not to get stuck in a continual loop of perfectionism however) - just little chunks, when you can manage it.

A previous Brazillian colleague of mine, Edge, descibes another important thing to do at the end of every day, where you ask yourself:
"What have I done today that I could have done better?".
 
Edge suggests actually writing the answer to this question down which is a good idea as there may be more than one, and items that may need to be fed back into your task list. 

If you asked yourself the first question as often as you could remember (eventually though it just becomes a feeling) and the second question every day, then just imagine the improvements that you will see over time.

Categories:   Personal Development
Actions:   E-mail | Permalink | Comments

Running BlogEngine.NET on .NET 3.5

Sunday, 20 December 2009 12:41 by Haemoglobin

Unfortunately BlogEngine.NET is currently stuck back on .NET 2.0 due to a few lingering web hosts still not supporting .NET 3.5 yet.
Here is a comment made from Ben Amada, a BlogEngine.NET developer:

I agree, we can gain from using the new features in .NET 3.5.  You may or may not be aware that the BE core project has already been upgraded to .NET 3.5.  Some of the new .NET 3.5 compiler level features are being used -- but new namespaces such as Linq (and probably the Syndication namespace too) are not yet being used.  The website project is still on .NET 2.0.  Probably sooner than later, the website project too will be upgraded to .NET 3.5.

I think the main reason it hasn't yet been upgraded is because there are some BE users hosting their sites at webhosts that don't yet offer .NET 3.5.  The core project is at .NET 3.5, but because none of the new 3.5 namespaces are being used, the compiled core DLL can still be used in a .NET 2.0 environment.  At this point, I think just automatic properties and lambdas are being used in the core project (compiler level features).

Hopefully as the number of webhosts not offering 3.5 gets fewer and fewer, the website project too can be upgraded to .NET 3.5.

~~ BenAmada

 

If you want to write a user control or widget however in .NET 3.5 now for your BlogEngine.NET site (which I have needed to do) – it is relatively simple to do. All you need to do is modify the web project’s web.config slightly, you can see the changes that you need to make here:

The above diff was created using the report export functionality of WinMerge. p.s I wouldn’t normally recommend posting your web.config files to the web but in this case there are no “secrets” there.

General Tip:
In terms of making substantial modifications to your BlogEngine.NET instance (if you are in the habit of doing this, not necessarily just for this web.config change) – I recommend being connected to the BlogEngine.NET subversion repository (https://blogengine.svn.codeplex.com/svn) using TortoiseSVN. Now you can track any modifications that you make as Tortoise will flag the file as modified. Subversion will also attempt to automatically merge any further changes to the file that come from the BlogEngine.NET developers when you do an update, you of course won’t be able to submit your changes back unless you are part of their team. After doing the SVN update you can also monitor the changed files that come across and subsequently upload them to your web instance. Depending on if you are a risk taker or not, you may only want to do this when they mark a particular revision for a stable build.

Categories:   BlogEngine.NET
Actions:   E-mail | Permalink | Comments

Enabling Disqus Comments in BlogEngine.NET

Saturday, 28 November 2009 16:29 by Haemoglobin

Recently, I have switched across to using Disqus as the comments system on my blog instead of the inbuilt BlogEngine.NET comments.

Immediate benefits are:

  1. Threaded conversation (i.e you can reply to someone’s comment directly).
  2. Identify yourself with your Facebook or Twitter account (by logging in safely directly to the Facebook and Twitter sites respectively).
  3. If you subscribe to the comments conversation by email – you can use email to leave replies to comments on the website.
  4. Lets you keep track of comments you make across the blogosphere on all sites that use Disqus.
  5. As the owner of the site you can moderate directly from email notifications (i.e by replying with “Delete”). This makes moderation easy when out on the road.
  6. Generally looks sleek + many other reasons for using it (link#1, link#2, link#3).

I love comments so feel free to leave any and try the new system out!


Now, for the benefit of anyone using BlogEngine.NET who wishes to do this also, continue reading and I’ll outline the steps I took to do it:

  1. Create an account at http://disqus.com
  2. For Facebook integration, get your Facebook connect API key from http://developers.facebook.com/setup.php (you will also be asked to upload a xd_receiver.htm file to the root of your website).
  3. If you wish to use Akismet spam protection, use your Wordpress account API key located here http://dashboard.wordpress.com/wp-admin/profile.php (in small text at the top of the page)
  4. Within Disqus, under Settings –> General –> “Cross-domain Receiver URL” it describes an advantage to upload a blank.htm file to the root of your website and pointing to it.
  5. Under Settings –> Customize, change from the new Narcissus theme to either of the Classic ones. I found that the new Narcissus theme’s Reply and Edit buttons on a comment did not work for me as they initiate a post back and the AJAX action is lost. After some FireBug debugging I found that this simply because the buttons do not contain a “return false;” on their onclick events (works fine when I manually add this in using FireBug). I have sent an email to Disqus about this but as of yet have received no reply.

I made the following alterations to various files in my BlogEngine instance (note that some alterations are made to core BE.NET files themselves which is going to make upgrading BE.NET more of a pain but I believed it would be easy enough to integrate again if it was documented well enough, i.e here):

  1. Retrieve the second code snippet from http://disqus.com/comments/universal and add it to the “Tracking script” section of the BE.NET settings tab.
  2. Modify /theme/MyTheme/PostView.ascx, removing any html referencing the BE.NET comment system and replacing it with:
    <a rel="nofollow" href="<%=Post.PermaLink %>#disqus_thread">Comments</a>
  3. In the main /post.aspx change the visible property of the CommentView control to false:
    <uc:CommentView ID="CommentView1" runat="server" visible="false"/>
    And add the following: Yours will vary slightly, your version can be retrieved from the first snippet at http://disqus.com/comments/universal. Note the commented out disqus_developer variable, this can be uncommented to test the system on your local machine before deploying.
  4. Find the comments variable in /widgets/RecentPosts/widget.ascx.cs and replace the line with: While I was there, I also added a "Read more..." link that links to the archives page (which I think should be there): I do not use the RecentComments widget hence did not have to modify this - it would need to be however if it was used.
  5. Inside /archive.aspx.cs locate the comments.InnerHtml variable of the CreateTableRow method and replace it with: Note even though you can change what Disqus replaces the text with here by going to the Settings->Customize->Appearance Tab on your Disqus account, this is a global action across your site. Normally the archive page just has a number for the comments, not the "Comments" text itself so I had to modify my theme’s css a bit to accommodate the extra width required in this column.

That’s it :) Looks more daunting in hindsight actually. It would be much nicer if BE.NET had Disqus integrated into the standard build as an option.

Oh, and one more thing, something I have always wanted, comments on BE.NET pages. With the default BE.NET commenting system this is not possible, but with similar Disqus modifications, it is possible to have Disqus comments on your BE.NET pages also :)

Here are the steps I took to enable this:

  1. Add the following lines under the AdminLinks section of \page.aspx: Once again, yours will vary slightly and can be retrieved from the first snippet at http://disqus.com/comments/universal. There is a little bit of extra code here to make the comments appear only after the link is clicked (for tidyness sake). This is not necessary though.
  2. Add the following property to \page.aspx.cs:

And enjoy :)
Hamish

Categories:   BlogEngine.NET
Actions:   E-mail | Permalink | Comments

Monitoring ADSL Drop Outs

Wednesday, 18 November 2009 00:10 by Haemoglobin

At home we have previously had issues with our ADSL dropping out intermittently and have had the ISP send technicians around to fiddle test and rewire etc. This seemed to make a difference for a good while, but as of the last two days we are back to square one with frequent and annoying ADSL disconnections (no changes to anything in the house).

What I’m afraid of doing now is ringing the ISP again and being told the standard “restart the router”, “pull all the phones out of the wall”, “turn the oven off”/”Pray to the Gods” etc etc, all of which I know most likely has nothing to do with it (tried it all before).

I decided to do my own internet research for reasons why ADSL might drop out. I learnt all sorts of interesting things about noise margin’s, line attenuation, data sync rates etc that all have an impact on how stable the line is.

Checking my Belkin router’s status page, I note that it actually gives me this information - cool:

image

Of course, I start rapidly refreshing the page to see how the numbers are changing as the ADSL internet connection drops in and out. The Data rate is different on each reconnect, and the noise margin is fluctuating all over the place.

Refreshing is no good, tonight I decided that this goodness needed to be graphed!

Window’s inbuilt performance counters are ideal for this sort of thing. We just need a custom performance counter for the ADSL connection data, poll the router’s status page and feed the new performance counter with data.

I fired up Visual Studio and started plugging away at a windows app that will do this for me – easy to do – behold the ADSL Monitor:
image

The following code creates the new ADSL performance object, with the four counters I’m interested in (noise margin up/down and data rate up/down):

 

CounterCreationDataCollection counters = new CounterCreationDataCollection();

counters.Add(new CounterCreationData("Noise Margin Down", "Noise Margin Down", PerformanceCounterType.NumberOfItems64));
counters.Add(new CounterCreationData("Noise Margin Up", "Noise Margin Up", PerformanceCounterType.NumberOfItems64));
counters.Add(new CounterCreationData("Data Rate Down", "Data Rate Down", PerformanceCounterType.NumberOfItems64));
counters.Add(new CounterCreationData("Data Rate Up", "Data Rate Up", PerformanceCounterType.NumberOfItems64));

string _performanceCategory = "ADSL"; 

if (PerformanceCounterCategory.Exists(_performanceCategory))
{
PerformanceCounterCategory.Delete(_performanceCategory); 
}

PerformanceCounterCategory.Create(_performanceCategory, "ADSL Diagnostics", PerformanceCounterCategoryType.SingleInstance, counters);

 

I then fire off a thread and have it looping over the following every second:

	           
	while (running)
	{
		WebRequest request = WebRequest.Create("http://192.168.2.1/status.stm");
		WebResponse webResponse = request.GetResponse();
		StreamReader stream = new StreamReader(webResponse.GetResponseStream());
		string statusPage = stream.ReadToEnd();
		stream.Close();
		webResponse.Close();

		//Providing data to the performance counter 
		PerformanceCounter pc = new PerformanceCounter(_performanceCategory, "Noise Margin Down", false);
		pc.RawValue = Convert.ToInt32(GetDataResult(DataMatch.adsl_noise_margin_ds, statusPage));
		...

		Thread.Sleep(1000); 
	}

A simple Regex is used in GetDataResult to pull the appropriate data off the router’s status page.

Now, browsing to the inbuilt windows Performance Monitor, we can add our newly created ADSL performance object and graph what is really going on. For me, it was looking like this:

image

What the ! !  It seems more than half the time I’m without internet. The most important lines I believe are the blue and red. The blue shows the synced data downstream rate (higher the better), and the red shows the downstream noise margin (once again, higher the better – apparently anything below 6 is quite unstable).

Where the blue line is at rock bottom is where I don’t have any internet at all. What a pain – as you can see towards the end it started to stabilise with quite a high noise margin, albeit a low data rate :(
This will hopefully give me more information to provide the ISP however when I finally do ring as well as letting me monitor the situation and not even bother surfing the internet while it is ridiculously unstable.  

Sigh.

Categories:   Development
Actions:   E-mail | Permalink | Comments

ObjectDock/xplorer² Locking USB Drive

Saturday, 17 October 2009 21:18 by Haemoglobin

For a while now I’ve been getting frustrated with hardly ever being able to safely remove my external USB HDD, as it was always “in use” even after closing as many applications as I could think of. However, using LockHunter (great tool) reveals the following information:

imageimage_1

Trying to safely remove the device at this point of course gives the following message:

image_2

The first two items are windows handles that do not interfer with the safe removal process – the second two however do.

I have enjoying my use of xplorer² (lite) as a windows explorer replacement that makes life a lot easier when doing a lot of file system maintenance. However, if the last folder you have open with it was on the USB drive, then the process stays alive even after “closing” the xplorer² window (probably for faster reloading?), keeping a hold of the drive in the process. I have found that the following option however fixes this issue (if you don’t tend to use the DOS functionality):

image_3

 image_4As for ObjectDock as far as I can see the only solution to this is not to have the Recycle Bin docklet on the dock – I guess I will just have to live with it being on the desktop for now.

Sometimes it pays to just take a bit of time out to sort out the things that can frustrate you daily and you will be much better off :)

Categories:   Technology
Actions:   E-mail | Permalink | Comments

Welcome Microsoft Security Essentials

Saturday, 3 October 2009 12:03 by Haemoglobin

Based on the general difficultness of locating the free version of AVG (not actually mentioned on www.avg.com - only on the secret http://free.avg.com), along with the nags for upgrading to the professional edition – and finally following the pcworld review comparing AVG Free to MS Security Essentials, I’ve made the switch!

It seems MS Security Essentials was even coming out on top in the comparison.

It seems more lightweight and fast too, and it's free – nice. If you wish to download it you can get it from here.

Categories:   Technology
Actions:   E-mail | Permalink | Comments

How Twitter @Replies Work

Tuesday, 14 July 2009 01:42 by Haemoglobin

It seems that the way twitter replies work have changed since a bit since I read this post a while ago. There are now no longer options to display what sort of reply volumes show up on your home page.

I did a cursory look around the internet for how things currently work including twitter’s own help but couldn’t find much that explains what happens in many cases. So I thought I would do some tests using a second account so I would know for sure.

Here are my findings. We will do this with two people, PersonA and PersonB.

First of all, here are a couple of things taken from the Twitter help pages that are good to know:

Following is not necessary to reply to someone, and all of your replies are visible in the @username tab in your home page sidebar.
If your account is protected, we assume that you only want your followers to see your updates. @replies sent to people who aren't following you will not be seen.  If you want to interact with everyone on Twitter, you should not protect your account.
You can only send a direct message to a person who follows you.
Your home page shows replies made by people you follow to people you follow.
Any tweet beginning with @username is considered a reply.  We call tweets with @username elsewhere in the update mentions.

Wow - what a mish mash, I had to try a few things out myself just to clear it up a bit.

Note that replies and mentions are treated slightly differently, as you will see in the following examples.

Now, I'll show you what I ran through for my testing that should hopefully cover most scenarios I could think of..
Note that for the avid twitter user you will likely already know all these... I still learnt a couple of things though which was good to know.

Lets get started. The Yes / No shows where the message will appear:
Person A and Person B not following each other.
Person A
has a private account.

PersonA PersonA Profile PersonB Profile PersonB Home @PersonB Replies Comments
Hello World ! Yes No No No Obviously.
@PersonB Hey – Just “replying” to you.
Yes No No No Your replies and mentions will not make it to people who don’t follow you if your account is private. You are talking into thin air :) Did you know that? In hindsight it seems I have sent a few into thin air :) Whoops.


PersonA now makes their account public

@PersonB Ok – how about now? Yes  No No Yes If your account is public, your replies and mentions will still go to people who don’t follow you, but only if they look at their reply/mentions section on twitter.com. HOWEVER, at the time of testing the Thwirl and Digsby clients seemed to still show these on the main homepage. Blu on the other hand would only show these in its Replies area. I’d probably prefer it on the homepage myself since I’m don’t to check the Replies section much (maybe you would need that separation though if you were a major celebrity or to fight against general spam for that matter).
d @PersonB Sending you some direct message spam! No No No No Actually – this results in an error for PersonA saying you must follow PersonB before sending a DM.

PersonB now follows PersonA

Hello World ! Yes No Yes No After the follow the PersonA’s updates are now visible on the home page of PersonB (we all know that one).
@PersonB Thanks for the follow. Yes No Yes Yes Replies and mentions will show up in PersonB’s home page as well as the Replies area since they are now following PersonA.
@SomeoneElse Hello someone else. Yes No No No If @SomeoneElse is a valid user but PersonB does not follow them, PersonB won’t see this post on their home page.
Hey @SomeoneElse howsit going? Yes No Yes No Aha – and here is the difference between a reply and a mention – PersonB will see this on their home page even though they don’t follow @SomeoneElse. 
@NonexistantUser Hey non existant user. Yes No Yes  No Whoops – PersonA probably mistyped someone’s username, if this @NonexistantUser isn’t a valid username, this message will actually appear on PersonB’s home page… Interesting find? My guess is in this case it isn’t treated as a reply but takes on the behaviour of a mention of Mr Non-Existant.

PersonB now follows PersonC

@PersonC Hey man – how are you? Yes No Yes No PersonB will see on their home page replies PersonA sends to people they follow.
@PersonC @PersonB Hey guys – you are both cool. Yes No Yes Yes This will also appear in the PersonB reply/mention area. Note that the @PersonB part can exist anywhere in the tweet with the same effect.
@SomeoneElse @PersonB Hey someone else, and B. Yes No Yes Yes Even though this was a reply to someone PersonB doesn’t follow, it will still appear for them because they were mentioned (as you would expect). 
@SomeoneElse Hey someone else and @SomeoneElseAgain Yes No No  No This is treated as as valid reply to @SomeoneElse. Hence only @SomeoneElse and @SomoneElseAgain will receive this message (either just in their replies tab or on their home page depending on if they are following PersonA).  
@NonexistantUser @SomeoneElseAgain Hey Mr No-One. Yes No Yes No OK – as before, this one has sort of flipped to mention mode because of the invalid user to begin with (even though the second user was valid), so this will be visible on PersonB’s homepage and any anyone else following PersonA for that matter.

 

If you think of any other scenarios I might have missed that are interesting or if any of these are incorrect please let me know and I will update it :)

Happy Tweeting :)
Hamish

Categories:   Technology
Actions:   E-mail | Permalink | Comments

My Documents - I give in

Thursday, 9 July 2009 21:45 by Haemoglobin

Ok - I'm over applications littering my "Documents" folder with their stuff. For example the automatically created Visual Studio folder, MSN Received files folder, digsby chat history folders, and user settings and files of numerous other applications that chose to put folders in there!

Yes, in each case, which I have been doing, it is possible to change the location of these - sometimes through hacking the registry or fiddling with a config file, but it really is an uphill battle.. so yes, I officially give in :|

Applications, you may use my "Documents" folder all you want now, because I am no longer using it - I have abandoned it for my own "My Files" folder where I can look for things without having to navigate around random application folders. It's like clothes from yesterday (last week / last month - depending on who you are) on the floor that annoy you every time you see them, but you never really do anything about). Now they can have their very own washing basket to play in.

Tags:  
Categories:   Technology
Actions:   E-mail | Permalink | Comments