Создание Reg файлов из внутренних ассоциаций ТС
Select messages from
# through # FAQ
[/[Print]\]

Total Commander -> Автоматизация Total Commander

#1: Создание Reg файлов из внутренних ассоциаций ТС Author: Andrey_ALocation: Сочи PostPosted: Thu Jan 21, 2010 03:20
    —
Наверняка, кто-то сталкивался с тем, что есть разница между открыванием файлов в Тотале и проводнике... и значки расширений отличаются...
Хотелось бы видеть и открывать в проводнике тем, чем ты это делаешь в Тотале!!!
Пришла мысль, помогите осуществить: сканирование внутренних ассоциаций (т.е. раздела [Associations] в wincmd.ini) и создание из них Reg файлов.
Как я вижу решение этой задачи:
Нужен наверное скрипт, который бы читал строки

Filter1=*.avi;*.mpg;*.wmv
Filter1_open=""%COMMANDER_PATH%\Programs\VideoLAN\vlc.exe" "%1""
Filter1.icon=Wcmicons.dll,1582

и создавал бы для каждого расширения ДВА именных Reg файла в отдельной папке
1. Один для ассоциирования иконки с расширением:
Code:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.avi]
@="avifile"

[HKEY_CLASSES_ROOT\avifile]

[HKEY_CLASSES_ROOT\avifile\DefaultIcon]
@="C:\\Total Commander\\Wcmicons.dll,1600"


2. Другой для ассоциирования программы с раширением:
Code:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.avi]
@="avifile"

[HKEY_CLASSES_ROOT\avifile]

[HKEY_CLASSES_ROOT\avifile\shell]

[HKEY_CLASSES_ROOT\avifile\shell\open]

[HKEY_CLASSES_ROOT\avifile\shell\open\command]
@="\"C:\\Total Commander\\Programs\\VideoLAN\\vlc.exe\" \"%1\""

(с синтаксисом мог и напутать, но главное принцип)

Файлы сохраняются в две папки:
- первый с именем (к примеру avi_icon.reg) в заданную папку ICONS_REG
- второй с именем расширения (к примеру avi.reg) в заданную папку RASHIRENIE_REG

И так для каждого расширения найденного в ассоциациях, сканируя каждое расширение в Filter1...., потом Filter2...., Filter3...

Почему два файла и по разным папкам?
На чужих машинах свои ассоциации не поставишь, а вот родные иконки для всех файлов можно (запустил все рег файлы из папки ICONS_REG и в проводнике уже что-то своё)
(кроме этого в ассоциациях есть файлы где нет ассоциированных программ, а только иконки , к примеру
Filter105=*.cmd
Filter105.icon=Wcmicons.dll,1651
тогда создаётся только один файл cmd_icon.reg в папке ICONS_REG)

На тех системах где можно - запускаешь все файлы из обеих папок - и тогда в проводнике всё то, что в Тотале
Надеюсь найдутся те, кому эта идея понравится и она дойдёт до осуществления

#2:  Author: BatyaLocation: Москва, Россия PostPosted: Thu Jan 21, 2010 10:53
    —
Andrey_A wrote:
Пришла мысль, помогите осуществить: сканирование внутренних ассоциаций (т.е. раздела [Associations] в wincmd.ini) и создание из них Reg файлов.
Как я вижу решение этой задачи:
Нужен наверное скрипт, который бы читал строки

Я - пас.
Не обижайся, но мне кажется, что твоё желание всё по максимуму автоматизировать стало приобретать маниакальные масштабы Shocked

#3:  Author: Loopback PostPosted: Thu Jan 21, 2010 11:58
    —
Лично мне затея представляется несколько сомнительной, поскольку на чужих машинах как раз и удобнее использовать внутренние ассоциации. Но задача в целом несложная, вот написал такой скрипт (Autoit3):

Code:

$TC_INI = EnvGet("COMMANDER_INI")

$aAssocList = _TCHConListRead($TC_INI, "Associations", "Filter@|Filter@_open|Filter@.icon", 1)

For $i = 1 To $aAssocList[0][0]
    $aExt = StringSplit($aAssocList[$i][0], ";")
    For $j = 1 To $aExt[0]
        $sCurExt = StringTrimLeft(StringStripWS($aExt[$j], 3), 2)
        $sIconFile = @ScriptDir & "\ICON_REG\" & $sCurExt & "_icon.reg"
        $sProgFile = @ScriptDir & "\PROG_REG\" & $sCurExt & "_prog.reg"
        ; программы
        $hFile = FileOpen($sProgFile, 2+8+32)
        FileWriteLine($hFile, "Windows Registry Editor Version 5.00" & @CRLF & @CRLF)
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\.%s]\r\n@=%sfile\r\n\r\n", $sCurExt, $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell\\open]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell\\open\\command]\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat('@="\"%s\" \"%1\"', _TCHExpandEnv($aAssocList[$i][1])))
        FileClose($hFile)
        ; иконки
        $hFile = FileOpen($sIconFile, 2+8+32)
        FileWriteLine($hFile, "Windows Registry Editor Version 5.00" & @CRLF & @CRLF)
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\.%s]\r\n@=%sfile\r\n\r\n", $sCurExt, $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat('[HKEY_CLASSES_ROOT\\%sfile\\DefaultIcon]\r\n', $sCurExt))
        FileWriteLine($hFile, StringFormat('@="%s"', _TCHExpandEnv($aAssocList[$i][2])))
        FileClose($hFile)
    Next
Next

; функция чтения списков "со счетчиком"
Func _TCHConListRead($sIniName, $sSection, $sKeysFormat, $nStartCount = 0)
    Local $nNewIdx, $sErrStr = "<<none>>"
    Local $aKeyNames = StringSplit($sKeysFormat, "|")
    Local $nKeys = $aKeyNames[0]
    Local $aResult[1][$nKeys] = [[0, $nKeys]]
    Local $sRedirect = IniRead($sIniName, $sSection, "RedirectSection", $sErrStr)
    If $sRedirect <> $sErrStr Then
        $sRedirName = StringRegExpReplace($sIniName, "(.+\\)([^\\]+)", "\1")
        $sIniName = $sRedirName & $sRedirect
    EndIf
    While 1
        $sCurVal = IniRead($sIniName, $sSection, StringReplace($aKeyNames[1], "@", $aResult[0][0]+$nStartCount), $sErrStr)
        If $sCurVal <> $sErrStr Then
            $aResult[0][0] += 1
            $nNewIdx = $aResult[0][0]
            ReDim $aResult[$nNewIdx+1][$nKeys]
            $aResult[$nNewIdx][0] = $sCurVal
            For $i = 2 To $aKeyNames[0]
                $sCurVal = IniRead($sIniName, $sSection, StringReplace($aKeyNames[$i], "@", $aResult[0][0]-1+$nStartCount), $sErrStr)
                If $sCurVal <> $sErrStr Then $aResult[$nNewIdx][$i-1] = $sCurVal
            Next
        Else
            Return $aResult
        EndIf
    Wend
EndFunc

; функция разворачивания переменных окружения
Func _TCHExpandEnv($sText)
    $aResult = StringRegExp($sText, "%(\w+)%", 3)
    If IsArray($aResult) Then
        For $i = 0 To UBound($aResult)-1
            $sText = StringReplace($sText, "%" & $aResult[$i] & "%", EnvGet($aResult[$i]))
        Next
    EndIf
    Return $sText
EndFunc


Разумеется, есть ограничения - будет работать, только если в фильтре - простой список расширений. Запускать скрипт надо только из тотала, чтобы он правильно получил путь к ini.

#4:  Author: CaptainFlintLocation: Москва PostPosted: Thu Jan 21, 2010 13:36
    —
Не забудьте такой момент, что если таким способом переназначить только значок, то файл может перестать запускаться. Если с системе уже был класс avifile, то всё будет нормально, а если нет? Тогда он создастся пустой — с одним лишь значком и без единой привязки к программам, система не будет знать, чем этот .avi открывать.

#5:  Author: Andrey_ALocation: Сочи PostPosted: Thu Jan 21, 2010 15:49
    —
Огромное спасибо за понимание Loopback, файлы создаются, но есть небольшая загвоздка:
в файлах в папке Prog_reg вместо строки
@="\"C:\\Total Commander\\Programs\\VideoLAN\\vlc.exe\" \"%1\""

прописывается

@="@"C:\Total Commander\Programs\VideoLAN\\vlc.exe" "%1"

в файлах в папке Icon_reg вместо строки

@="C:\\Total Commander\\Wcmicons.dll,1584"

прописывается

@="C:\Total Commander\Wcmicons.dll,1582"

если это можно исправить, я буду очень признателен

а то, что касается Маньяка в коментариях Batya это комплимент для меня, мне понравилось - когда я 10 месяцев назад подключился к этому форуму, я всех считал маньяками-фанатами в своём роде, тех кто делал невероятное со скриптами, батниками...
Конечно же не любое "маньячество" и я приветствую, но автоматизация для меня - это не прихоть, а экономия времени, как и для других, наверное

#6:  Author: Loopback PostPosted: Thu Jan 21, 2010 18:47
    —
Да, что-то заблудился я в кавычках и слешах... Вот исправленный вариант.

Code:

$TC_INI = EnvGet("COMMANDER_INI")

$aAssocList = _TCHConListRead($TC_INI, "Associations", "Filter@|Filter@_open|Filter@.icon", 1)

For $i = 1 To $aAssocList[0][0]
    $aExt = StringSplit($aAssocList[$i][0], ";")
    For $j = 1 To $aExt[0]
        $sCurExt = StringTrimLeft(StringStripWS($aExt[$j], 3), 2)
        $sIconFile = @ScriptDir & "\ICON_REG\" & $sCurExt & "_icon.reg"
        $sProgFile = @ScriptDir & "\PROG_REG\" & $sCurExt & "_prog.reg"
        ; программы
        $hFile = FileOpen($sProgFile, 2+8+32)
        FileWriteLine($hFile, "Windows Registry Editor Version 5.00" & @CRLF & @CRLF)
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\.%s]\r\n@=%sfile\r\n\r\n", $sCurExt, $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell\\open]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell\\open\\command]\r\n", $sCurExt))
        $sProgPath = _TCHExpandEnv($aAssocList[$i][1])
        $sProgPath = StringLeft($sProgPath, StringInStr($sProgPath, '"')-1)
        $sProgPath = StringReplace(StringStripWS($sProgPath, 3), "\", "\\")
        FileWriteLine($hFile, StringFormat('@="\\"%s\\" \\"\%1\\""', $sProgPath))
        FileClose($hFile)
        ; иконки
        $hFile = FileOpen($sIconFile, 2+8+32)
        FileWriteLine($hFile, "Windows Registry Editor Version 5.00" & @CRLF & @CRLF)
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\.%s]\r\n@=%sfile\r\n\r\n", $sCurExt, $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat('[HKEY_CLASSES_ROOT\\%sfile\\DefaultIcon]\r\n', $sCurExt))
        $sIconPath = _TCHExpandEnv($aAssocList[$i][2])
        $sIconPath = StringReplace($sIconPath, "\", "\\")
        FileWriteLine($hFile, StringFormat('@="%s"', $sIconPath))
        FileClose($hFile)
    Next
Next

; функция чтения "последовательных" списков
Func _TCHConListRead($sIniName, $sSection, $sKeysFormat, $nStartCount = 0)
    Local $nNewIdx, $sErrStr = "<<none>>"
    Local $aKeyNames = StringSplit($sKeysFormat, "|")
    Local $nKeys = $aKeyNames[0]
    Local $aResult[1][$nKeys] = [[0, $nKeys]]
    Local $sRedirect = IniRead($sIniName, $sSection, "RedirectSection", $sErrStr)
    If $sRedirect <> $sErrStr Then
        $sRedirName = StringRegExpReplace($sIniName, "(.+\\)([^\\]+)", "\1")
        $sIniName = $sRedirName & $sRedirect
    EndIf
    While 1
        $sCurVal = IniRead($sIniName, $sSection, StringReplace($aKeyNames[1], "@", $aResult[0][0]+$nStartCount), $sErrStr)
        If $sCurVal <> $sErrStr Then
            $aResult[0][0] += 1
            $nNewIdx = $aResult[0][0]
            ReDim $aResult[$nNewIdx+1][$nKeys]
            $aResult[$nNewIdx][0] = $sCurVal
            For $i = 2 To $aKeyNames[0]
                $sCurVal = IniRead($sIniName, $sSection, StringReplace($aKeyNames[$i], "@", $aResult[0][0]-1+$nStartCount), $sErrStr)
                If $sCurVal <> $sErrStr Then $aResult[$nNewIdx][$i-1] = $sCurVal
            Next
        Else
            Return $aResult
        EndIf
    Wend
EndFunc

; функция разворачивания переменных окружения
Func _TCHExpandEnv($sText)
    $aResult = StringRegExp($sText, "%(\w+)%", 3)
    If IsArray($aResult) Then
        For $i = 0 To UBound($aResult)-1
            $sText = StringReplace($sText, "%" & $aResult[$i] & "%", EnvGet($aResult[$i]))
        Next
    EndIf
    Return $sText
EndFunc

#7:  Author: Andrey_ALocation: Сочи PostPosted: Thu Jan 21, 2010 22:56
    —
с файлами в папке Icon_reg всё нормально, вот в папке Prog_reg
последняя строка везде одинаковая @="\"\" \"%1\""

#8:  Author: Loopback PostPosted: Thu Jan 21, 2010 23:45
    —
Нашел в чем проблема, первый пост помог Smile Почему-то у меня в коммандере ассоциации без внешних кавычек - наверное, все пути к программам были короткие. Переделал извлечение пути.

Нужно заменить этот кусок кода.
Code:

        ; программы
        $hFile = FileOpen($sProgFile, 2+8+32)
        FileWriteLine($hFile, "Windows Registry Editor Version 5.00" & @CRLF & @CRLF)
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\.%s]\r\n@=%sfile\r\n\r\n", $sCurExt, $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell\\open]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell\\open\\command]\r\n", $sCurExt))
        $sProgPath = _TCHExpandEnv($aAssocList[$i][1])
        $sProgPath = StringRegExpReplace($sProgPath, '"*([^"]+)\s*".+"', '\1')
        $sProgPath = StringReplace($sProgPath, "\", "\\")
        FileWriteLine($hFile, StringFormat('@="\\"%s\\" \\"%1\\""', $sProgPath))
        FileClose($hFile)

#9:  Author: Andrey_ALocation: Сочи PostPosted: Fri Jan 22, 2010 01:31
    —
извиняюсь за настойчивость, ещё пару ньюансов
1. в обоих папках во всех файлах должно быть
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.avi]
@="avifile"
а выходит
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.avi]
@=avifile (т.е. не хватает ковычек) (я и сам заметил это только что)

2. Последнее исправление в папке Prog_reg выдаёт:

@="\"C:\\Total Commander\\Programs\\VideoLAN\\vlc.exe\" \"
а должно:
@="\"C:\\Total Commander\\Programs\\VideoLAN\\vlc.exe\" \"%1\""

#10:  Author: Loopback PostPosted: Fri Jan 22, 2010 11:04
    —
По-видимому, у нас разные версии Autoit, и функция форматирования работает по-разному, а значит в какой-то из них - баг. Переделал другим способом, тем более что использование форматирования было не очень-то и оправданно.

Нужно заменить этот кусок кода.
Code:

For $i = 1 To $aAssocList[0][0]
    $aExt = StringSplit($aAssocList[$i][0], ";")
    For $j = 1 To $aExt[0]
        $sCurExt = StringTrimLeft(StringStripWS($aExt[$j], 3), 2)
        $sIconFile = @ScriptDir & "\ICON_REG\" & $sCurExt & "_icon.reg"
        $sProgFile = @ScriptDir & "\PROG_REG\" & $sCurExt & "_prog.reg"
        ; программы
        $hFile = FileOpen($sProgFile, 2+8+32)
        FileWriteLine($hFile, "Windows Registry Editor Version 5.00" & @CRLF & @CRLF)
        FileWriteLine($hFile, StringFormat('[HKEY_CLASSES_ROOT\\.%s]\r\n@="%sfile"\r\n\r\n', $sCurExt, $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell\\open]\r\n\r\n", $sCurExt))
        FileWriteLine($hFile, StringFormat("[HKEY_CLASSES_ROOT\\%sfile\\shell\\open\\command]\r\n", $sCurExt))
        $sProgPath = _TCHExpandEnv($aAssocList[$i][1])
        $sProgPath = StringRegExpReplace($sProgPath, '"*([^"]+)\s*".+"', '\1')
        $sProgPath = StringReplace(StringStripWS($sProgPath, 3), "\", "\\")
        FileWriteLine($hFile, '@="\"' & $sProgPath & '\" \"%1\""')
        FileClose($hFile)
        ; иконки
        $hFile = FileOpen($sIconFile, 2+8+32)
        FileWriteLine($hFile, "Windows Registry Editor Version 5.00" & @CRLF & @CRLF)
        FileWriteLine($hFile, StringFormat('[HKEY_CLASSES_ROOT\\.%s]\r\n@="%sfile"\r\n\r\n', $sCurExt, $sCurExt))
        FileWriteLine($hFile, StringFormat('[HKEY_CLASSES_ROOT\\%sfile]\r\n\r\n', $sCurExt))
        FileWriteLine($hFile, StringFormat('[HKEY_CLASSES_ROOT\\%sfile\\DefaultIcon]\r\n', $sCurExt))
        $sIconPath = _TCHExpandEnv($aAssocList[$i][2])
        $sIconPath = StringReplace($sIconPath, "\", "\\")
        FileWriteLine($hFile, '@="' & $sIconPath & '"')
        FileClose($hFile)
    Next
Next

#11:  Author: Andrey_ALocation: Сочи PostPosted: Sat Jan 23, 2010 01:33
    —
Всё работает отлично!!! Низкий поклон !!! Ты просто... профи Loopback !!! Спасибо за понимание и терпение!!!

#12:  Author: MVVLocation: Ростов-Дон PostPosted: Thu Jan 28, 2010 10:59
    —
Работать-то оно может быть и работает, но не хотел бы я оказаться на месте того, к кому ты придешь и запустишь этот рег-файл.

Почему? Да потому, что, во-первых, этим можно напрочь испортить ассоциации, а во-вторых, что останется после извлечения флешки? Куча записей реестра с путями в никуда? Для того и сделаны внутренние ассоциации, чтобы ты мог в любом месте в своем тотале чувствовать себя как дома, при этом ничем не навредив системе. Писать скрипт - так тогда уж чтобы он смотрел, как называется ключ, соответствующий каждому расширению, прописывал в него путь к новому значку, но при этом обязательно создавал файл отката изменений, хотя все равно такие шутки с системой небезопасны, и если у тебя есть хоть капля уважения к тем людям, в чьи компы ты втыкаешь свою флешку - откажись от использования этой затеи.

На твоем месте я бы тоже не хотел оказаться в момент, когда хозяин компа узнает о твоем беспределе. Laughing Как минимум потому, что не люблю осознавать, что что-то испортил.

#13:  Author: AvadaLocation: Россия, Саратов PostPosted: Thu Jan 28, 2010 13:22
    —
MVV
Готов подписаться под каждым словом.

Всё последующее — моя реакция на эту тему (к сожалению, несколько запоздалая) как модератора.
Варианты скриптового кода оставляю в сохранности из уважения к работе, проделанной Loopback, а также потому, что это может кому-то пригодиться для решения других задач. Однако использование всех этих наработок для цели, заявленной автором темы, категорически не рекомендую.

И большая просьба к специалистам по автоматизации: насколько это возможно, оценивать потенциальную опасность запрошенных действий и при обнаружении таковой — без всяких сантиментов отказывать, даже если задача технически вполне решаема. С разъяснением пагубности возможных последствий. Давайте не будем поощрять игру с огнём.

Тему закрываю.




Total Commander -> Автоматизация Total Commander


output generated using printer-friendly topic mod. All times are GMT + 4 Hours

Page 1 of 1

Powered by phpBB © 2001, 2005 phpBB Group