1 (изменено: wisgest, 2014-02-11 21:08:53)

Тема: 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 — незначительное изменение, не затрагивающее сути.)

Post's attachments

reg_user.zip 4.25 kb, 7 downloads since 2014-02-11 

You don't have the permssions to download the attachments of this post.

2 (изменено: wisgest, 2014-02-11 18:56:22)

Re: CMD/BAT: Создание файла реестра с подстановкой переменных

Для подобных целей (внесение изменений в реестр с настройкой параметров) существует формат .rgs (Registry Script).

The .RGS syntax is used in ATL C++ projects and is more powerful than
the syntax used in .REG files.

Ресурсы в этом формате можно встретить в PE-файлах (dll, exe…).
Описание формата можно найти здесь: http://msdn.microsoft.com/en-us/library/8350a3tf.aspx.
Обрабатывать самостоятельные rgs-файлы позволяет консольная утилита RGS.exe:

RGS 1.0 registry application for running ATL .RGS files
Freeware developed by Marius Samoila msamoila2004@yahoo.com
Command line:
RGS <registry_script_file.RGS> [<key>=<value> [,...]] [ /u ]

        <key>=<value> the key
                ex: %MODULE% used in .RGS and its replacement value
        /u: unregister

— сайт http://members.shaw.ca/msamoila/, работоспособность пока не проверял, использует библиотеку ATL.dll (скорее всего должна быть уже установлена, по крайней мере, у меня так):

+ открыть спойлер

Remarks

In order to run above programs (sections 2. 3. 6.)  you need to have in your \windows\system32 folder some common DLLs:
DLL name minimal version available on
ATL.DLL 3.0 http://www.dll-files.com/dllindex/dll-files.shtml?atl
MsvCrt.DLL 6.0 http://www.dll-files.com/dllindex/dll-files.shtml?msvcrt


If you already have these DLLs and their version is newer, do not replace them.

After you copy Atl.dll, you must register it before using. Just login as Administrator and execute this command:
>regsvr32 atl.dll