title: Change wallpaper with service
body: <p>I'm trying to use a service installed to run as a specific user (me in this case) to change the wallpaper.</p>
  
  <p>Here is my <code>Wallpaper</code> class which has a <code>SetWallpaper</code> function:</p>
  
  <pre><code>public sealed class Wallpaper
  {
     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError=true)]
     private static extern Int32 SystemParametersInfo(
        UInt32 action, UInt32 uParam, String vParam, UInt32 winIni);
  
     private static readonly UInt32 SPI_SETDESKWALLPAPER = 0x14;
     private static readonly UInt32 SPIF_UPDATEINIFILE = 0x01;
     private static readonly UInt32 SPIF_SENDWININICHANGE = 0x02;
  
     public static void SetWallpaper(String path)
     {
        System.IO.Stream s = new System.Net.WebClient().OpenRead(path.ToString());
        System.Drawing.Image img = System.Drawing.Image.FromStream(s);
        string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
        ImgurWallpaperSetter.ImgurWallpaperSetter.log(tempPath);
        img.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
        SystemParametersInfo(SPI_SETDESKWALLPAPER, 1, tempPath,
        SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
        int error = Marshal.GetLastWin32Error();
        ImgurWallpaperSetter.ImgurWallpaperSetter.log("Last error: " + error);
     }
  }
  </code></pre>
  
  <p>It works perfectly when I run <code>SetWallpaper</code> from a unit test, but it doesn't work at all when I install the service and start it.</p>
  
  <p>Here is the service start code:</p>
  
  <pre><code>protected override void OnStart(string[] args) {    
     //WallpaperScheduler.ScheduleWallpaperFetch(DateTime.Now.Hour, DateTime.Now.Minute+1);
     //Debugger.Launch();
     Uri imageUrl = WallpaperRetriever.mostPopularImgurWallpaper();
     log(imageUrl.AbsoluteUri);
     Wallpaper.SetWallpaper(imageUrl.AbsoluteUri);
  }
  </code></pre>
  
  <p>I've confirmed that it's downloading the image into my temp directory correctly, but it's not setting the wallpaper. It doesn't error out or log anything to the event logs.</p>
  
  <p>Here's my service installed in the local service viewer:</p>
  
  <p><img src="https://i.stack.imgur.com/XpfKH.png" alt="Service installed as the user (me)"></p>
  
  <p>Running it does nothing.</p>
  
  <p><a href="https://stackoverflow.com/questions/20092611/how-to-change-the-wallpaper-using-service-c-sharp">A similar thread I've read</a></p>
  
  <p><strong>Edit:</strong>
  Added this code to run on my <code>serviceInstaller_Committed</code> event which should allow the service to interact with the desktop, but I see a huge delay between the service run and the actual switching of the wallpaper:</p>
  
  <pre><code>ConnectionOptions coOptions = new ConnectionOptions();
  coOptions.Impersonation = ImpersonationLevel.Impersonate;
  
  ManagementScope mgmtScope = new ManagementScope(@"root\CIMV2", coOptions);
  mgmtScope.Connect();
  
  ManagementObject wmiService;
  wmiService = new ManagementObject(
     "Win32_Service.Name='" + serviceInstaller1.ServiceName + "'"
  );
  
  ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");
  InParam["DesktopInteract"] = true;
  ManagementBaseObject OutParam = wmiService.InvokeMethod("Change", InParam, null);
  </code></pre>
  
  <p><strong>Edit2:</strong>
  I've updated my service to log to the system events <code>GetLastError()</code>. Now I am seeing that the service is throwing error 1459 ("This operation requires an interactive window station."). However, this doesn't explain why my wallpaper does eventually switch (I think usually after waking from sleep). Updated <code>Wallpaper</code> class above as well.</p>
  
  <p><strong>Edit3</strong>
  I've confirmed that after sleeping, the new wallpaper is set. Can anyone explain why this is? Could it be that I need to restart for the Interactive Desktop ability to be set?</p>
  
  <p><strong>Edit4</strong>
  What I'm doing is feeling pretty hacky. Would it be better if I had the service do nothing but download wallpapers and potentially had another non-service application for changing the wallpaper if new wallpapers have been downloaded and the user is logged in?</p>