not_a_generic_user
not_a_generic_user

Reputation: 2178

How can I read and work with Binary values in the Registry using C#?

I'm trying to create a toggle function in C# for enabling and disabling the full view of the Windows Task Manager (because in recent versions they reduced the TM to a useless list of a few programs and no other data).

I found this: https://www.tenforums.com/tutorials/126960-reset-task-manager-default-windows-10-a.html

Which says to delete the following registry key: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\TaskManager

This works to get TM to full view (regular mode), but if I have some psycho that wants it back in minified view, what do I do?

The key has the following two values: enter image description here

When I manually toggle the value in the TM, the only value that changes is Preferences which is a binary value. I can see that it's changing, but I don't know what it's changing to or why. I can try to record the entire binary string and manually put that in my code (before and after), but that seems rather sloppy and prone to error because I have no idea what other data is stored there.

Is there a way to extract binary data to something useful - is it encoded in some way? I already have code to read values, change them, delete them etc, but how do I work with this?

Upvotes: 0

Views: 1534

Answers (1)

Ok so here's is what I did

I opened task manager (Ctrl+Shift+Escape in case you didn't know) and turned the view into "fewer details" and closed task manager.

I opened the registry that you have referenced in the question and once there from File I press Export and export the TaskManager entry as a txt file

Then I went back to the task manager and changed the view to "more details" and closed the task manager once more. To make sure there is no problem with updating the registry, I closed regedit and opened the same location again and exported the entry to a txt file once more.

I compared the files using the Notepad++ compare plugin.

Between the two states of the registry entry there is only 1 bit of difference. Here are the results:

this is for fewer details:

00000000   0d 00 00 00 60 00 00 00 - 60 00 00 00 04 02 00 00  ....`...`.......
00000010   d7 02 00 00 7f 03 00 00 - 4b 04 00 00 01 00 00 00  ×.......K.......
00000020   00 00 00 80 00 00 00 80 - d8 01 00 80 df 01 00 80  ........Ø...ß...
00000030   00 01 00 00 04 02 00 00 - d7 02 00 00 fa 06 00 00  ........×...ú...
00000040   d5 04 00 00 e8 03 00 00 - 00 00 00 00 00 00 00 00  Õ...è...........
...

And this is for more details:

00000000   0d 00 00 00 60 00 00 00 - 60 00 00 00 04 02 00 00  ....`...`.......
00000010   d7 02 00 00 7f 03 00 00 - 4b 04 00 00 00 00 00 00  ×.......K.......
00000020   00 00 00 80 00 00 00 80 - d8 01 00 80 df 01 00 80  ........Ø...ß...
00000030   00 01 00 00 04 02 00 00 - d7 02 00 00 fa 06 00 00  ........×...ú...
00000040   d5 04 00 00 e8 03 00 00 - 00 00 00 00 00 00 00 00  Õ...è...........
...

As you can see the only difference is that 01 becomes 00 in the second file. It is reasonable to assume that that bit toggles whether task manager is in full mode or minimized mode. I do not know how you will read it or write to it in c# per see (perhaps this might help). If you cannot do that as well just comment to this and I will try to help.

Also to confirm that it works, I opened task manager in more details mode, closed it, exported the registry to a reg file. The byte that we wanted to change was 0x00 at that time. I manually changed it to 0x01 in the registry file and imported the registry file. Indeed my task manager turned into fewer details mode. ,

As for the design considerations. Since you only wish to toggle a single preference, when toggling just read the entire value and change the necessary byte. If I counted correctly 29th byte is the byte you want to change but I would count it again myself. Make sure you only change the last bit of that value to 1 (or 0), in which case you can make sure that you are not altering anything else.

Edit 2:

I don't know why you are trying to make things harder or imagine that this process is somehow more complicated than it is. Oftentimes than not these things are pretty straightforward. Everything I have said in the previous edits and the original answer held out to be true.

I created two radio buttons one for minimize one for maximize in a Winforms application and just wrote their relative CheckChanged actions.

Here is the code:

private void MoreDetails(object sender, EventArgs e)
{
    
    if (radioButton1.Checked)
    {
        #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
        #pragma warning disable CS8602 // Dereference of a possibly null reference.
        RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\TaskManager", true);
        byte[] data = (byte[])key.GetValue("Preferences");
        #pragma warning restore CS8602 // Dereference of a possibly null reference.
        #pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type.
        
        if (data != null)
        {
            data[28] &= (byte)0xFE;
            key.SetValue("Preferences", data);
            MessageBox.Show("Set to maximized view");
        }

        key.Close();
    }
}

private void FewerDetails(object sender, EventArgs e)
{
    if (radioButton2.Checked)
    {
        #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
        #pragma warning disable CS8602 // Dereference of a possibly null reference.
        RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\TaskManager", true);
        byte[] data = (byte[])key.GetValue("Preferences");
        #pragma warning restore CS8602 // Dereference of a possibly null reference.
        #pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type.
        
        if (data != null)
        {
            data[28] |= (byte)0x01;
            key.SetValue("Preferences", data);
            MessageBox.Show("Set to minimized view");
        }

        key.Close();
    }
}

I have tried this code and it objectively works, atleast on my system which is a windows 10, every single time.

Upvotes: 1

Related Questions