Тема: CMD/BAT: Создание файла реестра с подстановкой переменных
Пример внесения изменений в реестр с помощью создаваемого во время работы reg-файла, содержание которого зависит от настроек.
Это лишь возможное решение, не обязательно лучшее (кое-что меня не до конца устраивает, но выкладываю пока то, что есть), но пример полностью рабочий. Замечания приветствуется.
Этот командный файл предназначен для регистрации библиотеки KiXforms только для текущего пользователя, и должен находится в том же каталоге, что и kixforms.dll.
Т.е. переменной частью создаваемого файла реестра является путь к содержащему файл каталогу. Этот путь может содержать любые допустимые символы, т.к. файл рестра создаётся в юникоде.
Т.к. для создания файла реестра в юникоде требуется вывод в его начале двух байтов BOM, то приводимый командный файл содержит непечатные знаки (в строке 89) и поэтому дополнительно содержится в присоединённом архиве. Также архив включает безопасную версию, в которой закомментированны завершение работы при отсутствие kixforms.dll и действительное внесение изменений в реестр.
@if /i not "%~1"=="/u" (cmd.exe /u /d /c call "%~f0" /u&exit /b 2>nul)
:: Заменить строку 1 разбором %cmdcmdline%?..
@echo on
@setlocal enableextensions enabledelayedexpansion
@echo Регистрация библиотеки KiXforms для текущего пользователя
@echo Пользователь: !USERNAME!@!USERDOMAIN!
:: Коды возврата:
:: 1 - действие отменено пользователем
:: 2 - не найден файл kixforms.dll
:: 3 - ошибка при создании файла реестра
:: 4 - ошибка REG.EXE
@echo:
@set "x="
@set /p "x=Продолжить [N - нет]? "
@if /i !x!==N endlocal&exit /b 1
@set "prompt=%~nx0> "
@set "HKEY_CLASSES_ROOT=HKEY_CURRENT_USER\Software\Classes"
@pushd "%~dp0"
@for %%F in (kixforms.dll) do @(
if not exist "%%~F" (
echo Не найден файл "%%~fF".
endlocal&pause&exit /b 2
)
set "DIR=%%~dpF"
)
@popd
@set "DIR=%DIR:\=\\%"
@echo:
@set /p=Создание файла вносимых в реестр изменений. . .<nul
@(for %%Z in (.) do call :MakeRegFile>"%TEMP%\kixforms.reg")<"%~f0"||(
endlocal&pause&exit /b 3
)
@echo:
@set "x="
@set /p "x=Предварительно показать вносимые в реестр изменения [Y - да]? "
@if /i !x!==Y (
set /p=Для продолжения может понадобиться закрыть текстовый редактор . . .<nul
for %%Z in (.) do notepad.exe "%TEMP%\kixforms.reg"
echo:
set "x="
set /p "x=Продолжить [N - нет]? "
if /i !x!==N set "exitcode=1"
) else set "x=Y"
@if /i not !x!==N (
echo:
set /p=Внесение изменений в реестр . . .<nul
(for %%I in (.) do reg.exe import "%TEMP%\kixforms.reg"
)&&set exitcode=0||set exitcode=4
pause
)
@echo:
@set /p=Удаление временного файла реестра. . .<nul
del "%TEMP%\kixforms.reg"
:: DEL не устанавливет код ошибки
@if exist "%TEMP%\kixforms.reg" pause
@endlocal&exit /b %exitcode%
:MakeRegFile
@call :BOM
@setlocal enableextensions enabledelayedexpansion
:MakeRegFile.1
@(
set "line="
set /p "line="
if not "!line!"=="Windows Registry Editor Version 5.00" goto %0.1
)
:MakeRegFile.2
@ echo:%line%
@(
set "line="
set /p "line="
if !line!==[END] goto %0.3
goto %0.2
)
:MakeRegFile.3
@endlocal
@exit /b 0
:BOM
@cmd.exe /a /d /c set /p p= ?<nul
@exit /b
:::::::::::::::::::::::::::::::::::::
Windows Registry Editor Version 5.00
; Файл реестра для регистрации библиотеки KiXforms для текущего пользователя.
; Создан '!prompt:~,-2!' !date! в !time!
; с учётом при его создании расположения файла 'kixforms.dll'.
[-!HKEY_CLASSES_ROOT!\CLSID\{F89DF848-618A-46F9-8A1C-396EA442BDD3}]
[!HKEY_CLASSES_ROOT!\CLSID\{F89DF848-618A-46F9-8A1C-396EA442BDD3}]
@="Widget Class"
[!HKEY_CLASSES_ROOT!\CLSID\{F89DF848-618A-46F9-8A1C-396EA442BDD3}\InprocServer32]
@="!DIR!kixforms.dll"
"ThreadingModel"="both"
[!HKEY_CLASSES_ROOT!\CLSID\{F89DF848-618A-46F9-8A1C-396EA442BDD3}\ProgID]
@="Kixtart.Form"
[!HKEY_CLASSES_ROOT!\CLSID\{F89DF848-618A-46F9-8A1C-396EA442BDD3}\VersionIndependentProgID]
@="Kixtart.Form"
[!HKEY_CLASSES_ROOT!\Kixtart.Form]
@="Widget Class"
[!HKEY_CLASSES_ROOT!\Kixtart.Form\CLSID]
@="{F89DF848-618A-46F9-8A1C-396EA442BDD3}"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[-!HKEY_CLASSES_ROOT!\CLSID\{C9A8E0D2-1D16-4EA4-9EA4-54F08D9C0D17}]
[!HKEY_CLASSES_ROOT!\CLSID\{C9A8E0D2-1D16-4EA4-9EA4-54F08D9C0D17}]
@="Dialogs Class"
[!HKEY_CLASSES_ROOT!\CLSID\{C9A8E0D2-1D16-4EA4-9EA4-54F08D9C0D17}\InprocServer32]
@="!DIR!kixforms.dll"
"ThreadingModel"="both"
[!HKEY_CLASSES_ROOT!\CLSID\{C9A8E0D2-1D16-4EA4-9EA4-54F08D9C0D17}\ProgID]
@="Kixtart.Forms.Dialogs"
[!HKEY_CLASSES_ROOT!\CLSID\{C9A8E0D2-1D16-4EA4-9EA4-54F08D9C0D17}\VersionIndependentProgID]
@="Kixtart.Forms.Dialogs"
[!HKEY_CLASSES_ROOT!\Kixtart.Forms.Dialogs]
@="Dialogs Class"
[!HKEY_CLASSES_ROOT!\Kixtart.Forms.Dialogs\CLSID]
@="{C9A8E0D2-1D16-4EA4-9EA4-54F08D9C0D17}"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[-!HKEY_CLASSES_ROOT!\CLSID\{FEEC1680-5609-4A96-847D-4585CEB24ED4}]
[!HKEY_CLASSES_ROOT!\CLSID\{FEEC1680-5609-4A96-847D-4585CEB24ED4}]
@="System Class"
[!HKEY_CLASSES_ROOT!\CLSID\{FEEC1680-5609-4A96-847D-4585CEB24ED4}\InprocServer32]
@="!DIR!kixforms.dll"
"ThreadingModel"="both"
[!HKEY_CLASSES_ROOT!\CLSID\{FEEC1680-5609-4A96-847D-4585CEB24ED4}\ProgID]
@="Kixtart.System.1"
[!HKEY_CLASSES_ROOT!\CLSID\{FEEC1680-5609-4A96-847D-4585CEB24ED4}\VersionIndependentProgID]
@="Kixtart.System"
[!HKEY_CLASSES_ROOT!\Kixtart.System.1]
@="System Class"
[!HKEY_CLASSES_ROOT!\Kixtart.System.1\CLSID]
@="{FEEC1680-5609-4A96-847D-4585CEB24ED4}"
[!HKEY_CLASSES_ROOT!\Kixtart.System]
@="System Class"
[!HKEY_CLASSES_ROOT!\Kixtart.System\CLSID]
@="{FEEC1680-5609-4A96-847D-4585CEB24ED4}"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[!HKEY_CLASSES_ROOT!\TypeLib\{C8DCCD39-471D-4AFD-8EA2-89604A9C6252}\1.0]
@="Kixforms 1.0 Type Library"
[!HKEY_CLASSES_ROOT!\TypeLib\{C8DCCD39-471D-4AFD-8EA2-89604A9C6252}\1.0\0\win32]
@="!DIR!kixforms.dll"
[!HKEY_CLASSES_ROOT!\TypeLib\{C8DCCD39-471D-4AFD-8EA2-89604A9C6252}\1.0\FLAGS]
@="0"
[!HKEY_CLASSES_ROOT!\TypeLib\{C8DCCD39-471D-4AFD-8EA2-89604A9C6252}\1.0\HELPDIR]
@="!DIR!"
[END]
Если воспользоваться этим командным файлом по назначению, то отменить регистрацию библиотеки можно обычным образом, вызвав от имени текущего пользователя:
regsvr32.exe /u kixforms.dll(11.02.2014 — незначительное изменение, не затрагивающее сути.)

