Форум программистов, компьютерный форум, киберфорум
Фаер
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  

Python 3. Ассоциирование расширений файлов со своей программой.

Запись от Фаер размещена 15.01.2015 в 22:31
Показов 2005 Комментарии 0

Всем здорово!
На досуге занимался редактированием реестра с помощью Python 3 и возжелал кое-какими наработками поделиться. Ну, знаете, не всеми, потому что на этом зарабатываю сессия, времени нет и прочее, в общем, получится, как с компиляцией Python-скриптов: азы дам, а дальше сами догоняйте.

Короче, к делу.

Допустим, данность такова:
Моё приложение представляет собой среду разработки Лунатик и позволяет редактировать .html файлы. Запустить программу и использовать её интерфейс, чтобы открыть один из таких файлов - это, конечно, вариант рабочий, но не самый изящный. Может, кто-то хочет зайти в каталог, дважды кликнуть по HTML-файлу и тем самым запустить среду, одновременно открыв в ней выбранный файл. Как это организовать!?

Предварительный въезд:
Наверняка, Вам известно, что такое реестр Windows. Это структурированная база данных, в которой уважающие себя приложения(и не только они) хранят свои данные, обычно, те, что нужно держать подальше от алчных или просто криворуких пользователей. Оказывается, в реестре также хранится информация о том, какие файлы какими программами нужно открывать. Эти данные можно настроить под себя, например, с помощью Редактора Реестра из Панели Управления. Однако Мы пишем приложение не для себя, а для тех, от кого само существование реестра следует держать в тайне. Следовательно, Нам нужно затолкать в свою программу несколько команд, которые будут незаметно производить необходимые изменения.

Практика:
Для того, чтобы изменить параметры реестра, Нам понадобится cmd. Обращаться к ней Мы будем с помощью функции call() модуля subprocess. Нужно учитывать, что команды, транслируемые в cmd, будут возвращать результаты выполнения в ту же cmd - а Нам необходимо иметь доступ к этим данным, поэтому Мы потанцуем с бубном и перенаправим stdout и stderr командной строки в текстовый файл. Для начала давайте попробуем получить список параметров из реестра, чтобы понять, нужно ли вообще что-либо изменять:

Python
1
2
3
4
import subprocess
 
with open('out.txt','w') as outfile:
    subprocess.call('reg query HKEY_CLASSES_ROOT',stdout=outfile,stderr=outfile,shell=False)
По порядку:
Команда reg query выдаёт список параметров, сохранённых под некоторым ключом. В Нашем случае, ключ(каталог, если так понятнее) называется HKEY_CLASSES_ROOT. Запустив команду, Мы направляем её поток вывода и поток ошибок в файл out.txt. Будем считать, что Наше приложение называется Proga. Проверим наличие такого каталога в реестре(может его и создавать не требуется) по списку, сохранённому в файле out.txt, и создадим запись, указывающую на главный исполняемый файл Нашей программы:

Python
1
2
3
4
5
6
7
regdata=open('out.txt').read()
 
if not 'HKEY_CLASSES_ROOT\Proga' in regdata:
    main=os.getcwd()+'\\Proga.exe'
    command=r'reg add HKEY_CLASSES_ROOT\Proga\shell\open\command /ve /f /d "\"'+main+'\\" \\"%1\\""'
    with open('out.txt','w') as outfile:
        subprocess.call(command,stdout=outfile,stderr=outfile,shell=False)
На этот раз команда у Нас посложнее. Начнём с того, что reg add - это функция создания записи в реестре. Далее Мы указываем, в каком каталоге хотим сделать запись(shell\open\command - это стандарт, форма, так что эту часть всегда пишите, не задумываясь). Если такого каталога не существует, он будет создан. Затем флагом /ve Мы создаём в новом каталоге безымянную переменную, которая в реестре будет записана под именем "(По умолчанию)". Далее идёт флаг /f. Дело в том, что, если переменная каким-то невозможным образом, всё-таки, существует, команда добавления такой же потребует от пользователя разрешения на перезапись. Чтобы этого избежать, Мы указываем флаг /f. Ну а после флага /d Мы пишем само значение свежеиспечённой переменной. Обратите внимание на тот факт, что в строке Мы использовали кучу экранирующих символов. Если не хотите залипнуть с ошибкой на несколько часов, делайте всё в точности так, как написано у меня.

После того, как выполните эту часть скрипта, откройте редактор реестра и найдите созданную запись. Выглядеть она должна точно так, как показано на скриншоте. Значок %1 - это адрес файла, на который пользователь кликнул дважды(или ПКМ), так что не вздумайте пропустить его!

Колдовство ещё не окончено. Дело в том, что сейчас Мы только зарегистрировали(если можно так сказать) приложение в системе, а вот сами ассоциации пока остались без изменений. Пишем следующую команду:

Python
1
2
with open('out.txt','w') as outfile:
    subprocess.call('reg add HKEY_CLASSES_ROOT\.html\OpenWithProgIDs /f /v Proga',stdout=outfile,stderr=outfile,shell=False)
Здесь Вам уже должно быть всё понятно. Параметры расширений записываются прямо вот в таких каталогах .html, .mp3 для музыкальных файлов или, .txt для текстовых, посреди HKEY_CLASSES_ROOT. По поводу каталога OpenWithProgIDs можете тоже не беспокоиться - он есть во всех каталогах расширений. Ну а с флагами /f и /v Мы уже знакомы. Кстати, да, в этом каталоге Мы создали переменную без значения. Она лишь указывает своим именем, из какого ключа брать адрес исполняемого файла Нашей программы.

Собственно, это всё. Теперь Вы можете смело нажать ПКМ на любом HTML-файле(или какой Вы там писали) и увидеть свою программу в списке "Открыть с помощью". Там же можно поставить галочку на "Использовать для всех файлов этого типа", чтобы решать всё двойным щелчком. Разумеется, есть вариант сделать это программно, но такая практика не соответствует правилами этикета, так что на этом Мы остановимся.

Если Вы что-то понимаете в программировании, то уже смекнули, что после нажатия "Открыть с помощью" будет запущена Ваша программа, вот только выбранный файл в ней не откроется. Вот здесь Нам и понадобится тот самый символ %1, который Мы прописали в реестре. Как Вы помните, он передавал в программу адрес выбранного файла. Узнать этот адрес уже внутри приложения можно с помощью системных аргументов:

Python
1
2
import sys
file=sys.argv[1]
Обратите внимание на тот факт, что в результате всех этих манипуляций каталог Вашей программы может с дуру измениться на тот, в котором находится запускаемый файл. Так что не забудьте записать где-нибудь адрес основного каталога программы, чтобы ничего не потерять(извлечь его, кстати говоря, можно и из сделанной ранее записи в реестре).

Так же должен обратить Ваше внимание на пару важных моментов:
Во-первых, записи в реестре, как и ассоциации по расширениям, появятся только после первого запуска Вашей программы. Исправить сие недоразумение крайне трудно, но возможно. Рекомендую порыться в dist-утилитах компилятора cx_Freeze.
Во-вторых, ассоциировать файловые расширения можно только с исполняемыми EXE-файлами(поправьте, если не так). Записывая в shell\open\command, например, адрес к Python-скрипту, Вы не сможете прописать ассоциации, и, даже если они появятся в списке "Открыть с помощью", при запуске Вы будете получать ошибку, вроде "Такой-то файл не является приложением Win32".

На этом, собственно, всё. Не забывайте ставить оценки за запись.
А ещё читайте и бахайте лайки моей новой книге.
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru