Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Rename Start Button

3.26/5 (96 votes)
11 Feb 2008CPOL6 min read 18   1.5K  
An article describing how to rename the Start button programmatically.

Image 1

Contents

Introduction

Have you ever wanted to change the text on Start button? If yes, you probably know that in order to do that, you will need a hex editor, digging in the Registry, and a resource editor. Using the code presented here, you can rename your Start button text with just one click. No more Registry editing, hex editors, and resource editors. Everything is done for you with just one click! What's more, you can rename the Start button either for the whole system or for the current user only. Even Unicode is supported, so now your Start button can look like this:

Image 2 Image 3 Image 4

Image 5 Image 6 Image 7

Note: This program has been tested only on Windows XP SP2 with the XP-style Start menu, so if you are using a different version of Windows and/or have the Classic menu, it might not work.

Background

I was interested if start button text could be changed. So I googled and found this: Change Text on XP Start Button. I tried it and it worked. The disadvantage of that method is that for every change you should recompile explorer.exe and make changes to the registry. So I decided to write a program that would do all that for me.

How the Start button text is changed

Technical part

The string which defines the text of the Start button is hard-coded in explorer.exe. If you use a hex editor and navigate to the address 0xF60A4, you will see something like this:

Image 8

Notice the string "start". Using the method described in the above link, I changed the Start menu text to "12345". When I opened it in a hex editor and navigated to the same line, I found the string "12345" instead of start, as I had expected. However, when I used the file comparison tool of the hex editor, it revealed 239 differences. That was too much. Then, I changed the Start button text to "54321". When I compared these two custom explorers, I found only three differences. This was a better result. So, I decided to write a program that would read everything up to string "12345" from the custom explorer.exe, then append the new text for the button, and then append everything remaining. I tried it, and it worked, but there was one problem to deal with.

Cracking the five character limit of the Start text

Overcoming the five character limit of the Start text was a little bit problematic, but I found a tricky way. The problem is that as you can see from the picture above, immediately before the string "start" in explorer.exe, there is a byte with a value 5, and it defines the length of the Start button's text. You might think that you would change it to 6 and then insert a 6 character long text, but it just won't work. Even worse, when you start Windows, the taskbar will look very ugly, and everything will be upside-down. The problem is that when you insert a 6 character long text, you insert two extra bytes. To overcome this, you will have to remove two bytes, but how do you know which two bytes to remove? Also, what if you wanted a 7 character long text? Or 8? Or 9? Or even 20? In that case, you will need to remove 4 extra bytes, 6 bytes, 8 bytes, or 30 extra bytes. How do you know the address of the bytes to remove? To find out that, I used a resource editor and changed the text on the Start button to various length strings and examined the generated explorer.exe. I wanted to find the pattern in the address of the bytes to remove. But, there was a problem. The pattern wasn't obvious, and even if there had been a pattern, it would not be easy to implement. The only way was to find a trick. After several days, an idea came to me, and it worked.

The trick

The trick is very simple. I changed the Start button text to 12345678901234567890 using the resource editor. The compiled explorer.exe didn't contain the extra 30 bytes, and it worked well. The value of the byte before the string "12345678901234567890" which shows the length of the text was 20. I decided to change this byte and leave the text untouched. I change it to 5 and it worked! The Start button displayed "12345". So, explorer.exe was fooled. It doesn't pay attention to the text which goes over the length, defined by the byte immediately before the text.

Registry changes

After the new explorer.exe has been generated, you need to make changes to the Registry. If you navigate to the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon, you will see a string there called Shell, and its value is equal to explorer.exe. My program sets its value to the path of the new explorer.exe. But, this will change the default shell for every user. To make it possible to change the Start button text for the current user, you will need to change the shell for the user who is logged in. So, we need to change Shell at HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Winlogon. However, you will discover that there is no such string. To solve the problem, I created such a string and set its value to the path of the custom explorer.exe, and it worked. The Start button text was changed only for my user.

Programming part

What my application does is quite simple: It just creates a new Explorer, but the string "12345678901234567890" is replaced by the text the user submits, and the new length is inserted before the string. The creation process is quite simple. Firstly, a file which contains everything before the string "12345678901234567890" and its length (this file is called begin.exe in the solution folder) is copied to the destination folder, and the length of the user submitted text is inserted. Secondly, the new string is appended. If the length of the new string is less than 20, then the remaining number of characters is inserted, which won't be displayed on the button, and then the remaining lines of explorer.exe are appended from the second file (this file is called end.exe in the solution folder). After creating a new Explorer, the application makes changes in the Registry and displays a message box informing the user about the work done. If the user chooses to, the application will restart Windows, which is necessary for the changes to take effect.

Restarting Windows

In order to restart windows, I used the WindowsController class from here. This class allows you to shutdown, restart, or log a user off.

Using the code

Here is the function that does the renaming and changes to the Registry. As you can see, it takes the new text for the Start button as a parameter. The getpath() function returns the destination path for the new Explorer depending on the user's choice and the present location of explorer.exe.

C#
private bool rename(string newname)
{

    if (!File.Exists("begin.exe") || !File.Exists("end.exe"))
    {
        MessageBox.Show("Source files not found", 
                        "error", MessageBoxButtons.OK, 
                        MessageBoxIcon.Information);
        return false;
    }

    string explorerpath = "";
    windir = Environment.GetEnvironmentVariable("WINDIR");
    appdata = Environment.GetEnvironmentVariable("AppData") + 
                                                "\\start button rename";

    try
    {
        explorerpath = getpath();

        if (File.Exists(explorerpath + "\\explorer.exe"))
        {
            File.Delete(explorerpath + "\\explorer.exe");
        }

        //Copy beginning of custom exe to the destination folder
        File.Copy("begin.exe", explorerpath + "\\explorer.exe"); 

        FileStream outstr = new FileStream(explorerpath + 
            "\\explorer.exe", FileMode.Append, FileAccess.Write, FileShare.None);
        BinaryWriter outbr = new BinaryWriter(outstr);

        //Insert new length
        outbr.Write((short)newname.Length);

        //Insert new text
        byte[] input = Encoding.Unicode.GetBytes(newname);
        outbr.Write(input);

        //Insert some text that won't be displayed
        for (int j = 0; j < 20 - newname.Length; j++)
        {
            outbr.Write((short)j);
        }

        //Append end of custom exe
        FileStream infs = new FileStream("end.exe", FileMode.Open, 
        FileAccess.Read, FileShare.None);
        BinaryReader inbr = new BinaryReader(infs);

        for (int i = 0; i < 1620; i++)
        {
            input = inbr.ReadBytes(16);
            outbr.Write(input);
        }

        input = inbr.ReadBytes(2);
        outbr.Write(input);

        inbr.Close();
        infs.Close();
        outbr.Close();
        outstr.Close();
    }

    catch (IOException)
    {
        MessageBox.Show("Error during accessing files", "error", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
    }

    catch (Exception)
    {
        MessageBox.Show("Unkown error", "error", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
    }

    //Make changes to the registry
    try
    {
        Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT"+
        "\\CurrentVersion\\Winlogon", "Shell", "");

        if (skinRadioButton1.Checked)
        {
            Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT"+
            "\\CurrentVersion\\Winlogon", "Shell",explorerpath + "\\explorer.exe");
        }
        else
        {
            Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT"+
            "\\CurrentVersion\\Winlogon","Shell", explorerpath + "\\explorer.exe");
        }
    }

    catch (System.UnauthorizedAccessException)
    {
        MessageBox.Show("Error accessing registry", 
                        "error", MessageBoxButtons.OK, 
                        MessageBoxIcon.Error);

    return false;
    }

    catch (System.Security.SecurityException)
    {
        MessageBox.Show("Error accessing registry. Make sure you have enough rights.",
                        "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
    }

    return true;
}

As you can see, the changes to the Registry are made according to the user's choice.

Points of interest

In order to display & on the Start button, you will have to type &&. Thanks Nishant Sivakumar for the comment.

History

  • 1 June, 2007 - Initial release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)