Domanda

Questo è lo scenario:

Abbiamo uno script Python che avvia un file batch di Windows e reindirizza il suo output su un file.Successivamente legge il file e poi tenta di eliminarlo:

os.system(C:\batch.bat >C:\temp.txt 2>&1)
os.remove(C:\temp.txt)

Nel batch.bat avviamo un programma GUI di Windows come questo:

start c:\the_programm.exe

Questo è tutto nel file batch.

Ora os.remove() fallisce con "Autorizzazione negata" perché temp.txt è ancora bloccato dal sistema.Sembra che ciò sia causato dal the_programm.exe ancora in esecuzione (il cui output sembra essere reindirizzato a temp.txt).

Qualche idea su come avviare the_programm.exe senza che temp.txt sia bloccato mentre è ancora in esecuzione?La parte Python è difficilmente modificabile poiché si tratta di uno strumento (Occupato B).

In effetti non ho bisogno dell'output di the_programm.exe, quindi l'essenza della domanda è: Come disaccoppiare the_programm.exe dal blocco di temp.txt per il suo output?O: Come posso utilizzare START o un altro comando Windows per avviare un programma senza ereditare il reindirizzamento dell'output batch?

È stato utile?

Soluzione 6

Finalmente ho potuto trovare una soluzione adeguata:

Non sto più utilizzando un file batch per avviare the_programm.exe, ma uno script Python:

from subprocess import Popen

     if __name__ == '__main__':
          Popen('C:/the_programm.exe', close_fds=True)

Il parametro close_fds disaccoppia gli handle di file dal processo .exe!Questo è tutto!

Altri suggerimenti

Questo è un po' complicato, ma potresti provarlo.Utilizza il AT comando per eseguire the_programm.exe fino a un minuto nel futuro (che calcola utilizzando il file %TIME% variabile d'ambiente e SET aritmetica).

batch.bat:

@echo off
setlocal
:: store the current time so it does not change while parsing
set t=%time%
:: parse hour, minute, second
set h=%t:~0,2%
set m=%t:~3,2%
set s=%t:~6,2%
:: reduce strings to simple integers
if "%h:~0,1%"==" " set h=%h:~1%
if "%m:~0,1%"=="0" set m=%m:~1%
if "%s:~0,1%"=="0" set s=%s:~1%
:: choose number of seconds in the future; granularity for AT is one
:: minute, plus we need a few extra seconds for this script to run
set x=70
:: calculate hour and minute to run the program
set /a x=s + x
set /a s="x %% 60"
set /a x=m + x / 60
set /a m="x %% 60"
set /a h=h + x / 60
set /a h="h %% 24"
:: schedule the program to run
at %h%:%m% c:\the_programm.exe

Puoi guardare il AT /? E SET /? per vedere cosa sta facendo ciascuno di questi.Ho lasciato fuori il /interactive parametro di AT dal momento che hai commentato che "non è consentita alcuna interazione con l'utente".

Avvertenze:

  • Sembra che %TIME% è sempre di 24 ore, indipendentemente dalle impostazioni locali nel pannello di controllo, ma non ho alcuna prova di ciò.
  • Se il tuo sistema è carico e batch.bat impiega più di 10 secondi per essere eseguito, il file AT l'esecuzione del comando verrà pianificata 1 giorno dopo.Puoi recuperarlo manualmente, utilizzando AT {job} /delete, e aumentare il x=70 a qualcosa di più accettabile.

IL START comando, purtroppo, anche quando dato /i per ignorare l'ambiente corrente, sembra trasmettere i descrittori di file aperti del genitore cmd.exe processi.Questi descrittori di file sembrano essere trasferiti ai sottoprocessi, anche se i sottoprocessi vengono reindirizzati a NUL, e vengono mantenuti aperti anche se i processi di shell intermedi terminano.Puoi vederlo in Esplora processi se hai un file batch che STARTc'è un altro file batch che STARTs un altro file batch (ecc.) che STARTÈ un'app Windows GUI.Una volta terminati i file batch intermedi, l'app GUI sarà proprietaria degli handle di file, anche se (e i file batch intermedi) sono stati tutti reindirizzati a NUL.

Non penso che Windows ti permetterà di eliminare un file aperto.Sembra che tu voglia buttare via l'output del programma;il reindirizzamento a "nul" farebbe invece ciò di cui hai bisogno?

A quanto ho capito, questo è il problema e cosa vuole fare:

  1. Fare NO modifiche al codice Python.
  2. Il codice Python viene scritto presupponendo che "temp.txt" non venga più utilizzato quando questa funzione restituisce:

    os.system(C:\batch.bat >C: emp.txt 2>&1)

  3. In realtà questo non è il caso perché "batch.bat" genera un programma GUI interattivo utilizzando il comando "start".

Che ne dici di cambiare il tuo file "batch.bat" per contenere:

start c:\the_programm.exe
pause

Ciò manterrà il file "batch.bat" in esecuzione finché non premi un tasto in quella finestra.Una volta premuto un tasto, verrà restituito il comando python "os.system", quindi python chiamerà "os.remove".

Stai chiudendo il file dopo aver finito di leggerlo?I seguenti lavori alla mia fine:

import os

os.system('runbat.bat > runbat.log 2>&1')
f = open('runbat.log')
print f.read()
f.close()
os.remove('runbat.log')

ma fallisce se rimuovo il file f.close() linea.

Perché acquisire in un file se lo elimini immediatamente?

Cosa ne pensi di questo:

os.system(C:\batch.bat >nul 2>&1)

MODIFICARE:Ops, mi ero perso il tuo commento sulla lettura del file, ho notato solo il codice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top