MSDN писал(а):1. Расширение файла (file extension) - это строка, добавляемая к имени файла, состоящая из букв и цифр (рекомендуеться использовать англ. буквы)
2. Вы можете использовать в имени файла несколько периодов (частей разделенных точкой), но только символы рассположенные за последней точкой являються расширением. Все остальные периоды являются частью имени файла.
! НЕ ИСПОЛЬЗУЙТЕ ПРОБЕЛЫ В РАСШИРЕНИЯХ ФАЙЛОВ !
3. Когда вы создаете или изменяете ассоциирование файлов, важно оповестить систему о том что вы внесли изменения. Используйте SHChangeNotify, с событием SHCNE_ASSOCCHANGED. Если вы не оповестите систему, изменения могут быть не приняты (т.е. не работать) до того момента, пока система не будет перезагружена.
Итак, чтобы связать своё приложение с каким-либо типом файлов необходимо в реестре, в ветке HKEY_CLASSES_ROOT создать два раздела, имена которых представляют собой: 1. расширение, которое вы хотите зарегистрировать, 2. название вашей программы.
Например, для того чтобы ассоциировать файлы с расширением ".myp" с программой "MyProgram" необходимо создать следующие разделы реестра:
HKEY_CLASSES_ROOT
.myp - со значением по умолчанию MyProgram.1 (рекомендуеться ставить .1 для того чтобы была возможность создавать новые версии приложения, которые могли бы быть одновременно установленными на одном компьютере)
MyProgram.1 - со значением по умолчанию MyProgram Application (на самом деле сюда следует записывать полное название вашей программы)
так же вы можете привязать к определённому расширению каку-либо иконку, для этого надо создать дополнительный раздел MyProgram.1\DefaultIcon и присвоить его значению по умолчанию путь к файлу иконки, например:
"C:\Program Files\MyProgram\icon.ico" (здесь указываеться файл иконки),
так же можно воспользоваться строкой вида:
"C:\Program Files\MyProgram\myprog.exe,20" (данная строка подразумевает, что у ваc в файле программы, в ресурсах присутствует не менее 20 иконок, причем иконка по умолчанию будет именно 20-ая, если данной иконки не существует, то будет отображаться ярлык "неопозннаого" документа)
Так же необходимо создать ключ "MyApp.1\shell\open\command" и его значением по умолчанию установить строку вида:
"C:\Program Files\MyProgram\myprog.exe %1". Именно это строка отвечает за то, каким приложением будет открываться файл такого типа.
! Так же вы можете сменить "open" на другую строку, и именно она будет появляться при счелчке правой кнопкой мыши по файлу с ассоциированным расширением.
И последнее, для того чтобы ваша программа соответственно реагировала на открытие файла, при запуске (желательно в процедуре Main, до появления каких-либо окон приложения) проверять параметр командной строки, и если там передаеться имя како-го либо файла, сразу же открывать его, ну а если командная строка пуста, или там содержиться ссылка на несуществующий файл, можно спокойно спрашивать у пользователя, какой файл открыть...
Оповещение системы, о внесении изминений в ассоциирование файлов. Необходимо вызвать ф-ию SHChangeNotify с wEventId равным SHCNE_ASSOCCHANGED, и uFlags равным SHCNF_IDLIST.
Вот описание данной ф-ии и констант для VB 6:
MSDN писал(а):Private Declare Sub SHChangeNotify Lib "shell32.dll" _
(ByVal wEventId As Long, _
ByVal uFlags As Long, _
dwItem1 As Any, _
dwItem2 As Any)
Const SHCNE_ASSOCCHANGED = &H8000000
Const SHCNF_IDLIST = &H0&
а вот для VB.NET
MSDN писал(а):Private Declare Sub SHChangeNotify Lib "shell32.dll" (ByVal wEventId As Integer, ByVal uFlags As Integer, ByVal dwItem1 As Integer, ByVal dwItem2 As Integer)
Const SHCNE_ASSOCCHANGED = &H8000000
Const SHCNF_IDLIST = &H0&
Так же существуют дополнительные возможности по настройке работы с расширениями файлов, о них вы можете прочитать вот тут.
Теперь я хочу предложить вам вариант реализации процедуры регистрации расширения для VB 6. Данный код являеться просто примером, в нём не производиться проверка на ошибки, что безусловно должно присутствовать. Для обработки ошибок дополните код, сравнивая результат функций работы с реестром со значениями определённых в коде констант. Т.е. лишь тогда, когда значение переменной ret равно нулю мы можем утверждать, что при работе с реестром не произошло никаких ошибок.
- Код: Выделить всё
' Функции API необходимые для работы с реестром
Private Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegSetValue Lib "advapi32.dll" Alias "RegSetValueA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal dwType As Long, ByVal lpData As String, ByVal cbData As Long) As Long
Private Declare Sub SHChangeNotify Lib "shell32.dll" (ByVal wEventId As Long, ByVal uFlags As Long, dwItem1 As Any, dwItem2 As Any)
Const SHCNE_ASSOCCHANGED = &H8000000
Const SHCNF_IDLIST = &H0&
' Возможные варианты результатов функций работы с реестром
Const ERROR_SUCCESS = 0&
Const ERROR_BADDB = 1&
Const ERROR_BADKEY = 2&
Const ERROR_CANTOPEN = 3&
Const ERROR_CANTREAD = 4&
Const ERROR_CANTWRITE = 5&
Const ERROR_OUTOFMEMORY = 6&
Const ERROR_INVALID_PARAMETER = 7&
Const ERROR_ACCESS_DENIED = 8&
Private Const HKEY_CLASSES_ROOT = &H80000000
Private Const MAX_PATH = 260&
Private Const REG_SZ = 1
'
Sub AssExtension()
Dim sKeyName As String
Dim sKeyValue As String
Dim ret as Long
Dim lphKey as Long
'Создание раздела программы
sKeyName = "MyApp.1" ' Название приложения
sKeyValue = "My Application 1" ' Полное название, так же возможно краткое описание
ret = RegCreateKey(HKEY_CLASSES_ROOT, sKeyName, lphKey)
ret = RegSetValue(lphKey, "", REG_SZ, sKeyValue, 0&)
'Создание раздела, для использования иконки.
sKeyName = "MyApp.1\DefaultIcon" ' Название приложения
sKeyValue = "C:\Program Files\MyProgram\myprog.exe,0" ' Путь к используемой иконке
ret = RegCreateKey(HKEY_CLASSES_ROOT, sKeyName, lphKey)
ret = RegSetValue(lphKey, "", REG_SZ, sKeyValue, 0&)
'Создание раздела, относящегося к расширению
sKeyName = ".myp" ' Регистрируемое расширение
sKeyValue = "MyApp.1" ' Приложение, с которым связываеться данное расширение
ret = RegCreateKey(HKEY_CLASSES_ROOT, sKeyName, lphKey)
ret = RegSetValue(lphKey, "", REG_SZ, sKeyValue, 0&)
'Коммандная линия для приложения"MyApp".
sKeyName = "MyApp.1"
sKeyValue = "C:\Program Files\MyProgram\myprog.exe %1"
ret = RegCreateKey(HKEY_CLASSES_ROOT, sKeyName, lphKey)
ret = RegSetValue(lphKey, "shell\open\command", REG_SZ, sKeyValue, MAX_PATH)
Call SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0)
End Sub
Итак: процедура регистрации расширения на VB.NET.
В данной процедуре, при внутренних ошибках вызывается (а так же ошибках доступа к реестру и др.) исключение, содержащие описание ошибки (в поле Message).
- Код: Выделить всё
Private Declare Sub SHChangeNotify Lib "shell32.dll" (ByVal wEventId As Integer, ByVal uFlags As Integer, ByVal dwItem1 As Integer, ByVal dwItem2 As Integer)
Const SHCNE_ASSOCCHANGED = &H8000000
Const SHCNF_IDLIST = &H0&
Public Sub AssociateExtension(ByVal Extension As String, ByVal ProgramName As String, ByVal Description As String, ByVal DefaultIcon As String, ByVal CommandLine As String, ByVal RemoveExistingAssociation As Boolean)
'Передаваемые параметры:
'Extension - имя расширения
'ProgramName - название программы
'Description - описание программы
'DefaultIcon - путь к иконке, для регистрируемого расширения
'CommandLine - путь к программе, для открытия файлов такого типа
'RemoveExistingAssociation - если параметр будет равен True, тогда предыдущее
'асоциирование с данным расширением будет удалено (если оно конечно есть)
'Переменные для работы с реестром
Dim RegHKCR As Microsoft.Win32.RegistryKey
Dim RegTempKey, RegTempKey2 As Microsoft.Win32.RegistryKey
'Исключение, вызываемое при каких-либо ошибках
Dim AssociateExtensionExeption As Exception
Try
RegHKCR = Microsoft.Win32.Registry.ClassesRoot
Catch ex As Exception
If Not RegHKCR Is Nothing Then RegHKCR.Close()
AssociateExtensionExeption = New Exception(ex.Message)
Throw AssociateExtensionExeption
End Try
'Сначала проверяем параметры на допустимость
'Удаляем все пробелы из имени расширения и названия программы
Extension = Extension.Replace(" ", "")
ProgramName = ProgramName.Replace(" ", "")
'Удаляем все точки перед и после названия программы
Do While ProgramName.Length > 0
If ProgramName.Chars(0) = "." Then
ProgramName = ProgramName.Remove(0, 1)
ElseIf ProgramName.Chars(ProgramName.Length - 1) = "." Then
ProgramName = ProgramName.Remove(0, 1)
Else
Exit Do
End If
Loop
'Имя программы не должно представлять собой нулевую строку, а так же его
'длинна не должна превышать 255 символов
If ProgramName.Length = 0 Or ProgramName.Length > 255 Then
RegHKCR.Close()
AssociateExtensionExeption = New Exception("Недопусимое имя программы.")
Throw AssociateExtensionExeption
End If
'Проверяем: возможно программа с таким именем уже существует
Try
RegTempKey = RegHKCR.OpenSubKey(ProgramName, True)
Catch ex As Exception
RegHKCR.Close()
AssociateExtensionExeption = New Exception(ex.Message)
Throw AssociateExtensionExeption
End Try
If Not RegTempKey Is Nothing Then
RegTempKey.Close()
RegHKCR.Close()
AssociateExtensionExeption = New Exception("Программа с таким именем уже существует")
Throw AssociateExtensionExeption
End If
'Предварительно убераем все точки в имени расширения
Extension = Extension.Replace(".", "")
'Предполагается, что расширение (без точек) не может быть нулевой строкой,
'а так же превышать 5 символов.
If Extension.Length = 0 Or Extension.Length > 5 Then
RegHKCR.Close()
AssociateExtensionExeption = New Exception("Недопусимое имя расширения.")
Throw AssociateExtensionExeption
End If
'Далее ставим точку перед расширением
Extension = "." & Extension
'Проверяем: возможно такое расширение уже существует
Try
RegTempKey = RegHKCR.OpenSubKey(Extension, True)
Catch ex As Exception
RegHKCR.Close()
AssociateExtensionExeption = New Exception(ex.Message)
Throw AssociateExtensionExeption
End Try
If Not RegTempKey Is Nothing Then
RegTempKey.Close()
If RemoveExistingAssociation Then
Try
RegHKCR.DeleteSubKeyTree(Extension)
Catch ex As Exception
RegHKCR.Close()
AssociateExtensionExeption = New Exception(ex.Message)
Throw AssociateExtensionExeption
End Try
Else
RegHKCR.Close()
AssociateExtensionExeption = New Exception("Такое расширение уже существует")
Throw AssociateExtensionExeption
End If
End If
'Убераем лишние пробелы из описания и пути к иконке по умолчанию
Description = Trim(Description)
DefaultIcon = Trim(DefaultIcon)
'Если описание программы представляет собой нулевую строку, то записыаем
'в него имя программы
If Description.Length = 0 Then Description = ProgramName
' *************************************************************************
' ! Сейчас в коде нет проверки описания и пути (к иконке) на корректность !
' ! так же не производится проверка командной строки на запуск приложения !
' ! возможно, что всё появится в ближайшее вермя, просто пока писать лень !
' *************************************************************************
'Итак на данный момент не существует программы и расширения с заданными именами
'так что можно спокойно начинать записывать необходимые разделы и значения
'Создаем раздел с именем расширения, и записываем его значением по умолчанию
'имя программы
Try
RegTempKey = RegHKCR.CreateSubKey(Extension)
RegTempKey.SetValue("", ProgramName)
RegTempKey.Flush()
Catch ex As Exception
RegHKCR.Close()
AssociateExtensionExeption = New Exception(ex.Message)
Throw AssociateExtensionExeption
Finally
If Not RegTempKey Is Nothing Then
RegTempKey.Close()
RegTempKey = Nothing
End If
End Try
Try
'Создаем раздел с названием программы
RegTempKey = RegHKCR.CreateSubKey(ProgramName)
RegTempKey.SetValue("", Description)
RegTempKey.Flush()
'Создаем раздел с иконкой для файлов
If DefaultIcon.Length <> 0 Then
RegTempKey2 = RegTempKey.CreateSubKey("DefaultIcon")
RegTempKey2.SetValue("", DefaultIcon)
RegTempKey2.Flush()
RegTempKey2.Close()
RegTempKey2 = Nothing
End If
'Создаем раздел, отвечающий за запуск файлов
If CommandLine.Length <> 0 Then
'Указанная здесь строка будет отображаться при счелчке правой кнопкой мыши по
'файлу с регистрируемым расширением
Dim CommandName As String = "open"
RegTempKey2 = RegTempKey.CreateSubKey("shell" & CommandName & "\command")
RegTempKey2.SetValue("", CommandLine)
RegTempKey.Flush()
RegTempKey2.Close()
RegTempKey2 = Nothing
End If
Catch ex As Exception
AssociateExtensionExeption = New Exception(ex.Message)
Throw AssociateExtensionExeption
Finally
If Not RegTempKey Is Nothing Then RegTempKey.Close()
If Not RegTempKey2 Is Nothing Then RegTempKey2.Close()
RegHKCR.Close()
End Try
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0)
End Sub
---
Все замечания и дополнения пишите в личные сообщения, или сюда: FAQ.VBStreets@areh.ru
vbskb_assoc vbskb_reg vbskb_tricks