ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

C# で Windows 用スクリーンセーバーを作ってみた

会社の人が PC 内の画像をランダムに流すスクリーンセーバーを設定していて (Mac OS X デフォルトのものらしい) 結構うらやましかったので、画像をランダムに出しまくるスクリーンセーバーを Windows 用に作ってみた。 Visual Studio の使い方とか、実際にスクリーンセーバーを動かしたりするところでいろいろはまったので、はまったところを書き残しておく。 私自身 Windows のこととか Visual Studio の使い方とかろくにわかってないので、そういう初心者向け。

C# に関する知識とかスクリーンセーバーに関する知識とか Windows COM コンポーネントに関する知識とか全然ないのでよくわからないこと書いてるかもしれない。 突っ込み歓迎。

とりあえず環境準備

「スクリーンセーバーを作ってみよう」 と思ったもののどうやって作ればいいのかよくわからなかったので調べてみた。 ちなみに OS は Windows 8 Pro。

まず見つけたのは Microsoft 公式のスクリーンセーバーのサンプル。

Visual Studio を使って C# で開発できるっぽいので、Visual Studio Express 2012 for Windows Desktop を以下のページからダウンロードしてインストール。 上記サンプルコードを読み込んでみた。

しかし、参照として追加すべき COM コンポーネント "Microsoft Feeds, version 1.0" が自分の環境にはなくて、そのままのコードだと動かせなかったので断念。 とはいえコードは結構参考になりそうだったので、このコードを参考にしつつ、似たようなことをやってる以下のページを参考にして作ることにした。

C# のプロジェクト作成からコード追加やイベントハンドラの作成

まずはプロジェクトを作成しないといけない。 Visual Studio Express 2012 for Windows Desktop で "新しいプロジェクト" を選択し、テンプレートから C# の "Windows フォーム アプリケーション" を選択。 Windows フォームというのが、Windows デスクトップのウィンドウを表す UI 要素らしい。 つまり、スクリーンショットは通常のウィンドウをもつアプリケーションと同じように作ればいいようである。

スクリーンセーバー起動後の処理は、Program.cs の中の Main メソッドの中に書いていく。 コマンドライン引数によって処理を分ける必要がある。 そこら辺は上に書いたページを参考にすればわかると思う。

また、Form1.cs という Windows フォームも作成したプロジェクトの中にもともと含まれている。 これをスクリーンセーバー用の Windows フォームとして使えばよい。 "ソリューションエクスプローラー" の中で Form1.cs を開くと、Form1.Designers.cs や、Form1.resx というファイルも含まれている。 ここら辺は IDE 側が自動で生成するようになっているらしい。 フォームのプロパティを IDE 側で設定することができて、それらの設定値を実際に設定するためのコードなどが含まれている。

なので、例えばフォームに背景画像を表示しようと思った場合、そのためのコードを書く必要はなくて *1、"ソリューションエクスプローラー" で Form1.cs を右クリックして "デザイナーの表示" を選択した時に出てくるプロパティ画面で BackgroundImage というプロパティに表示したい背景画像を設定すればそれだけでフォームに背景画像が表示できる。 便利。

スクリーンセーバーなので、マウスカーソルを非表示にしたりとか、マウスクリック時にスクリーンセーバーを終了するようにしたりとか、そういうことも設定しないといけない。 そういった設定も、背景画像の場合と同じようにプロパティ画面で行える。 マウスクリック時に実行されるイベントハンドラの設定については、まず、Form1.cs の Form1 クラス内にイベントハンドラとなるメソッドを記述し、それをプロパティ画面のイベントタブ (稲妻のアイコン) で対象となるイベントに対して設定する。 下記ページが参考になった。

スクリーンセーバーの実行

開発中にデバッグ用に実行する場合は Visual Studio 上で普通に実行すればよい。 実際にスクリーンセーバーとして動かせる状態にするには、ビルドしてでてきた .exe ファイルの拡張子 .scr に変更するだけである。

しかし、この scr ファイルを手元の PC のスクリーンセーバーとして設定しようとしてもなかなかうまくいかなかった。 scr ファイルを右クリックすると "インストール" という項目があって、それをクリックすると "スクリーンセーバーの設定" 画面が開いて、作ったスクリーンセーバーが使えるように見える状態になるのだけれど、実際にスクリーンセーバーが起動すべき時間だけ PC を放置していてもスクリーンセーバーは起動しなかった。 (自作のスクリーンセーバーが起動しないだけで、もともとインストールされているものは動く。)

どうやら scr ファイルの置き場所が悪いようだ (このときは D ドライブ内に置いていた) ということで、もともとインストールされているスクリーンセーバーの実行ファイルと同じ場所 (C:\Windows\System32 の中に) 移動して実行してみた。 すると今度は以下のようなエラーメッセージが表示された。

ScreenSaver.scr - This application could not be started.

This application could not be started.

Do you want to view information atou this issue?

この問題の解決方法として、.NET Framework 3.5 を有効にしろ、みたいなことが書かれていたのだけれど、実際にやってみてもうまくいかず。 C:\Windows\System32 に移動する前はこんなエラーメッセージは出なかったわけなので、別の場所ならどうかと思って C:\Windows 直下に置いて試してみたら無事動いた。 どこに置くのが正解なのかよくわからない。

作ったスクリーンセーバー

GitHub に置いてるので、参考にしたり突っ込みいれたりしてください。 まだ細かい部分よくわかってなかったりするので変な箇所多いと思います。

現状はマイピクチャディレクトリ直下の screensaver というフォルダの中にある画像をランダムにぽんぽん表示するようになっています。 実行ファイルは以下にあるので使いたい方はどうぞ。

C:\Windows 直下に置いて、コンテキストメニューから "インストール" を選ぶととりあえず使えると思います。 マイピクチャ内に screensaver ディレクトリがないと何もエラーを出さずに起動もしないので注意。 ちなみに screensaver ディレクトリ内にあるショートカットは、1 回だけリンク先をたどるようになってます。

*1:もちろんコードを書いても実現できる