┏第41号━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃         .NETプログラミング研究         ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ──<メニュー>─────────────────────── ■.NET Tips ・OS起動時にプログラムを自動的に実行する  OS起動時に一回だけプログラムを自動的に実行する ・プログラムをファイルの拡張子に関連付ける ・エクスプローラでフォルダやドライブを右クリックしたときに表示  されるコンテキストメニューに項目を追加する ・エクスプローラの新規作成メニューに項目を追加する ─────────────────────────────── ─────────────────────────────── ■.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キーについて詳しくは、以下のマイクロソフトサポート技 術情報をご覧ください。 [URL]マイクロソフト サポート技術情報 - 314866 Windows XP レジストリの Run キーの定義 http://support.microsoft.com/default.aspx?kbid=314866 [URL]マイクロソフト サポート技術情報 - 137367 レジストリの RunOnce キーの定義 http://support.microsoft.com/default.aspx?kbid=137367 [URL]マイクロソフト サポート技術情報 - 179365 [INFO] Run、RunOnce、RunServices、RunServicesOnce レジストリ キーと [スタートアップ] フォルダの関係 http://support.microsoft.com/default.aspx?kbid=179365 [URL]マイクロソフト サポート技術情報 - 232487 RunOnceEx レジストリ キーについて http://support.microsoft.com/default.aspx?kbid=232487 以下に、HKEY_CURRENT_USERのRunキーにアプリケーションの実行ファ イルのパスを登録し、OS起動時に実行されるようにするためのコード を紹介します。Microsoft.Vsa.dllを参照に加える必要があります。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ''' ''' CurrentUserのRunにアプリケーションの実行ファイルパスを登録する ''' Public Shared Sub SetCurrentVersionRun() 'Runキーを開く 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 ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ /// /// CurrentUserのRunにアプリケーションの実行ファイルパスを登録する /// public static void SetCurrentVersionRun() { //Runキーを開く Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey( @"Software\Microsoft\Windows\CurrentVersion\Run", true); //値の名前に製品名、値のデータに実行ファイルのパスを指定し、書き込む regkey.SetValue(Application.ProductName, Application.ExecutablePath); //閉じる regkey.Close(); } ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ─────────────────────────────── ●プログラムをファイルの拡張子に関連付ける これも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 というキーに、名前がなく、データがコマンドラインとなる値を作成 します。 以上は最低限の設定で、さらにアイコンの設定等も必要により行う必 要があります。関連付けに関する詳しい話は、次のサイトが参考にな ります。 [URL]Jet Page - Windows レジストリ 解剖記 http://homepage2.nifty.com/kuri-page/program/winreg.htm なお関連付けによりプログラムが実行された時、プログラムでファイ ルのパスを取得するには、コマンドライン引数を調べます。コマンド ライン引数を取得する方法は、次のページをご覧ください。 [URL]DOBON.NET .NET Tips - 起動時のコマンドライン引数を取得す る http://dobon.net/vb/dotnet/programing/commandline.html 以下に拡張子への関連付けを行うサンプルを示します。ここではアイ コンの設定等も行っています。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ '関連付ける拡張子 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() ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //関連付ける拡張子 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(); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ また、関連付けを削除するには、次のように対象となるすべてのキー を削除します。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ '拡張子 Dim extension As String = ".000" 'ファイルタイプ名 Dim fileType As String = Application.ProductName 'レジストリキーを削除 Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(extension) Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(fileType) ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //拡張子 string extension = ".000"; //ファイルタイプ名 string fileType = Application.ProductName; //レジストリキーを削除 Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(extension); Microsoft.Win32.Registry.ClassesRoot.DeleteSubKeyTree(fileType); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ─────────────────────────────── ●エクスプローラでフォルダやドライブを右クリックしたときに表示  されるコンテキストメニューに項目を追加する エクスプローラでフォルダやドライブを右クリックしたときに表示さ れるコンテキストメニューには、「検索」などの項目が表示されると 思いますが、ここに新たな項目を追加し、指定したプログラムを起動 させる方法を紹介します。 実はこれを行うには、フォルダやドライブに関連付けを行えばよく、 先に紹介した「プログラムをファイルの拡張子に関連付ける」とほと んど同じ方法で実現できます。 「プログラムをファイルの拡張子に関連付ける」では、拡張子と同じ 名前のキーに情報を登録しましたが、フォルダやドライブへの関連付 けでは特別な名前を使用し、フォルダの場合は"Folder"、ドライブの 場合は"Drive"、ファイルフォルダの場合は"Directory"という名前の キーとなります。(「ファイルフォルダ」というのが何なのかはっき り分かりませんが、多分、一般的なローカルなフォルダ(ドライブは 含まない)というような意味ではないでしょうか。また、Folderへの 登録では、フォルダとドライブ、さらに、ゴミ箱、マイネットワーク でも表示されるようです。) この3つ以外にも特別な意味を持つキーがいくつかあります。例えば、 "*"はすべてのファイルを意味し、"AllFileSystemObjects"はすべて のファイルとフォルダを意味します。詳しくは先に紹介した「Jet Page - Windows レジストリ 解剖記」や、次のページ等をご覧くださ い。 [URL]MSDN - Creating Shell Extension Handlers http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_extending/extensionhandlers/shell_ext.asp フォルダへの関連付けにより、エクスプローラでフォルダを右クリッ クしたときに"MyApplicationで開く"を表示させるサンプルを以下に 示します。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ '実行するコマンドライン 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() ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //実行するコマンドライン 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(); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ─────────────────────────────── ●エクスプローラの新規作成メニューに項目を追加する エクスプローラでフォルダを選び、メニューの「ファイル - 新規作 成」(あるいは、右クリックによるコンテキストメニューの「新規作 成」)を選択すると、指定されたタイプのファイルを新しく作成する ことができます。ここではこの「新規作成」メニューに独自の項目を 追加する方法を紹介します。 しつこいようですが、これまた、Windowsとレジストリの知識で、そ の方法は次のページで詳しく紹介されています。 [URL]@IT:Windows TIPS -- Tips:エクスプローラの[新規作成] メニューをカスタマイズする http://www.atmarkit.co.jp/fwin2k/win2ktips/282filenew/filenew.html まずは拡張子への関連付けが必要ですので、「プログラムをファイル の拡張子に関連付ける」により、新規作成に追加したい拡張子を登録 します。 「新規作成」メニューにより作成されるファイルには2種類(注1) あり、サイズ0(空)のファイルか、テンプレートファイルを基にし たファイルになります。 サイズ0のファイルを作成する場合は簡単で、レジストリの HKEY_CLASSES_ROOT\(拡張子)\ShellNew というキーに名前が"NullFile"でデータが""の値を作成するだけです。 テンプレートファイルを使用する場合は、新規作成により作成される ファイルをWindowsのテンプレートフォルダ("System.Environment. GetFolderPath(Environment.SpecialFolder.Templates)"によりパス が取得できます)に置いておき、先と同じShellNewキーに名前が "FileName"でデータがテンプレートのファイル名の値を登録します。 "NullFile"と"FileName"の両方を指定することはできませんが、両方 が存在する場合は、"NullFile"が優先されるようです。 以下にサンプルを示します。まずは、「新規作成」メニューによりサ イズ0のファイルが作成される例です。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ '拡張子 Dim extension As String = ".000" '「新規作成」により、空のファイルを作成 Dim regkey As Microsoft.Win32.RegistryKey = _ Microsoft.Win32.Registry.ClassesRoot.CreateSubKey( _ extension + "\ShellNew") regkey.SetValue("NullFile", "") regkey.Close() ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //拡張子 string extension = ".000"; //「新規作成」により、空のファイルを作成 Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey( extension + "\\ShellNew"); regkey.SetValue("NullFile", ""); regkey.Close(); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ 次にテンプレートファイルを使用した例を示します。 ‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ '拡張子 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() ‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ ‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ //拡張子 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(); ‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ (注1)@IT:Windows TIPSでは2種類しか紹介されていませんが、 実際にはこれ以外に"Command"と"Data"いうのもあります。 名前が"Command"でデータがコマンドラインの値を作成すると、新規 作成の際、指定したコマンドラインが実行されます。これは、ショー トカットを新規作成するときのように、ウィザードによりファイルを 作成するときに使用します。 また、"Data"を名前とする値の場合、データにバイナリ値を指定しま す。 =============================== ■このマガジンの購読、購読中止、バックナンバー、説明に関しては  次のページをご覧ください。  http://www.mag2.com/m/0000104516.htm ■発行人・編集人:どぼん!  (Microsoft MVP for Visual Basic, Oct 2003-Oct 2004)  http://dobon.net  dobon_info@yahoo.co.jp ■ご質問等はメールではなく、掲示板へお願いいたします。  http://dobon.net/vb/bbs.html ■上記メールアドレスへのメールは確実に読まれる保障はありません  (スパム、ウィルス対策です)。メールは下記URLのフォームメール  から送信してください。  http://dobon.net/mail.html Copyright (c) 2003 - 2004 DOBON! All rights reserved. ===============================