Powershellで雪でも降らせる

冬だし、Powershellで雪でも降らせるか、とスクリプトを書いてみた。
実行すると、私がぽちぽちドットを押して描いた雪の結晶が一つ、適当な位置から落ちていきます。
一番下まで落ちたら終了。



スクリプト

Add-Type -AssemblyName System.Windows.Forms
$form = New-Object System.Windows.Forms.Form
$form.SuspendLayout()
$form.FormBorderStyle = 'None'
$form.ShowInTaskbar = $false
$form.Text = 'snow'
$image = [System.Drawing.Image]::FromStream((New-Object System.IO.MemoryStream([Convert]::FromBase64String(@"
	iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfCAYAAAAfrhY5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv
	8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAERSURBVFhHzZeNDoIwDIT3/i89QRmW8/oLcTMxJoq73t
	fuBq211ie+8+J9e+0F42fBRF58CL/Vj0IKwruBmrh0fmONvPgU7BLxQI7fJSl8nUf6p4ll/3sUmZ/aK
	nayOz7OcXI9nAz7QG7RAUJX4UwvNdTWbIBJPu3yIhTxsMvfnVm4ijP8DCMSYm5lG5Qi/H0uhbx+YvHO
	1tPF2UJYiDZ4wSJ+xS1RRGnhZrsISPjYER1zn0y2cYwv6nxKzz3MWpJZqae0ZcF9/reEQyGWcgzbY9l
	uCTIRq79eCgojC5zn0RtCy5UXNIRgPOFYlGrFeIWct1HBC88nG+88T6wXd87CJyHEHstq4oU0e0Z8Ce
	w3kfcXhsk6G9IUwIsAAAAASUVORK5CYII=
"@), $false)))
$image2 = $image.Clone()
$image2.RotateFlip('Rotate90FlipNone')
$funcMouseUp = {
	Param ($sender, $ev)
	if($ev.Button -eq 'Right') { $form.Close() }
	$visi = $pictureBox.Visible
	$pictureBox.Visible = $pictureBox2.Visible
	$pictureBox2.Visible = $visi
}
$funcMouseDown = {
	Param ($sender, $ev)
	if($ev.Button -eq 'Left') { $dragPos = New-Object System.Drawing.Point(-$ev.X, -$ev.Y) }
}
$funcMouseMove = {
	Param ($sender, $ev)
	if($ev.Button -eq 'Left') {
		$form.Left += $dragPos.X + $ev.X
		$form.Top += $dragPos.Y + $ev.Y
	}
}
$pictureBox = New-Object System.Windows.Forms.PictureBox
$pictureBox.Image = $image
$pictureBox.Add_MouseUp($funcMouseUp)
$pictureBox.Add_MouseDown($funcMouseDown)
$pictureBox.Add_MouseMove($funcMouseMove)
$form.Controls.Add($pictureBox)
$pictureBox2 = New-Object System.Windows.Forms.PictureBox
$pictureBox2.Visible = $false
$pictureBox2.Image = $image2
$pictureBox2.Add_MouseUp($funcMouseUp)
$form.Controls.Add($pictureBox2)
$form.ClientSize = $image.Size
$form.BackColor = $image.GetPixel(0, 0)
$form.TransparencyKey = $form.BackColor
$form.ResumeLayout($false)
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 500
$random = New-Object Random
$timer.Add_Tick({
	if($pictureBox.Visible) {
		$pictureBox2.Visible = $true
		$pictureBox.Visible = $false
	} else {
		$pictureBox.Visible = $true
		$pictureBox2.Visible = $false
	}
	$form.Left += $random.Next(3) - 1
	$form.Top += 1
	if($form.Top -ge [System.Windows.Forms.Screen]::GetBounds($form).Height) { $form.Close() }
})
$timer.Enabled = $true
[void]$form.ShowDialog()
$form.Dispose()

解説他

ただ雪の結晶っぽいものを動かしたかっただけなんだけど、回転しているように見せようとしたらいろいろ面倒になった。
一応、マウスで掴んで動かせます。(あ、縦表示の時のみだ、、、)
右クリックするとその場で終了します。(これはどっちでも可)


関数化してきままに入力するとか、Start-Job利用して複数降らすとか、好きにしたってください。
10個同時に降らすなら、こんな感じ。

$funcSnow = {
(上のコピー)
}
for($i=0; $i -lt 10; $i++) { Start-Job $funcSnow }


これ、最初xamlで書いてたんですけど、UWSCで実行したらダメと言われたのですよ。(環境による気もする)
後から解決方法は思いついたけど、、、これ晒すと、Pro版のCreateFormの存在意義に関わるな、と思ったのでやめました。
System.Windows.Formsは、CreateFormに比べて面倒ですから、こっちはいいかな、と。
UWSCで実行するには、スクリプトをTEXTBLOCK化して、Powershell関数に渡すだけです。