Уведомления

Группа в Telegram: присоединиться | Jabber-конференция сообщества: pythonua@conference.jabber.ru

#1 Май 17, 2017 20:19:22

slice
Зарегистрирован: 2017-05-17
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Закрыт ли файл?

есть задача открыть файл (не в питоне), пусть будет txt или word или что угодно, для этого используем
import os
os.startfile('NEWS.txt')

ок, мы его открыли
как потом, после закрытия, доказать что он закрыт?

я пробовал использовать

import psutil

и смотреть за процессами, но а если будет открыт другой файл а предыдущий будет закрыт, а процесс то один. Помогите пожалуйста

Офлайн

#2 Май 17, 2017 21:39:56

slice
Зарегистрирован: 2017-05-17
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Закрыт ли файл?

[code python]import psutil, os,re

def notClose(pid):
while psutil.pid_exists(pid)!=False:
pass
else: return False
def openFile(file):
data = {
'docx':'word',
'txt':'notepad'
}
try:
processName = data[re.split('\.',file)[-1]]
except KeyError:
print('Неизвестный формат файла')

os.startfile(file)
for i in psutil.pids():

process = psutil.Process(i)
if processName in data.name() or processName.upper() in data.name():
if notClose(data.pid)==False:
print(file,'closed')


[/code]
код как бы работает, но на вордах нет. Как получить время создания процесса ?

Офлайн

#3 Май 19, 2017 00:01:46

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 5261
Репутация: +  484  -
Профиль   Отправить e-mail  

Закрыт ли файл?

python.org. os.startfile()

startfile() returns as soon as the associated application is launched. There is no option to wait for the application to close, and no way to retrieve the application’s exit status.

Попробуй subprocess.Popen() использовать вместо этого.



Офлайн

#4 Май 19, 2017 07:54:52

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 2878
Репутация: +  151  -
Профиль   Отправить e-mail  

Закрыт ли файл?

Думаю проблема ТС пошире - он не знает что запускать.
Судя по тому что он запускает ОС windows

Тогда можно командой assoc получить имя ассоциации
командой ftype по имени ассоциации получить шаблон командной строки
В него подставить имя файла.
И использовать не Popen а check_call тогда управление не вернется пока не закончится выполнение команды



Офлайн

#5 Май 19, 2017 09:06:27

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 5261
Репутация: +  484  -
Профиль   Отправить e-mail  

Закрыт ли файл?

doza_and
И использовать не Popen а check_call тогда управление не вернется пока не закончится выполнение команды
Там есть метод .wait()

Функция check_call() реализована через call(), а call() реализована через Popen().
https://github.com/python/cpython/blob/master/Lib/subprocess.py

Но фишка этих функций в том, что они не так гибки, как изначальный объект из Popen(), с которым можно сделать всё по максимуму.

doza_and
Думаю проблема ТС пошире - он не знает что запускать.
Да, но он не просто не знает, что запускать, а не знает, как это делается вообще.
Отдавать неизвестную фигню на откуп чего-то там - это явно к чему-нибудь приведёт, и совсем не к тому, что не ожидалось.
В общем, нужно конкретно выбирать: если у тебя текстовый файл, открывай его только в блокноте; если у тебя документ ворда, открывай его только в ворде; если у тебя html-страница, открывай её только в браузере. Нужно сделать функцию выбора конкретной процедуры открытия и в ней определять, как открыть файл.



Отредактировано py.user.next (Май 19, 2017 09:14:42)

Офлайн

#6 Май 19, 2017 14:21:46

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 435
Репутация: +  91  -
Профиль   Отправить e-mail  

Закрыт ли файл?

Нихрена не выйдет, разные программы по разному работают с файлами, тот же блокнот открывает файл, считывает его в память и сразу закрывает, тоесть процесс еще не завершен, файл кагбэ “открыт” а реально он закрыт. Вы можете с ним сделать все что угодно, изменить, переименовать, удалить.
С вордом ситуация обратная, он открывает файл и держит его, пока его не звкроют.. проверить достаточно просто, банальный код:

 import os
import time
myFile = 'r.doc'
os.startfile(myFile)
time.sleep(5)
try:
    inFile = open(myFile,'ab')
except IOError:
    print('файл {} еще открыт'.format(myFile))
else:
    print('файл {} закрыт'.format(myFile))
    inFile.close()
при открытии файла в ворде, получим сообщение что файл еще открыт, а в блокноте, что файл закрыт.

Отредактировано PEHDOM (Май 19, 2017 14:22:13)

Офлайн

#7 Май 19, 2017 21:10:51

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 2878
Репутация: +  151  -
Профиль   Отправить e-mail  

Закрыт ли файл?

py.user.next
если у тебя документ ворда, открывай его только в ворде
:) а у меня вордовые документы ворд частенько не может открыть или портит при открытии. Поэтому конкретно у меня ассоциирован docx на Libreoffice. Ничего не поделаешь еще один уровень редиректа.



Отредактировано doza_and (Май 19, 2017 21:13:44)

Офлайн

#8 Май 20, 2017 01:43:41

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 5261
Репутация: +  484  -
Профиль   Отправить e-mail  

Закрыт ли файл?

doza_and
Поэтому конкретно у меня ассоциирован docx на Libreoffice.
Видел, как в git'е сделано? Когда нужно сравнить два файла, используется difftool - абстрактный сравниватель.

http://schacon.github.io/git/git-difftool.html
CONFIG VARIABLES

git difftool falls back to git mergetool config variables when the difftool equivalents have not been defined.

diff.tool
The default diff tool to use.

diff.guitool
The default diff tool to use when --gui is specified.

То есть мы имеем difftool по умолчанию, но используется он через абстрактный difftool, к которому что-то прикручено. По умолчанию прикручено что-то и в настройках можно указать, которые перекроют умолчания.

Так и здесь надо сделать ему: определить абстрактный текстовый редактор, абстрактный документный редактор, абстрактный html-страничный просмотрщик. А потом сделать для них настройки, где можно записать, что запускает каждый из абстрактных редакторов или просмотрщиков.

У меня так в загрузчике файлов из Интернета сделано: качается всё через абстрактный загрузчик, а в абстрактном загрузчике записан Wget, но при этом, если я заменю его на Curl, например, вся программа этого даже не заметит, потому что все загрузки она просит выполнить абстрактный загрузчик через его методы.

И как понять тогда, закрыт у него файл или открыт? Очень просто - надо ему сделать обёртку, которая создаёт признак открытого файла и удаляет этот признак после закрытия приложения. И всё это происходит за пределами питона на уровне операционной системы. Так что из питона внутри системы ничего не надо проверять, достаточно проверить наличие признака (временного файла, например).



Отредактировано py.user.next (Май 20, 2017 10:53:29)

Офлайн

#9 Май 20, 2017 08:23:19

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 2878
Репутация: +  151  -
Профиль   Отправить e-mail  

Закрыт ли файл?

py.user.next
Так и здесь надо сделать ему: определить абстрактный текстовый редактор,
Согласен. Штатный способ сделать это в винде я описал. Там только от рождения fallback нету. Это надо самому пилить.

По поводу контроля открытия я считал что автор хочет контролировать открытие исполняемого файла т.е. подождать когда пользователь закончит манипуляции с файлом.
Если самого документа, то пусть ТС уточняет что он хочет.
Я согласен с
PEHDOM
проверить достаточно просто, банальный код:
Занятость файла проверяется элементарно. А то что приложение может считать файл и сразу закрыть, ну чтоже - значит он уже закрыт. Может пользователь его не по Save а по SaveAs сохранит. Значит это другой файл а не первый!

Кстати контроль процесса тоже может не сработать. Иногда запускаемый процесс порождает еще один процесс для редактирования, а сам закрывается.



Офлайн

#10 Май 20, 2017 08:42:50

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 435
Репутация: +  91  -
Профиль   Отправить e-mail  

Закрыт ли файл?

PS, если у человека только венда, тогда уже проще запускать файл через shellExecuteEх , венда сама найдет чем это файо открыть(при условии конечно что ассоциации выставлены в самой венде), запустит нужное приложение, откроет файл в этом приложении, и вернет хендл приложения, а уже имея хендл с помощью pywin32 или pywinauto с этим процессом можно делать все что угодно.

 import win32com.shell.shell as shell
import win32event
fileName = 'test.txt'
dict = shell.ShellExecuteEx(fMask = 64, lpFile=fileName, lpParameters='', nShow=1)
hndl = dict['hProcess']
print (hndl)
ret = win32event.WaitForSingleObject(hndl, -1)
print (ret)

Отредактировано PEHDOM (Май 20, 2017 08:43:37)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version