Скрипт не завершает работу

Автор Massaraksh7, 25 апреля 2024, 23:22

0 Пользователи и 1 гость просматривают эту тему.

Massaraksh7

Вызываю скрипт на выполнение, код:
# coding: utf-8
from __future__ import unicode_literals
import uno
import tempfile
import os
import os.path
import time
import sys
import subprocess
import ctypes
from com.sun.star.beans import PropertyValue
from com.sun.star.awt import Rectangle
from com.sun.star.table import CellRangeAddress
from com.sun.star.drawing.LineStyle import DASH as dash
from com.sun.star.drawing.LineStyle import SOLID as solid
from com.sun.star.drawing.LineStyle import NONE as none
from com.sun.star.drawing.DashStyle import ROUND as roundpoint
from com.sun.star.table.CellHoriJustify import LEFT as hleft
from com.sun.star.table.CellHoriJustify import CENTER as hcenter
from com.sun.star.table.CellHoriJustify import RIGHT as hright
from com.sun.star.table.CellVertJustify import TOP as vtop
from com.sun.star.table.CellVertJustify import CENTER as vcenter
from com.sun.star.table.CellVertJustify import BOTTOM as vright
from com.sun.star.awt.FontWeight import BOLD as bold

def setVisible(b):
    global model
    if b:
        model.CurrentController.Frame.ContainerWindow.setVisible(True)
    else:
        model.CurrentController.Frame.ContainerWindow.setVisible(False)

def msgbox(text,cap):
    ctypes.windll.user32.MessageBoxW(0, text, cap, 1)

def attemptOffice():
    global ctx
    try:
        err = 0
        ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")   #---Подключаемся к запущенному LibreOffice
    except:
        err = 1
    return err   

def connectOffice():
    global nn
    try:
        subprocess.Popen('soffice --invisible --accept="socket,host=localhost,port=2002;urp;"',shell=True)   #---вызвать soffice в режиме прослушивания   
    except:
        msgbox("В системе не установлен LibreOffice", "Ошибка")
    err = 1
    nn = 0
    while err>0:
        err = attemptOffice()
        if err==0:
            break
        time.sleep(0.5)
        nn+=1
        if nn>20:
            msgbox("Таймаут доступа к LibreOffice", "Ошибка")
            exit()       

def attemptSaveFile(n):
    global doc
    s=tempfile.gettempdir()
    tmpfile=os.path.join(s,"temp"+str(n)+".ods")   
    tmppath = uno.systemPathToFileUrl(tmpfile)          #---Путь к временному документу
    props = []
    try:
        err=0
        doc.storeAsURL(tmppath,(tuple(props)));             #---И сохраняем его во временной директории
    except:
        err=1
    return err   
       
def saveFile():
    for i in range(10):
        err = attemptSaveFile(i)
        if err==0:
            break
           
localContext = uno.getComponentContext()   #---Получаем контекст UNO
resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext)  #---Создаем UnoUrlResolver

connectOffice()
       
smgr = ctx.ServiceManager   #---Получаем Сервис-манаджер
desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop",ctx)   #---Объект рабочего стола
path = uno.systemPathToFileUrl('c:\\laz-aep\\maket.ods')   #---Путь к нужному документу
doc = desktop.loadComponentFromURL(path, '_default', 0, ())   #---Грузим документ
saveFile()

model = desktop.getCurrentComponent()     #---Получаем доступ к документу
sheet = model.CurrentController.ActiveSheet   #---Активный лист

setVisible(False)

m=20
n=30
k=0
mss = [[0 for j in range(m)] for i in range(n)]    # массив n x m - n строк, m столбцов
for i in range(0,n):
    for j in range(0,m):
        mss[i][j]=k
        k=k+1
       
rcell = sheet.getCellRangeByName("A1:T30")
rcell.DataArray = mss       

setVisible(True)
Он нормально отрабатывает, запускает LibreOffice в режиме прослушивания, подключается к нему, создаёт ods-файл из макета, открывает, на листе пишет, что надо, и, вроде бы, всё, но окно python продолжает висеть. И, вроде бы, оно не мешает, но непонятно - почему скрипт не завершает работу.

Massaraksh7

Так, начинаю врубаться: потому, что он не отсоединился от LibreOffice. Тогда вопрос: а как это сделать?

Massaraksh7


mikekaganski

Цитата: Massaraksh7 от 25 апреля 2024, 23:22        subprocess.Popen('soffice --invisible --accept="socket,host=localhost,port=2002;urp;"',shell=True)   #---вызвать soffice в режиме прослушивания

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

Massaraksh7

Цитата: mikekaganski от 26 апреля 2024, 09:08Для чего shell=True?
Да, вы правы, с Shell=False консоль закрывается.