'How to set account's picture in Windows 10

I want to set the account's picture through my C# program, but I can't find any API to set it.

So I try to set it by generating a accountpicture-ms file then apply it by changing the registry. However, Windows can't read the file that generated by my program. This is my code to generate accountpicture-ms file.

private static readonly byte[] ACCOUNTPICTURE_MS_HEADER = new byte[] { 0xB2, 0xF9, 0x00, 0x00, 0xAE, 0xF9, 0x00, 0x00, 0x31, 0x53, 0x50, 0x53, 0x18, 0xB0, 0x8B, 0x0B, 0x25, 0x27, 0x44, 0x4B, 0x92, 0xBA, 0x79, 0x33, 0xAE, 0xB2, 0xDD, 0xE7, 0xD5, 0x0C };
private static readonly byte[] FIRST_PICTURE_HEADER = new byte[] { 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x34, 0x00, 0x32, 0x00, 0x39, 0x00, 0x34, 0x00, 0x39, 0x00, 0x36, 0x00, 0x37, 0x00, 0x32, 0x00, 0x39, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0x0C, 0x00, 0x00 };
private static readonly byte[] SECOND_PICTURE_HEADER = new byte[] { 0x00, 0x00, 0xBD, 0xEC, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x34, 0x00, 0x32, 0x00, 0x39, 0x00, 0x34, 0x00, 0x39, 0x00, 0x36, 0x00, 0x37, 0x00, 0x32, 0x00, 0x39, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xEC, 0x00, 0x00 };

public static byte[] CreateAccountPicture(Image avatar)
{
    Bitmap avatar96 = Utils.ResizeImage(avatar, 96, 96);
    MemoryStream stream96 = new MemoryStream();
    avatar96.Save(stream96, ImageFormat.Jpeg);
    avatar96.Dispose();
    Bitmap avatar448 = Utils.ResizeImage(avatar, 448, 448);
    MemoryStream stream448 = new MemoryStream();

    avatar448.Save(stream448, ImageFormat.Jpeg);
    avatar448.Dispose();
    avatar.Dispose();
    byte[] jfif96 = stream96.ToArray();
    byte[] jfif448 = stream448.ToArray();
    stream96.Close();
    stream448.Close();
    MemoryStream picture = new MemoryStream(jfif96.Length + jfif448.Length + ACCOUNTPICTURE_MS_HEADER.Length + FIRST_PICTURE_HEADER.Length + SECOND_PICTURE_HEADER.Length);
    picture.Write(ACCOUNTPICTURE_MS_HEADER, 0, ACCOUNTPICTURE_MS_HEADER.Length);
    picture.Write(FIRST_PICTURE_HEADER, 0, FIRST_PICTURE_HEADER.Length);
    picture.Write(jfif96, 0, jfif96.Length);
    picture.Write(SECOND_PICTURE_HEADER, 0, SECOND_PICTURE_HEADER.Length);
    picture.Write(jfif448, 0, jfif448.Length);
    picture.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 8);
    byte[] pic = picture.ToArray();
    picture.Close();
    return pic;
}

Is there any way to generate this kind of file or set account's picture?



Solution 1:[1]

The picture settings are taken from registry branch HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users\{User_SID}. There are string parameters named Image{X}, where {X} is 32, 40, 48, 96, 192, 200, 240, 448. Each item represent the path to the image of corresponding size. So, you can

  • generate a set of images with sizes listed above and store the whole set on the disk
  • run your code as administrator to be able to write in the HKLM registry hive.
  • write paths into the registry.
  • reboot or logoff/login may needed to apply the changes.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Serg