- Code: Select all
# Script to load latest PNG from xkcd.com, invert it, and set it as the desktop background
function Compile-Csharp ([string] $code, $FrameworkVersion="v2.0.50727",
[Array]$References)
{
#
# Get an instance of the CSharp code provider
#
$cp = new-object Microsoft.CSharp.CSharpCodeProvider
#
# Build up a compiler params object...
$framework = [System.IO.Path]::Combine($env:windir, "Microsoft.NET\Framework\$FrameWorkVersion")
$refs = new-object Collections.ArrayList
$refs.AddRange( @("${framework}\System.dll",
# "${mshhome}\System.Management.Automation.dll",
# "${mshhome}\System.Management.Automation.ConsoleHost.dll",
"${framework}\system.windows.forms.dll",
"${framework}\System.data.dll",
"${framework}\System.Drawing.dll",
"${framework}\System.Xml.dll"))
if ($references.Count -ge 1)
{
$refs.AddRange($References)
}
$cpar = New-Object System.CodeDom.Compiler.CompilerParameters
$cpar.GenerateInMemory = $true
$cpar.GenerateExecutable = $false
$cpar.CompilerOptions = "/unsafe";
$cpar.OutputAssembly = "custom"
$cpar.ReferencedAssemblies.AddRange($refs)
$cr = $cp.CompileAssemblyFromSource($cpar, $code)
if ( $cr.Errors.Count)
{
$codeLines = $code.Split("`n");
foreach ($ce in $cr.Errors)
{
write-host "Error: $($codeLines[$($ce.Line - 1)])"
$ce |out-default
}
Throw "INVALID DATA: Errors encountered while compiling code"
}
}
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") > $null
[System.Reflection.Assembly]::LoadWithPartialName("System.Runtime") > $null
# Get the RSS feed from xkcd.com
$rssURL = "http://xkcd.com/rss.xml"
$blog = [xml](new-object System.Net.WebClient).DownloadString($rssURL)
# Pull the first item's description string, which should be an <img src="..."... />
$desc = $blog.rss.channel.item[0].description
# Grab the URL from the 'src' attribute of the 'img' tag:
$ix1 = $desc.IndexOf("src=") + 5
$imgurl = $desc.Substring($ix1, $desc.IndexOf('"', $ix1) - $ix1)
# C# code to invert colors and post to wallpaper
$code = @'
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;
using System.Net;
using Microsoft.Win32;
namespace test
{
public 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 static void SetInverted(string uri)
{
System.IO.Stream s = new WebClient().OpenRead(uri);
Image img = System.Drawing.Image.FromStream(s);
Bitmap copy = new Bitmap(img.Width, img.Height);
Graphics g = Graphics.FromImage(copy);
Rectangle rect = new Rectangle(0, 0, img.Width, img.Height);
g.DrawImage(img, rect, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
g.Dispose();
img.Dispose();
// Invert colors:
unsafe {
BitmapData bmd = copy.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, copy.PixelFormat);
int PixelSize = 4;
for(int y=0; y<bmd.Height; y++) {
byte* row=(byte *)bmd.Scan0+(y*bmd.Stride);
for(int x=0; x<bmd.Width; x++) {
row[x*PixelSize] = (byte)(255 - row[x*PixelSize]);
row[x*PixelSize+1] = (byte)(255 - row[x*PixelSize+1]);
row[x*PixelSize+2] = (byte)(255 - row[x*PixelSize+2]);
}
}
copy.UnlockBits(bmd);
}
// Save to a temp file:
string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
copy.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
RegistryKey key = Registry.CurrentUser.OpenSubKey( @"Control Panel\Desktop", true ) ;
key.SetValue(@"WallpaperStyle", 1.ToString( ) ) ;
key.SetValue(@"TileWallpaper", 0.ToString( ) ) ;
SystemParametersInfo( SPI_SETDESKWALLPAPER,
0,
tempPath,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE );
}
}
}
'@
compile-CSharp $code
[test.Wallpaper]::SetInverted($imgurl)
As usual, you need to sign the code for it to run on your machine.
