.NETプログラミング研究 第41号 †
.NET Tips †
OS起動時にプログラムを自動的に実行する / OS起動時に一回だけプログラムを自動的に実行する †
これは、.NETの知識というより、Windowsに関する知識ということになるでしょう。
OS起動時に指定したプログラムを自動的に実行されるようにするには、Windowsのプログラム内スタートアップフォルダにショートカットを作成するか、レジストリのRunキーに登録するというのが一般的な方法です。.NETではシュートカットの作成が簡単でないため、ここではレジストリのRunキーに書き込む方法を紹介します。
OS起動時に起動させるプログラムが登録されているキーには、次の4つがあります。(正確には、これらのキーに登録されたプログラムは新規ユーザーがログオンする時に実行されます。また、これ以外のキーもあります。詳しくは、下に紹介するマイクロソフトサポート技術情報をご覧ください。)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
これらのキーの内、HKEY_LOCAL_MACHINEとHKEY_CURRENT_USERの違いは、マシン毎の設定か、ユーザー毎の設定かであり、RunキーとRunOnceキーの違いは、登録されているプログラムを新規ユーザーがログオンするたびに実行するか、始めの一回のみ実行するかです。
よって通常はRunキーを使用し、RunOnceキーは現在使用中で削除できないファイルを次回起動時に削除するなどの目的で使用します。
なお、Runキーについて詳しくは、以下のマイクロソフトサポート技術情報をご覧ください。
以下に、HKEY_CURRENT_USERのRunキーにアプリケーションの実行ファイルのパスを登録し、OS起動時に実行されるようにするためのコードを紹介します。Microsoft.Vsa.dllを参照に加える必要があります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| | Public Shared Sub SetCurrentVersionRun()
Dim regkey As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.CurrentUser.OpenSubKey( _
"Software\Microsoft\Windows\CurrentVersion\Run", True)
regkey.SetValue( _
Application.ProductName, Application.ExecutablePath)
regkey.Close()
End Sub
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| | public static void SetCurrentVersionRun()
{
Microsoft.Win32.RegistryKey regkey =
Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
@"Software\Microsoft\Windows\CurrentVersion\Run", true);
regkey.SetValue(Application.ProductName, Application.ExecutablePath);
regkey.Close();
}
|
プログラムをファイルの拡張子に関連付ける †
これもWindowsのレジストリの知識です。
拡張子に関する情報は、レジストリのHKEY_CLASSES_ROOTキー以下に登録されています。例えば、".000"という拡張子のファイルに"myapp.exe %1"というコマンドラインを"open"というアクションで関連付けるには、
HKEY_CLASSES_ROOT\.000\shell\open\command
というキーに、名前がなく、データが"myapp.exe %1"の値を作成するだけです。
これが最も簡単な方法ですが、実際にこのように関連付けを行っているアプリケーションは稀です。一般的なやり方としては、まず
HKEY_CLASSES_ROOT\.000
というキーを作成し、ここに名前がなく、データに適当な文字列(ここでは、"MyApplication"とする)を指定した値を作成し、さらに、
HKEY_CLASSES_ROOT\MyApplication\shell\open\command
というキーに、名前がなく、データがコマンドラインとなる値を作成します。
以上は最低限の設定で、さらにアイコンの設定等も必要により行う必要があります。関連付けに関する詳しい話は、次のサイトが参考になります。
なお関連付けによりプログラムが実行された時、プログラムでファイルのパスを取得するには、コマンドライン引数を調べます。コマンドライン引数を取得する方法は、次のページをご覧ください。
以下に拡張子への関連付けを行うサンプルを示します。ここではアイコンの設定等も行っています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| | Dim extension As String = ".000"
Dim commandline As String = """" + Application.ExecutablePath _
+ """ %1"
Dim fileType As String = Application.ProductName
Dim description As String = "MyApplication File"
Dim verb As String = "open"
Dim verb_description As String = "MyApplicationで開く(&O)"
Dim iconPath As String = Application.ExecutablePath
Dim iconIndex As Integer = 0
Dim regkey As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(extension)
regkey.SetValue("", fileType)
regkey.Close()
Dim shellkey As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(fileType)
shellkey.SetValue("", description)
shellkey = shellkey.CreateSubKey("shell\" + verb)
shellkey.SetValue("", verb_description)
shellkey = shellkey.CreateSubKey("command")
shellkey.SetValue("", commandline)
shellkey.Close()
Dim iconkey As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey( _
fileType + "\DefaultIcon")
iconkey.SetValue("", iconPath + "," + iconIndex.ToString())
iconkey.Close()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| | string extension = ".000";
string commandline = "\"" + Application.ExecutablePath + "\" %1";
string fileType = Application.ProductName;
string description = "MyApplication File";
string verb = "open";
string verb_description = "MyApplicationで開く(&O)";
string iconPath =Application.ExecutablePath;
int iconIndex = 0;
Microsoft.Win32.RegistryKey regkey =
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(
extension);
regkey.SetValue("", fileType);
regkey.Close();
Microsoft.Win32.RegistryKey shellkey =
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(
fileType);
shellkey.SetValue("", description);
shellkey = shellkey.CreateSubKey("shell\\" + verb);
shellkey.SetValue("", verb_description);
//コマンドラインを登録
shellkey = shellkey.CreateSubKey("command");
shellkey.SetValue("", commandline);
shellkey.Close();
//アイコンの登録
Microsoft.Win32.RegistryKey iconkey =
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(
fileType + "\\DefaultIcon");
iconkey.SetValue("", iconPath + "," + iconIndex.ToString());
iconkey.Close();
|
また、関連付けを削除するには、次のように対象となるすべてのキーを削除します。
1
2
3
4
5
6
7
8
| | Dim extension As String = ".000"
Dim fileType As String = Application.ProductName
Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(extension)
Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(fileType)
|
1
2
3
4
5
6
7
8
| | string extension = ".000";
string fileType = Application.ProductName;
Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(extension);
Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(fileType);
|
エクスプローラでフォルダやドライブを右クリックしたときに表示されるコンテキストメニューに項目を追加する †
エクスプローラでフォルダやドライブを右クリックしたときに表示されるコンテキストメニューには、「検索」などの項目が表示されると思いますが、ここに新たな項目を追加し、指定したプログラムを起動させる方法を紹介します。
実はこれを行うには、フォルダやドライブに関連付けを行えばよく、先に紹介した「プログラムをファイルの拡張子に関連付ける」とほとんど同じ方法で実現できます。
「プログラムをファイルの拡張子に関連付ける」では、拡張子と同じ名前のキーに情報を登録しましたが、フォルダやドライブへの関連付けでは特別な名前を使用し、フォルダの場合は"Folder"、ドライブの場合は"Drive"、ファイルフォルダの場合は"Directory"という名前のキーとなります。(「ファイルフォルダ」というのが何なのかはっきり分かりませんが、多分、一般的なローカルなフォルダ(ドライブは含まない)というような意味ではないでしょうか。また、Folderへの登録では、フォルダとドライブ、さらに、ゴミ箱、マイネットワークでも表示されるようです。)
この3つ以外にも特別な意味を持つキーがいくつかあります。例えば、"*"はすべてのファイルを意味し、"AllFileSystemObjects"はすべてのファイルとフォルダを意味します。詳しくは先に紹介した「Jet Page - Windows レジストリ 解剖記」や、次のページ等をご覧ください。
フォルダへの関連付けにより、エクスプローラでフォルダを右クリックしたときに"MyApplicationで開く"を表示させるサンプルを以下に示します。
1
2
3
4
5
6
7
8
9
10
11
12
| | Dim commandline As String = _
"""" + Application.ExecutablePath + """ %1"
Dim description As String = "MyApplicationで開く"
Dim regkey As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey( _
"Folder\shell\" + description + "\command")
regkey.SetValue("", commandline)
regkey.Close()
|
1
2
3
4
5
6
7
8
9
10
11
| | string commandline = "\"" + Application.ExecutablePath + "\" %1";
string description = "MyApplicationで開く";
Microsoft.Win32.RegistryKey regkey =
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(
"Folder\\shell\\" + description + "\\command");
regkey.SetValue("", commandline);
regkey.Close();
|
エクスプローラの新規作成メニューに項目を追加する †
エクスプローラでフォルダを選び、メニューの「ファイル - 新規作成」(あるいは、右クリックによるコンテキストメニューの「新規作成」)を選択すると、指定されたタイプのファイルを新しく作成することができます。ここではこの「新規作成」メニューに独自の項目を追加する方法を紹介します。
しつこいようですが、これまた、Windowsとレジストリの知識で、その方法は次のページで詳しく紹介されています。
まずは拡張子への関連付けが必要ですので、「プログラムをファイルの拡張子に関連付ける」により、新規作成に追加したい拡張子を登録します。
「新規作成」メニューにより作成されるファイルには2種類(注1)あり、サイズ0(空)のファイルか、テンプレートファイルを基にしたファイルになります。
サイズ0のファイルを作成する場合は簡単で、レジストリの
HKEY_CLASSES_ROOT\(拡張子)\ShellNew
というキーに名前が"NullFile"でデータが""の値を作成するだけです。
テンプレートファイルを使用する場合は、新規作成により作成されるファイルをWindowsのテンプレートフォルダ("System.Environment.GetFolderPath(Environment.SpecialFolder.Templates)"によりパスが取得できます)に置いておき、先と同じShellNewキーに名前が"FileName"でデータがテンプレートのファイル名の値を登録します。
"NullFile"と"FileName"の両方を指定することはできませんが、両方が存在する場合は、"NullFile"が優先されるようです。
以下にサンプルを示します。まずは、「新規作成」メニューによりサイズ0のファイルが作成される例です。
1
2
3
4
5
6
7
8
9
| | Dim extension As String = ".000"
Dim regkey As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey( _
extension + "\ShellNew")
regkey.SetValue("NullFile", "")
regkey.Close()
|
1
2
3
4
5
6
7
8
9
| | string extension = ".000";
Microsoft.Win32.RegistryKey regkey =
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(
extension + "\\ShellNew");
regkey.SetValue("NullFile", "");
regkey.Close();
|
次にテンプレートファイルを使用した例を示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| | Dim extension As String = ".000"
Dim templateName As String = "myapp.000"
Dim templatePath As String = _
System.Environment.GetFolderPath( _
Environment.SpecialFolder.Templates) + "\" + templateName
Dim templateText As String = "DOBON.NET"
Dim sw = New StreamWriter(templatePath)
sw.Write(templateText)
sw.Close()
Dim regkey As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey( _
extension + "\ShellNew")
regkey.SetValue("FileName", templateName)
regkey.Close()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| | string extension = ".000";
string templateName = "myapp.000";
string templatePath =
System.Environment.GetFolderPath(
Environment.SpecialFolder.Templates) +
"\\" + templateName;
//テンプレートの中身
string templateText = "DOBON.NET";
//テンプレートファイルを作成する
System.IO.StreamWriter sw = new StreamWriter(templatePath);
sw.Write(templateText);
sw.Close();
//「新規作成」により、テンプレートファイルを作成
Microsoft.Win32.RegistryKey regkey =
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(
extension + "\\ShellNew");
regkey.SetValue("FileName", templateName);
regkey.Close();
|
(注1)@IT:Windows TIPSでは2種類しか紹介されていませんが、実際にはこれ以外に"Command"と"Data"いうのもあります。
名前が"Command"でデータがコマンドラインの値を作成すると、新規作成の際、指定したコマンドラインが実行されます。これは、シュートカットを新規作成するときのように、ウィザードによりファイルを作成するときに使用します。
また、"Data"を名前とする値の場合、データにバイナリ値を指定します。
コメント †