15
May

Move your user profile to other drive

by Mikael Lundin in Technicalities

Windows has this great functionality that lets you move parts of your user profile to another drive.

Crap, because it only moves the documents and not stuff like Application Data where most of my data is.

Crap.

And you know what? A lot of applications does not recognize that the documents folder has moved.

Dubble crap.

How to really move your user profile

If you’re not comfortable working in the command prompt – don’t try this. You will screw up your computer completely.

The trick is not to leave it to Windows for this low level stuff. Instead you should use a feature within NTFS – directory junction.

Consider why you want to do this. I have a small SSD as my primary hard drive that I run the system on. This was a great decision performance wise. My computer feels very fast because it runs on an SSD. The problem is that 80Gb is not a lot for both system files and user profile. That is why I have a slower, but much larger 1Tb, secondary hard drive (Western Digital Green Caviar) where I want to store my user profile. I’ve postponed this action for far too long and now I have no space left on my primary system drive.

A small side note on running SSD as your system drive: it’s fast but dangerous. Your SSD will fail, sooner or later, and much more often than a mechanical hard drive. That is the price for running a super performant system – you will fail and when you do – make sure that you can restore the system on a new hard drive with just a few clicks. Make sure that is a price you can pay. (continuous automatic backups – Windows Home Server or Synology)

Before you try this you should read other people experiences, because every situation is unique and this story alone will not help you.

My story, how I did it

These instructions worked for me. If they completely screw up your file system, I take no responsibility. That is why your first step should be

  1. Make a complete backup of your file system with some image tool. I recommend Norton Ghost. I have myself a daily image backup of my whole computer through Windows Home Server. That will work too.Copy files to a backup drive will not help you if your file system is shredded to pieces by your failed attempts to create directory junctions. Consider yourself warned!

    (also, you don’t really have a backup until you’ve tried to restore it)

  2. I’ve read a lot of problems with people trying to move their whole C:\Users directory. Don’t do that! It is much easier to just move your profile, so limit the risk and go for that. Move several profiles if you have to.
  3. Your profile contains directory junctions already. For example, your [Profile]\Documents\My Music points to  [Profile]\Music. I’ve not found a way to move these, so they will have to be recreated at the target location. Get a listing of all your current junctions and print it out (on real paper – you will thank me later)
    dir C:\Users\[profile] /al /s
  4. Restart your computer with the windows 7 install cd/dvd. Choose to repair an existing windows installation and choose command prompt as an option.Notice that your first hard drive is not neccessarily C: in here. For me it was E: and my secondary hard drive was D:.  I will name these [source drive] and [target drive] from here on.
  5. Use robocopy to copy the profile from one drive to another. You will read on the internet that you may just create a new user in windows, login as that and move your other user profile with that user. Don’t do that! You will screw up user permissions and sometimes not get all hidden files and folders.Here’s the command that worked well for me. (you may have to create target folder first)
    robocopy /MIR /XJ /B /R:1 /W1 "[source drive]:\Users\[profile] " "[target drive]:\Users\[profile]"
  6. Copying the profile took me 1,5 hours. The result of copy should not give you any failures. If it did, abort right now and find out why before you continue.

  7. Now that have a copy of your user profile on the target drive you need to recreate those junctions that did not copy over. If you run dir "[target drive]:\Users\[profile]" /al /s you will notice that you don’t have any junctions in the target. Damn! Lucky you that you have that printout of what it looked like before.
    mklink /J "[target drive]:\Users\[profile]\Documents\My Music" "[target drive]:\Users\[profile]\Music"
    mklink /J "[target drive]:\Users\[profile]\Documents\My Pictures" "[target drive]:\Users\[profile]\Pictures"
    mklink /J "[target drive]:\Users\[profile]\Documents\My Videos" "[target drive]:\Users\[profile]\Videos"

    … and so on

  8. Cool, now you can remove your old profile. Say what? Yes! Just do it. You don’t need it anymore.
    rmdir /S /Q "[source drive]:\Users\[profile]"
  9. Replace that old user profile with a junction from [source drive] to [target drive] like this.
    mklink /J "[source drive]:\Users\[profile]"  "[target drive]:\Users\[profile"

    Verify by

    dir "[source drive]:\Users\[profile]"

    You should see the files that is now on [target drive].

Reboot and mission accomplished.

12
May

Stylish improves web experience

by Mikael Lundin in Technicalities

I hate advertisement. I would never ever dream about putting advertisement on this blog. I hate it with all my soul, so much that I pay extra for some services just to get rid of the advertisement. I don’t look at commercial TV and I get bored at podradios pausing for a message from sponsors. Ye, I guess that you need sponsors because it is expensive to host a podcast, but I would rather pay 3$ per show just to not listen to your intro, outro or sponsor messages. Pure content – that’s the melody!

Banner advertisment

The Internet is full of these banners that tries to steal focus from the content. I’ve been a fan of Adblock for years, and I also use Flashblock on all my computers. Adblock uses some specialized logic that block ads from known advertisement sources. Flashblock blocks all flash running in the browser.

In Flashblock you have a white list of sites that you want to support flash on, for example TED or InfoQ. All other flash will display a play icon instead, where you can select to make an exception for this site.

This is great if you’re a tab-user like me that easily open up 30-40 tabs every day in my browser. If each would have a flash that would steal CPU, my computer would be doomed.

Style the web with stylish

To take this a step further, there really are some sites that look horrible, because they manage to get advertisement beyond both Adblock and flashblock. What can we do about them?

Stylish is a Chrome plugin that lets you redecorate a plugin by rewriting the css. This gives you full control over the presentation layer on the web.

The cool thing is the gallery where you can download predefined styles created by the community. This way you don’t have to restyle the whole web by yourself. :)

Here’s what a swedish newspaper looks without stylish.

And this is what it looks like after custom styling.

It’s like you’re able to breathe again!

Now, go get stylish from the Google Web Store.

1
May

Deploy Orchard CMS to Azure

by Mikael Lundin in Programming

It’s no secret that I’m working on a replacement for this blog in Orchard CMS, and while doing so, learning to deploy applications to Azure. There is a guide provided by the Orchard Team, but it takes for granted that you’re using Orchard as a plug’n'play CMS and not as a development platform. Here’s a small recollection of my findings.

The Orchard CMS is pointed at the Wordpress audience, comfortable with just installing a blog platform, choose theme, widgets and be up and running without any thought on code, deployment or testing. If you don’t want to author your own theme or write your own modules, you really should download the Azure package and be on your way.

But what if I’m a developer?

Project structure

As a developer I want to have my project setup in Visual Studio. I rename the default Orchard project and add it to a solution together with an Azure deployment project. This is all pretty trivial.

When it comes to compiling you will notice that there are a whole bunch of binaries in the bin-folder that “has to be there”. This is of course to support the xcopy deploy that wordpress people are familiar with (PHP does not have binaries). You should be able to take the package as a whole and dump it on a host to setup your first Orchard site.

I do however want a clean bin-folder that is rebuilt on every compile. How can we accomplish that?

Extract dependencies with NuGet

I use the NuGet package manager to solve out the binary dependencies. Sadly there is no Orchard package yet, but I assume that there will be in the future. Until then we’ll have to sort out the dependencies.

  • log4net 1.2.10
  • SqlServerCompact 4.0.8482.1
  • Autofac 2.2.4.900
  • Autofac.Mvc2 2.2.4.900
  • Iesi.Collections” 1.0.1
  • Antlr 3.1.3.42154
  • Castle.Core” 1.1.0
  • Castle.DynamicProxy 2.1.0
  • NHibernate 2.1.2.4000
  • NHibernate.Linq 1.0

Because you need specific versions of each library, you’ll have to add these through the Package Manager Console (View Menu / Other Windows / Package Manager Console). Example

Install-Package log4net -Version 1.2.10

This leaves us a couple of libraries that are not available in NuGet. I just moved these binaries to the package folder in my solution and referenced them as “Copy Always”. Here’s a complete list

  • Autofac.Configuration 2.2.4.900
  • FluentNHibernate 1.0
  • Orchard 1.1.30
    - Orchard.Core.dll
    - Orchard.exe
    - Orchard.Framework.dll
    - Orchard.WarmupStarter.dll
  • ClaySharp 1.0
  • System.Web.Mvc 3.0
    - Microsoft.Web.Infrastructure.dll
    - System.Web.Helpers.dll
    - System.Web.Mvc.dll
    - System.Web.Razor.dll
    - System.Web.WebPages.Deployment.dll
    - System.Web.WebPages.dll
    - System.Web.WebPages.Razor.dll

Yes, I added the MVC framework as a library, because I don’t know if the host has MVC3 installed in GAC. This would also prevent any collisions with MVC2 because binaries in the bin-folder has precedence over GAC.

The bin folder should now be recreated for you at compilation.

Database deployment

Connecting to your Azure database is easy, just add a firewall rule in Azure and connect with SQL Management Studio using the details available in the Azure management console.

But since we are developers we would like to work locally with functionality in a development database, and deploy to the production database. I prefer to work on a SQL CE4 database, because I can commit the whole thing to source control. This will not scale well with several developers in the team, because the database won’t merge, but as a sole developer I will get the whole database under centralized revision control – and that means a lot to productivity.

The workflow looks like this

  1. Dump your SQL CE4 database
  2. Import into Azure

Easy!

SQL compact toolbox

You should download the SQL compact toolbox and install it. This will allow you to script your entire CE4 database to SQL that will easily be imported into Azure DB.

Azure connection string

But where is that damn database configuration string? I have no idea why, but in App_Data/Sites/Default is a file called Settings.txt that looks like this. I think the reason has to do with the same Orchard instance should be able to host several “sites” with different databases.

Name: Default
DataProvider: SqlCe
DataConnectionString: null
DataPrefix: null
RequestUrlHost: null
RequestUrlPrefix: null
State: Running
EncryptionAlgorithm: AES
EncryptionKey: 471CAA5...
HashAlgorithm: HMACSHA256
HashKey: 54644AEBB...

Before you deploy to Azure you should change it to something like.

Name: Default
DataProvider: SqlServer
DataConnectionString: Server=tcp:[servername].database.windows.net;Database=[dbname];User ID=[username]@[servername];Password=[password];Trusted_Connection=False;Encrypt=True;

Service configuration

There is  nothing strange going on in the ServiceConfiguration.cscfg. At first I copied the one configuration file from Orchard CMS Azure Deployment Guide but it seems to be a bit outdated. I got warnings that my schema was obsolete.

<?xml version="1.0"?>
<ServiceConfiguration serviceName="OrchardCloudService" osVersion="*"  xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="Orchard.Azure.Web">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="DataConnectionString" value="UseDevelopmentStorage=true" />
    </ConfigurationSettings>
    <Certificates />
  </Role>
</ServiceConfiguration>

I changed this to make it a bit more expressive but I have no idea how to get it to conform to the latest version of the schema. I’m still new to Azure and not 100% sure about the configuration, but this works for my website.

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="LiteMedia.Web.Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="LiteMedia.Web" vmsize="ExtraSmall">
    <Certificates>
    </Certificates>
    <ConfigurationSettings>
      <Setting name="DiagnosticsConnectionString" />
      <Setting name="DataConnectionString" />
    </ConfigurationSettings>
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
    <Endpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
    </Endpoints>
    <LocalResources>
      <LocalStorage name="media" cleanOnRoleRecycle="false" sizeInMB="100" />
    </LocalResources>
    <Runtime executionContext="elevated">
    </Runtime>
    <Sites>
    </Sites>
  </WebRole>
</ServiceDefinition>

Speeding up warmup through precompilation

Oh my god! It takes forever to deploy my website! 5 minutes are spent only starting my website. I’ve seen complaints about this all over the Internet. Some have reported that Orchard CMS takes 15 minutes to boot up on a shared host. This is because a lot of the plugins has to be dynamically compiled at startup. If your site have few visitors, it will sleep and restart even more often making your website sluggish. Can we fix this?

Yes, we can extract projects from the Modules folder and statically compile them into the application. There is really no need for them to be dynamically compiled after each application restart.

You really have to look out for not moving out all the files, but only those that will compile into a binary. So, leave stuff like module.txt, web.config and any other resources like images and cshtml.

This will decrease startup time, but you can trim it even more if you ILmerge the modules prior to deploy. Make it a part of your automated build/deploy script and get a lot of startup improvement.

That’s it for now. Hopefully this will help someone in the same position as I am. :)

22
Apr

Discovering JavaScript Patterns

by Mikael Lundin in Technicalities

I opened my mail this Wednesday and discovered that the book I’ve ordered “JavaScript Patterns” by “Stoyan Stefanov” had arrived. To my surprise it wasn’t the concrete brick that I’m used to reading but a lightweight manual on how to improve your JavaScript code. I fell in love instantly.

I work mainly in the backend of websites, with integration and data manipulation, but quite often this requires that I go up in the frontend and make sure that my backend changes are reflected to the user. This has made me an occasionally JavaScripter.

A couple of weeks ago I started thinking about how to improve my JavaScript knowledge, how to test JavaScript and how to architect good JavaScript. Tens of thousands lines of JavaScript will do that to you. I got recommended this book “JavaScript Patterns” by a colleague.

The Review

I know the syntax and I have written quite a lot of code in my days. All I was interesting in was how to improve my JavaScript, how to structure the code and some do’s/don’ts. It’s exactly what this book is about.

I usually read books where the first 50 pages is a “skip” because the author needs to thank his spouse and his sister from his other mother for making it possible to produce this block of concrete, but this book get right to the point and delivers value from page 1.

That makes it very lightweight. (I finished it in 2 days) It only goes into specifics and does not try to teach us the obvious. If you want to learn the basic syntax of JavaScript, you should probably buy a beginners book also.

More tools for the hungry

Three tools that I’m going to take a closer look at.

  1. JsLint
    Tells you whats wrong with your javascript code. Excellent! Works pretty much like FxCop or StyleCop. There’s also a Visual Studio 2010 plugin that will evaluate your javascript at compile time.
  2. YUI Docs
    API Documentation for javascript. I’ve always wondered how I should comment and document javascript code, and now I have a template to follow. Great thing that you can generate API documentation from the source.
  3. YUI Compressor
    I’ve used this before – a tool for minimizing javascript. It can compress it down to about 50% of its original size, which is a real performance boost in page loading.

Watch out you frontend coders! You’re starting to get obsolete when backend specialists gets their hands on literature like this!

20
Apr

UTF8 encoding and Excel CSV

by Mikael Lundin in Programming

Working with WebForms I often use ASHX handlers for generating stuff. It can be anything from XML to CSV.

This is very lightweight and I like it, but today I ran into a problem where I wanted to generate a CSV for Microsoft Excel, but Excel could not recognize the UTF encoding and tried to parse it as ANSI.

Looks like crap because Excel can’t tell that we’re feeding it UTF8. This can be fixed by explicitly giving the file a BOM (byte order mark).

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentEncoding = Encoding.UTF8;
    context.Response.ContentType = "text/csv";
    context.Response.AppendHeader("Content-Disposition", "attachment;filename=data.csv");

    // Start the feed with BOM
    context.Response.BinaryWrite(Encoding.UTF8.GetPreamble());

    var data = new[]
    {
        "Namn;Land;Poäng", // Name;Country;Points
        "Mikael Lundin;Sverige;1200",
        "John Smith;US;800",
        "Jean-Pierre Bordeaux;Française;600"
    };

    foreach (var rows in data)
        context.Response.Write(rows + "\n");
}

The magic happens at line 8 where we explicitly write the BOM to the stream.