Metro Style Toggle for Windows 8 Developer Preview

imageUPDATE – Classic Start Menu was removed completely from Windows 8 Consumer Preview. This application will not work any more. Download link was removed.

I have been running Windows 8 Developer Preview for a while now. Since my laptop does not support touch, I am using the new Metro style Start menu with Mouse and Keyboard. Honestly, it rocks on touch! but I prefer the classic Start menu of Windows 7.

I surfed the web for a while looking up a way to disable the new metro Start menu and use the classic Windows 7 instead. Many websites pointed out that it is controlled through the Windows Registry under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer using the Value of RPEnabled. Metro’s value is 1 and classic Windows 7 is 0.

I decided to ease the toggle by writing an application (called it “Metro Style Toggle”) that updates the RPEnabled registry value. In this post I will share how I managed to read/write Windows Registry values to switch between the shell styles.

To quickly summarize the code:

  • Read the RPEnabled Registry value using Microsoft.Win32.Registry.GetValue and reflect the state on the UI by updating the status label and disabling the current status toggle button. So for example, if the current status is Metro, then the Metro toggle should be disabled.
  • When the user toggles the state, I use Microsoft.Win32.Registry.SetValue to update the RPEnabled Registry value. So for example, If the user wants to switch back to Metro, then RPEnabled should be updated to become 1.
  • An alert is displayed to the user asking them to restart their machine for changes to take effect.

I wrote the code to run on the Windows 8 Developer Preview, I have no clue if it will run on the Beta or RTM releases. Furthermore, you have to run this application as an Administrator, otherwise it will fail to update the Windows Registry (It worked with me without Administrative privileges, maybe because I am the administrator Winking smile, still better to run it as Administrator). Please note that Windows might ask you to install Microsoft .NET Framework 3.5 with SP1 using the Windows Features Activation if you have not activated the runtime yet.

If you are not a developer or not interested on how I built the Metro Style Toggle, you can skip the rest of the post and download the application.

Metro Style

image

Classic Windows 7 Style

image

The easiest way for me to explain the source code was to comment on it and paste it here. So for you geeks who are interested in the source code let’s start digging:

    1:  using System;
    2:  using Microsoft.Win32; 
    3:  //Used for Registry.GetValue() and Registry.SetValue() - Lines 78 and 88
    4:  using System.Windows.Forms;
    5:  using System.Diagnostics; 
    6:  //Used for Process.Start() - Line 134
    7:   
    8:  namespace MetroStyleToggle
    9:  {
   10:      public partial class ToggleControl : Form
   11:      {
   12:          public ToggleControl()
   13:          {
   14:              InitializeComponent();
   15:          }
   16:   
   17:          enum ShellStatus { Metro, Classic, Unknown }
   18:          ShellStatus currentShellStatus;
   19:          string registryPath = @"HKEY_CURRENT_USER\Software\Microsoft\
   20:                                  Windows\CurrentVersion\Explorer",
   21:              registryValue = "RPEnabled";
   22:          string metroStyle = "1", classicStyle = "0", currentKeyValue = "", 
   23:              restartMessege = "Restart needed for updates to take effect.";
   24:   
   25:          private void ToggleControl_Load(object sender, EventArgs e)
   26:          {
   27:              SetShellStatusMessege();
   28:          }
   29:   
   30:          private void SetShellStatusMessege()
   31:          {
   32:              //Get the current shell style state from Windows Registry and 
   33:              // store it inside currentKeyValue
   34:              //You will find more explination about the GetRegistryValue function
   35:              // whereabouts below
   36:              currentKeyValue = GetRegistryValue(registryPath, registryValue);
   37:              //Maintain the current shell style state
   38:              SetShellStatus(currentKeyValue);
   39:              //Update the shell status label with the current shell style state
   40:              ShellStatusMessege.Text = currentShellStatus.ToString();
   41:          }
   42:          
   43:          private void SetShellStatus(string status)
   44:          {
   45:              if (status == metroStyle)
   46:              {
   47:                  //Set the shell style state to Metro
   48:                  currentShellStatus = ShellStatus.Metro;
   49:                  //Disable the MetroToggle button
   50:                  MetroToggle.Enabled = false;
   51:                  //Enable the ClassicToggle button
   52:                  ClassicToggle.Enabled = true;
   53:              }
   54:              else if (status == classicStyle)
   55:              {
   56:                  //Set the shell style state to Classic
   57:                  currentShellStatus = ShellStatus.Classic;
   58:                  //Enable the MetroToggle button
   59:                  MetroToggle.Enabled = true;
   60:                  //Disable the ClassicToggle button
   61:                  ClassicToggle.Enabled = false;
   62:              }
   63:              else
   64:              {
   65:                  //Set the shell style state to Unknown
   66:                  currentShellStatus = ShellStatus.Unknown;
   67:              }
   68:          }
   69:   
   70:          public string GetRegistryValue(string path, string value) 
   71:          {
   72:              //Return the Windows Registry value using the Path set in 
   73:              // registryPath and registryValue
   74:              //registryPath value is 
   75:              // HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer
   76:              //registryValue value is RPEnabled
   77:              //If the key does not exist, the return value will be "Unknown"
   78:              return Convert.ToString(Registry.GetValue(path, value, "Unknown"));
   79:          }
   80:   
   81:          public void SetRegistryValue(string path, string value, string shell)
   82:          {
   83:              //Write to Windows Registry using the Path set in registryPath and registryValue
   84:              //registryPath value is 
   85:              // HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer
   86:              //registryValue value is RPEnabled
   87:              //shell contains either 0 for Classic Windows 7 Style or 1 for Metro Style
   88:              Registry.SetValue(path, value, shell);
   89:          }
   90:   
   91:          private void MetroToggle_Click(object sender, EventArgs e)
   92:          {
   93:              try
   94:              {
   95:                  //Set the shell style state to Metro, metroStyle was set to 1
   96:                  SetRegistryValue(registryPath, registryValue, metroStyle);
   97:                  //Update the status label
   98:                  SetShellStatusMessege();
   99:                  //Alert the user to restart their machine
  100:                  MessageBox.Show(restartMessege,this.Text, 
  101:                      MessageBoxButtons.OK, MessageBoxIcon.Warning);
  102:              }
  103:              catch (Exception ex)
  104:              {
  105:                  //Capture the error and push it to the status label
  106:                  ShellStatusMessege.Text = "Error: " + ex.Message;
  107:              }
  108:          }
  109:   
  110:          private void ClassicToggle_Click(object sender, EventArgs e)
  111:          {
  112:              try
  113:              {
  114:                  //Set the shell style state to Classic, classicStyle was set to 0
  115:                  SetRegistryValue(registryPath, registryValue, classicStyle);
  116:                  //Update the status label
  117:                  SetShellStatusMessege();
  118:                  //Alert the user to restart their machine
  119:                  MessageBox.Show(restartMessege, this.Text, 
  120:                      MessageBoxButtons.OK, MessageBoxIcon.Warning);
  121:              }
  122:              catch (Exception ex)
  123:              {
  124:                  //Capture the error and push it to the status label
  125:                  ShellStatusMessege.Text = "Error: " + ex.Message;
  126:              }
  127:          }
  128:   
  129:          private void BlogLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  130:          {
  131:              //Launch the user's default browser and browse to my blog URL. 
  132:              //BlogLink is a LinkButton and it's Text property 
  133:              // is set to https://blogs.msdn.com/balsharfi
  134:              Process.Start(BlogLink.Text);
  135:          }
  136:      }
  137:  }

Well, that’s it Smile