0

I've created a Windows Service in Visual Studio as described here and I can install it successfully with the log working.

I want the service to change the background of my desktop, using the following code (taken from here):

public sealed class Wallpaper
{
    Wallpaper() { }

    const int SPI_SETDESKWALLPAPER = 20;
    const int SPIF_UPDATEINIFILE = 0x01;
    const int SPIF_SENDWININICHANGE = 0x02;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);

    public enum Style : int
    {
        Tiled,
        Centered,
        Stretched
    }

    public static void Set(Uri uri, Style style)
    {
        System.IO.Stream s = new System.Net.WebClient().OpenRead(uri.ToString());

        System.Drawing.Image img = System.Drawing.Image.FromStream(s);
        string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
        img.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);

        RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);
        Log.Print(key.Name);
        if (style == Style.Stretched)
        {
            key.SetValue(@"WallpaperStyle", 2.ToString());
            key.SetValue(@"TileWallpaper", 0.ToString());
        }

        if (style == Style.Centered)
        {
            key.SetValue(@"WallpaperStyle", 1.ToString());
            key.SetValue(@"TileWallpaper", 0.ToString());
        }

        if (style == Style.Tiled)
        {
            key.SetValue(@"WallpaperStyle", 1.ToString());
            key.SetValue(@"TileWallpaper", 1.ToString());
        }

        var a = SystemParametersInfo(SPI_SETDESKWALLPAPER,
            0,
            tempPath,
            SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
    }
}

The service runs without crashing, however the wallpaper is not changing.

If I run the exact same code in a console application the wallpaper does change.

I've noticed that the SystemParametersInfo is returning a handle of 0 when run in a service, and a handle of 1 when run in a console application, so obviously something is going wrong with calling unsafe code in a windows service. I can't seem to pinpoint why however.

Community
  • 1
  • 1
kkyr
  • 3,785
  • 3
  • 29
  • 59
  • You use `Registry.CurrentUser`, a service is not run by the logged-in user. – wimh Nov 11 '16 at 14:34
  • Windows Services cannot interact with the logged in user(s) desktop(s). The brackets alone in my previous sentence should give you some pause for thought – Damien_The_Unbeliever Nov 11 '16 at 14:35
  • 1
    @wimh - `Registry.CurrentUser` will relate to the current user account under which the service is running, which is not in any way guaranteed to be related to any users who may currently have interactive sessions running on that machine. – Damien_The_Unbeliever Nov 11 '16 at 14:36
  • Should I install my service using `serviceProcessInstaller.Account = ServiceAccount.User` instead of `ServiceAccount.LocalSystem`? – kkyr Nov 11 '16 at 14:37
  • Oh, and another reason to pause for thought - [System.Drawing namespace](https://msdn.microsoft.com/en-us/library/system.drawing(v=vs.110).aspx): "Classes within the System.Drawing namespace are not supported for use within a Windows or ASP.NET service" – Damien_The_Unbeliever Nov 11 '16 at 14:37
  • @Damien_The_Unbeliever I've already checked that the image is being created successfully in the temp directory – kkyr Nov 11 '16 at 14:38
  • This is just all misguided. If you want something that can easily interact with *your* desktop, just have a normal windows application and put it in your windows startup folder. The service approach just isn't right. – Damien_The_Unbeliever Nov 11 '16 at 14:40
  • @kskyriacou, it might be simpler to [start a separate process from the windows service into the currently logged in user's session](http://stackoverflow.com/q/4278373/33499). Otherwise you have to [get the logged in user name from the window service](http://stackoverflow.com/q/4032619/33499) – wimh Nov 11 '16 at 14:44
  • Why ask if you are going to ignore the responses. Time to start listening. – David Heffernan Nov 11 '16 at 16:34

0 Answers0