Skip to content

Instantly share code, notes, and snippets.

@qubbit
Last active May 26, 2018 02:52
Show Gist options
  • Save qubbit/23c230e406ddb8553f58fb25b764e48c to your computer and use it in GitHub Desktop.
Save qubbit/23c230e406ddb8553f58fb25b764e48c to your computer and use it in GitHub Desktop.

Revisions

  1. Gopal Adhikari revised this gist May 26, 2018. 1 changed file with 48 additions and 36 deletions.
    84 changes: 48 additions & 36 deletions Program.cs
    Original file line number Diff line number Diff line change
    @@ -6,18 +6,21 @@
    using System.Windows.Forms;
    using System.Linq;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Dynamic;

    // A program that will periodically download an image from Unsplash and
    // change your Windows desktop background to the downloaded image

    // Compilation: csc /out:unsplash.exe /t:winexe .\Program.cs /nologo /o

    // After compilation, drop the executable in a folder and run it with command line args:
    // args[0] = minutes (how often to change the background image
    // args[1] = search terms to find your desire type of wallpaper
    // time = minutes (how often to change the background image)
    // category = search terms to find your desired type of wallpaper
    // fit = wallpaper fit, one of fill, fit, span, tile, center, stretch

    // Example invocation:
    // unsplash.exe 60 nature,scenary
    // Example:
    // unsplash.exe time=60 category=nature,scenary fit=stretch
    // This will change the wallpaper every hour from category of nature and scenary


    @@ -41,44 +44,52 @@ public void Log(string message) {
    }

    class Program {
    // All time units are in minutes unless otherwise specified
    const int ONE_HOUR = 60;
    const int FIFTEEN_MINUTES = 15;
    const string IMAGE_DIR_NAME = "Unsplash";
    const string DEFAULT_SEARCH_CATEGORY = "nature,scenary,landmarks";

    // Arg 0 = width, Arg 1 = height, Arg 2 = search terms (comma separated)
    const string SEARCH_URL_TEMPLATE = "https://source.unsplash.com/{0}x{1}/?{2}";
    const string SEARCH_URL_TEMPLATE = "http://source.unsplash.com/{0}x{1}/?{2}";

    static string url;
    static FileLogger logger = new FileLogger();
    static uint timerCallCount = 0;
    public static string imageDownloadDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, IMAGE_DIR_NAME);

    static dynamic ParseCommandLine(string[] args) {
    var typeDictionary = new Dictionary<string, Type>() {
    { "time", typeof(int)},
    { "category", typeof(string)},
    { "fit", typeof(Wallpaper.Style)}
    };

    dynamic o = new ExpandoObject();
    var options = (IDictionary<string, object>)o;

    foreach (var x in args) {
    var segments = x.Split('=');
    var key = segments[0];
    var value = segments[1];

    var converter = TypeDescriptor.GetConverter(typeDictionary[key]);
    var result = converter.ConvertFrom(value);
    options.Add(key, result);
    }

    return o;
    }

    static dynamic options;

    static void Main(string[] args) {
    SetAppBasePath();
    logger.Log("Application started");

    if (args.Length < 2) {
    logger.Log(String.Format("Setting default arguments since no arguments were specified. Interval = {0} minutes, search category = {1}",
    FIFTEEN_MINUTES, DEFAULT_SEARCH_CATEGORY));
    args = new string[] { FIFTEEN_MINUTES.ToString(), DEFAULT_SEARCH_CATEGORY };
    }
    if (args.Length < 3) args = new string[] { "time=15", "category=cities", "fit=stretch" };
    options = ParseCommandLine(args);

    var searchTerms = args[1];
    var screenBounds = Screen.AllScreens.Where(x => x.Primary).First().Bounds;
    logger.Log("Primary screen bounds: " + screenBounds.ToString());

    url = string.Format(SEARCH_URL_TEMPLATE, screenBounds.Width, screenBounds.Height, searchTerms);
    url = string.Format(SEARCH_URL_TEMPLATE, screenBounds.Width, screenBounds.Height, options.category);

    if (int.TryParse(args[0], out int interval)) {
    if (interval < FIFTEEN_MINUTES) interval = FIFTEEN_MINUTES;
    }
    else {
    interval = ONE_HOUR;
    }

    int intervalMilliseconds = interval * 60 * 1000;
    int intervalMilliseconds = options.time * 60 * 1000;
    new System.Threading.Timer(Tick, null, 0, intervalMilliseconds);

    while (true) System.Threading.Thread.Sleep(1000);
    @@ -93,7 +104,7 @@ private static void Tick(object state) {
    string imageFileName = ImageDownloader.Download(url);
    var logMessage = string.Format("Tick count: {0}. Setting wallpaper to {1}", ++timerCallCount, imageFileName);
    logger.Log(logMessage);
    Wallpaper.Set(imageFileName, Wallpaper.Style.Fill);
    Wallpaper.Set(imageFileName, options.fit);
    }
    }

    @@ -117,18 +128,19 @@ public static string Download(string url) {
    var responseUri = response.ResponseUri;
    string imageFileName = Program.imageDownloadDir + "\\" + new FileInfo(response.ResponseUri.LocalPath).Name + Extension(response.ContentType);

    using (Stream receiveStream = response.GetResponseStream())
    using (Stream outputStream = File.OpenWrite(imageFileName)) {
    byte[] buffer = new byte[4096];
    int bytesRead;
    using (Stream receiveStream = response.GetResponseStream()) {
    using (Stream outputStream = File.OpenWrite(imageFileName)) {
    byte[] buffer = new byte[4096];
    int bytesRead;

    do {
    bytesRead = receiveStream.Read(buffer, 0, buffer.Length);
    outputStream.Write(buffer, 0, bytesRead);
    } while (bytesRead != 0);
    do {
    bytesRead = receiveStream.Read(buffer, 0, buffer.Length);
    outputStream.Write(buffer, 0, bytesRead);
    } while (bytesRead != 0);

    }
    return imageFileName;
    }
    return imageFileName;
    }
    }

  2. Gopal Adhikari revised this gist May 25, 2018. No changes.
  3. Gopal Adhikari revised this gist May 25, 2018. 1 changed file with 28 additions and 55 deletions.
    83 changes: 28 additions & 55 deletions Program.cs
    Original file line number Diff line number Diff line change
    @@ -1,18 +1,18 @@
    using Microsoft.Win32;
    using System;
    using System.Drawing;
    using System.IO;
    using System.Net;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using System.Linq;
    using System.Collections.Generic;

    // A program that will periodically download an image from Unsplash and
    // change your Windows desktop background to the downloaded image

    // Compilation: csc /out:unsplash.exe /t:winexe .\Program.cs /nologo /o

    // After compilation, drop the executable in a folder and run it with some command line args
    // After compilation, drop the executable in a folder and run it with command line args:
    // args[0] = minutes (how often to change the background image
    // args[1] = search terms to find your desire type of wallpaper

    @@ -41,10 +41,10 @@ public void Log(string message) {
    }

    class Program {
    const int ONE_HOUR_MS = 60 * 60 * 1000;
    const int FIFTEEN_MINUTES_MS = ONE_HOUR_MS / 4;
    // All time units are in minutes unless otherwise specified
    const int ONE_HOUR = 60;
    const int FIFTEEN_MINUTES = 15;
    const string IMAGE_DIR_NAME = "Unsplash";
    const int DEFAULT_SEARCH_INTERVAL_MINUTES = 15;
    const string DEFAULT_SEARCH_CATEGORY = "nature,scenary,landmarks";

    // Arg 0 = width, Arg 1 = height, Arg 2 = search terms (comma separated)
    @@ -53,15 +53,16 @@ class Program {
    static string url;
    static FileLogger logger = new FileLogger();
    static uint timerCallCount = 0;
    public static string imageDownloadDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, IMAGE_DIR_NAME);

    static void Main(string[] args) {
    SetAppBasePath();
    logger.Log("Application started");

    if (args.Length < 2) {
    logger.Log(String.Format("Setting default arguments since no arguments were specified. Interval = {0} minutes, search category = {1}",
    DEFAULT_SEARCH_INTERVAL_MINUTES, DEFAULT_SEARCH_CATEGORY));
    args = new string[] { DEFAULT_SEARCH_INTERVAL_MINUTES.ToString(), DEFAULT_SEARCH_CATEGORY };
    FIFTEEN_MINUTES, DEFAULT_SEARCH_CATEGORY));
    args = new string[] { FIFTEEN_MINUTES.ToString(), DEFAULT_SEARCH_CATEGORY };
    }

    var searchTerms = args[1];
    @@ -71,20 +72,19 @@ static void Main(string[] args) {
    url = string.Format(SEARCH_URL_TEMPLATE, screenBounds.Width, screenBounds.Height, searchTerms);

    if (int.TryParse(args[0], out int interval)) {
    interval *= 60 * 1000; // convert minutes to milliseconds
    if (interval < FIFTEEN_MINUTES_MS) interval = FIFTEEN_MINUTES_MS;
    if (interval < FIFTEEN_MINUTES) interval = FIFTEEN_MINUTES;
    }
    else {
    interval = ONE_HOUR_MS;
    interval = ONE_HOUR;
    }

    new System.Threading.Timer(Tick, null, 0, interval);
    int intervalMilliseconds = interval * 60 * 1000;
    new System.Threading.Timer(Tick, null, 0, intervalMilliseconds);

    while (true) System.Threading.Thread.Sleep(1000);
    }

    private static void SetAppBasePath() {
    string imageDownloadDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, IMAGE_DIR_NAME);
    if (!Directory.Exists(imageDownloadDir)) { Directory.CreateDirectory(imageDownloadDir); }
    Directory.SetCurrentDirectory(imageDownloadDir);
    }
    @@ -115,7 +115,7 @@ public static string Download(string url) {
    var response = (HttpWebResponse)request.GetResponse();

    var responseUri = response.ResponseUri;
    string imageFileName = new FileInfo(response.ResponseUri.LocalPath).Name + Extension(response.ContentType);
    string imageFileName = Program.imageDownloadDir + "\\" + new FileInfo(response.ResponseUri.LocalPath).Name + Extension(response.ContentType);

    using (Stream receiveStream = response.GetResponseStream())
    using (Stream outputStream = File.OpenWrite(imageFileName)) {
    @@ -141,51 +141,24 @@ public sealed class Wallpaper {
    static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);

    public enum Style : int {
    Fill,
    Fit,
    Span,
    Tile,
    Center,
    Stretch
    Fill, Fit, Span, Tile, Center, Stretch
    }

    public static void Set(string filename, Style style) {
    Image img = Image.FromFile(filename);
    string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
    img.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
    private static Dictionary<Style, Tuple<string, string>> wallpaperStyles = new Dictionary<Style, Tuple<string, string>> {
    { Style.Fill, new Tuple<string, string>("10", "0") },
    { Style.Fit, new Tuple<string, string>("6", "0") },
    { Style.Span, new Tuple<string, string>("22", "0") },
    { Style.Stretch, new Tuple<string, string>("2", "0") },
    { Style.Tile, new Tuple<string, string>("0", "1") },
    { Style.Center, new Tuple<string, string>("0", "0") }
    };

    public static void Set(string filename, Style style) {
    RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);

    if (style == Style.Fill) {
    key.SetValue(@"WallpaperStyle", "10");
    key.SetValue(@"TileWallpaper", "0");
    }
    if (style == Style.Fit) {
    key.SetValue(@"WallpaperStyle", "6");
    key.SetValue(@"TileWallpaper", "0");
    }
    if (style == Style.Span) // Windows 8 or newer only!
    {
    key.SetValue(@"WallpaperStyle", "22");
    key.SetValue(@"TileWallpaper", "0");
    }
    if (style == Style.Stretch) {
    key.SetValue(@"WallpaperStyle", "2");
    key.SetValue(@"TileWallpaper", "0");
    }
    if (style == Style.Tile) {
    key.SetValue(@"WallpaperStyle", "0");
    key.SetValue(@"TileWallpaper", "1");
    }
    if (style == Style.Center) {
    key.SetValue(@"WallpaperStyle", "0");
    key.SetValue(@"TileWallpaper", "0");
    }

    SystemParametersInfo(SPI_SETDESKWALLPAPER,
    0,
    tempPath,
    SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
    var reg = wallpaperStyles[style];
    key.SetValue("WallpaperStyle", reg.Item1);
    key.SetValue("TileWallpaper", reg.Item1);
    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, filename, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
    }
    }
    }
    }
  4. Gopal Adhikari created this gist May 25, 2018.
    191 changes: 191 additions & 0 deletions Program.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,191 @@
    using Microsoft.Win32;
    using System;
    using System.Drawing;
    using System.IO;
    using System.Net;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using System.Linq;

    // A program that will periodically download an image from Unsplash and
    // change your Windows desktop background to the downloaded image

    // Compilation: csc /out:unsplash.exe /t:winexe .\Program.cs /nologo /o

    // After compilation, drop the executable in a folder and run it with some command line args
    // args[0] = minutes (how often to change the background image
    // args[1] = search terms to find your desire type of wallpaper

    // Example invocation:
    // unsplash.exe 60 nature,scenary
    // This will change the wallpaper every hour from category of nature and scenary


    namespace Unsplash {

    // Very simple logger implementation with a lock!
    public class FileLogger {
    protected readonly object locker = new object();
    const string LOG_FILE_PATH = "application.log";
    const bool ALSO_LOG_TO_STDOUT = true;

    public void Log(string message) {
    lock (locker) {
    using (var streamWriter = new StreamWriter(LOG_FILE_PATH, append: true)) {
    var line = string.Format("{0} \t {1}", DateTime.Now.ToString("MM/d/yyyy hh:mm:ss tt zzzz"), message);
    streamWriter.WriteLine(line);
    if (ALSO_LOG_TO_STDOUT) Console.WriteLine(line);
    }
    }
    }
    }

    class Program {
    const int ONE_HOUR_MS = 60 * 60 * 1000;
    const int FIFTEEN_MINUTES_MS = ONE_HOUR_MS / 4;
    const string IMAGE_DIR_NAME = "Unsplash";
    const int DEFAULT_SEARCH_INTERVAL_MINUTES = 15;
    const string DEFAULT_SEARCH_CATEGORY = "nature,scenary,landmarks";

    // Arg 0 = width, Arg 1 = height, Arg 2 = search terms (comma separated)
    const string SEARCH_URL_TEMPLATE = "https://source.unsplash.com/{0}x{1}/?{2}";

    static string url;
    static FileLogger logger = new FileLogger();
    static uint timerCallCount = 0;

    static void Main(string[] args) {
    SetAppBasePath();
    logger.Log("Application started");

    if (args.Length < 2) {
    logger.Log(String.Format("Setting default arguments since no arguments were specified. Interval = {0} minutes, search category = {1}",
    DEFAULT_SEARCH_INTERVAL_MINUTES, DEFAULT_SEARCH_CATEGORY));
    args = new string[] { DEFAULT_SEARCH_INTERVAL_MINUTES.ToString(), DEFAULT_SEARCH_CATEGORY };
    }

    var searchTerms = args[1];
    var screenBounds = Screen.AllScreens.Where(x => x.Primary).First().Bounds;
    logger.Log("Primary screen bounds: " + screenBounds.ToString());

    url = string.Format(SEARCH_URL_TEMPLATE, screenBounds.Width, screenBounds.Height, searchTerms);

    if (int.TryParse(args[0], out int interval)) {
    interval *= 60 * 1000; // convert minutes to milliseconds
    if (interval < FIFTEEN_MINUTES_MS) interval = FIFTEEN_MINUTES_MS;
    }
    else {
    interval = ONE_HOUR_MS;
    }

    new System.Threading.Timer(Tick, null, 0, interval);

    while (true) System.Threading.Thread.Sleep(1000);
    }

    private static void SetAppBasePath() {
    string imageDownloadDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, IMAGE_DIR_NAME);
    if (!Directory.Exists(imageDownloadDir)) { Directory.CreateDirectory(imageDownloadDir); }
    Directory.SetCurrentDirectory(imageDownloadDir);
    }

    private static void Tick(object state) {
    string imageFileName = ImageDownloader.Download(url);
    var logMessage = string.Format("Tick count: {0}. Setting wallpaper to {1}", ++timerCallCount, imageFileName);
    logger.Log(logMessage);
    Wallpaper.Set(imageFileName, Wallpaper.Style.Fill);
    }
    }

    class ImageDownloader {
    private static string Extension(string mimeType) {
    switch (mimeType) {
    case "image/jpeg":
    return ".jpg";
    case "image/png":
    return ".png";
    default:
    return "";
    }
    }

    public static string Download(string url) {
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    var request = (HttpWebRequest)WebRequest.Create(url);
    var response = (HttpWebResponse)request.GetResponse();

    var responseUri = response.ResponseUri;
    string imageFileName = new FileInfo(response.ResponseUri.LocalPath).Name + Extension(response.ContentType);

    using (Stream receiveStream = response.GetResponseStream())
    using (Stream outputStream = File.OpenWrite(imageFileName)) {
    byte[] buffer = new byte[4096];
    int bytesRead;

    do {
    bytesRead = receiveStream.Read(buffer, 0, buffer.Length);
    outputStream.Write(buffer, 0, bytesRead);
    } while (bytesRead != 0);

    }
    return imageFileName;
    }
    }

    public sealed class 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 {
    Fill,
    Fit,
    Span,
    Tile,
    Center,
    Stretch
    }

    public static void Set(string filename, Style style) {
    Image img = Image.FromFile(filename);
    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);

    if (style == Style.Fill) {
    key.SetValue(@"WallpaperStyle", "10");
    key.SetValue(@"TileWallpaper", "0");
    }
    if (style == Style.Fit) {
    key.SetValue(@"WallpaperStyle", "6");
    key.SetValue(@"TileWallpaper", "0");
    }
    if (style == Style.Span) // Windows 8 or newer only!
    {
    key.SetValue(@"WallpaperStyle", "22");
    key.SetValue(@"TileWallpaper", "0");
    }
    if (style == Style.Stretch) {
    key.SetValue(@"WallpaperStyle", "2");
    key.SetValue(@"TileWallpaper", "0");
    }
    if (style == Style.Tile) {
    key.SetValue(@"WallpaperStyle", "0");
    key.SetValue(@"TileWallpaper", "1");
    }
    if (style == Style.Center) {
    key.SetValue(@"WallpaperStyle", "0");
    key.SetValue(@"TileWallpaper", "0");
    }

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