fips81
Goto Top

Mit C prüfen ob eine Datei von einem anderen Programm geöffnet ist...

Einen schönen guten Morgen!

Ich muss über VPN drucken. Da der Druckjob bei Bildern und Texten mit Mustern im spooler so endlos groß wird, und ThinPrint meinem Kunden zu teuer ist, versuche ich das mittels PDF umzusetzen. Auf dem Server wandelt FreePDF die Druckausgabe in ein PDF-File um und legt sie auf einer Freigabe auf dem Heimcomputer ab. Dort überwacht DirMonitor dieses Verzeichnis. Wenn eine PDF-Datei eingeht, leitet DirMonitor diese an (dazwischen eine Batch) PDFP.exe weiter. PDFP druckt diese mittels AcrobatReader v8.0 und schließt den Reader nach erfolgreichem Spoolvorgang.
Soweit funktioniert das auch prima, nur wenn die PDF-Datei "größer" ist, d.h. über 100 kb, dann erkennt DirMonitor die PDF (die aber noch leer ist und durch den langsamen DSL-Upload erst noch gefüllt wird) und leitet die leere Datei an PDFP weiter. Mit dem Ergebnis, das eine Instanz vom Acrobat Reader geöffnet ist und sich nicht mehr schließt, und auch der Druck nicht funktioniert.
Hoffentlich habe ich das verständlich rüber gebracht.

Ich brauche quasi ein Programm, das überprüft, ob die PDF-Datei noch geöffnet ist. Z.B. mittels einem Schreibversuch. Mein erster Fehlversuch war eine Batch:

@echo off
c:/
cd pdfprint/pdfspooler
for /F "tokens=1,2,3,4 delims=" %%i in (%1) do @set pdffilename="%%l"  
c:/pdfprint/wait.exe 1
:loop
ren %pdffilename% %pdffilename%
if errorlevel 0 goto print
c:/pdfprint/wait.exe 3
if errorlevel 1 goto loop
:print
c:/pdfprint/pdfp.exe %1
del %1 /f /s /q

DirMonitor startet die Batch so:
"C:/PDFPrint/PDFP.exe" "C:/PDFPrint/PDFSPOOLER/test.pdf"

Die For-Schleife holt aus "C:/PDFPrint/PDFSPOOLER/test.pdf" den Dateinamen "test.pdf" mit Anführungszeichen.

Mein Gedanke war, andauernd zu versuchen die Datei umzubenennen (in den selben Namen) und mit errorlevel zu arbeiten. So lange die Datei "befüllt" wird, soll errorlevel 1 kommen. Mit rename funktioniert das auch, wenn ich die Schritte einzeln in der Kommandozeile durchgehe, aber in der Batch nicht mehr.

Jetzt brauche ich eine Lösung mittels eines Kommandozeilen-Befehls um den errorlevel zu erzeugen, oder lieber wäre es mir mittels eines C-Programms (deswegen habe ich es in der Rubrik C/C++ gepostet).
Ich bin gerade dabei C zu lernen und kenne nur die Grundlagen. Habe mir bereits folgendes Progrämmchen gebastelt:

#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv) 
{
      FILE *datei;
      datei = fopen ( argv[1] , "w+" );  
      if (datei == NULL ) {
                          return EXIT_FAILURE;
                          }
      else {
           return EXIT_SUCCESS;
           }
}

Das Programm erzeugt den errorlevel 1 aber nur wenn es die Datei nicht erstellen kann. Da sie aber schon existiert muss das Programm irgendwie erkennen, ob die Datei vollständig ist, bzw. nicht mehr durch Windows geöffnet ist.

Genau... Windows... eben hab' ich es erwähnt. Betriebssystem ist Windows XP. ;)

Für eine Lösung bin ich riesig dankbar!

Mfg, Michael

PS: Entschuldigung für den langen Text!


edit: WO SIND DIE BACKSLASHE? face-sad Ich musste sie durch slashs ersetzen, ich kriegs nicht hin. face-sad

Content-Key: 58196

Url: https://administrator.de/contentid/58196

Printed on: April 25, 2024 at 23:04 o'clock

Member: Guenni
Guenni May 04, 2007 at 17:01:26 (UTC)
Goto Top
@Fips81

Hi,

der Datentyp FILE ist ja eine Struktur. Unter anderem enthält
diese Struktur ein Dateiende- und ein Fehler-Flag:

typedef struct{

...

unsigned int flags; /* Dateiende- und Fehlerflag */

...

}FILE;

Fehler können mit der Funktion int ferror(FILE* f) abgefragt werden. Die Funktion
liefert einen Wert ungleich Null, wenn in(mit) f ein Fehler aufgetreten ist.

Habe ich gerade mal nachgeschlagen, aber WELCHE Fehler das sein könnten,
steht leider nicht in dem Buch.

Ich würde mir 2 Programme schreiben:

Eins, das eine Datei öffnet, und in einer Schleife die Datei mit Werten füllt.

Ein anderes, das die Datei ebenfalls öffnet(öffnen will), während das erste
Programm noch läuft, und dann mal gucken, was passiert.

Ist ein bißchen TRYandERROR, aber manchmal muß man halt ein
wenig experimentieren.

Grüße
Günni
Member: Fips81
Fips81 May 04, 2007 at 23:08:01 (UTC)
Goto Top
Hi Günni, riesen Dank für Deine Mühen!

Ich denke, damit kann ich mir weiteres Wissen zu ferror ergoogeln. face-smile

Heute Abend habe ich es soweit zum laufen gebracht. Halt mit Batch, aber es erfüllt seinen Zweck.
Schaun mer mal, vielleicht kann ich's nächste Woche noch ein wenig mit C optimieren...

Falls die Lösung jemand interessiert, kann ich sie gerne komplett posten! ...Einstellungen von FreePDF, DirMonitor und die Batches.

Ich hab's auch schon auf Stress getestet, d.h. durcheinander gedruckt, mehrere Sachen in rauhen Mengen gleichzeitig gedruckt. Soweit alles fehlerfrei und ohne Absturz. Und vor allem: 100 mal schneller!

Hier vorweg mal die Batch vom Server und die "Haupt-Batch" vom Client (backslashs ersetzt durch slashs):

Server:
@echo off
for /F "tokens=1,2,3,4 delims=/" %%i in (%1) do @set pdffilename=%%l  
if errorlevel 1 @for /F "tokens=1,2,3,4 delims=\" %%i in ("%1") do @set pdffilename=%%l  
e:
cd /spooler/temp
copy "%pdffilename%" "//%2/%3/%random%%random% %pdffilename%"  
del %1 /f /s /q

Client:
@echo off
for /F "tokens=1,2,3,4 delims=/" %%i in (%1) do @set pdffilename="%%l"  
c:
cd "/pdfprint/pdfspooler"  

:check
ping 127.0.0.1 -n 5
ren %pdffilename% %pdffilename%
if not exist %1 goto:eof
if %errorlevel% equ 0 (goto print) else (goto check)

:print
c:/pdfprint/pdfp.exe %1
del %1 /f /s /q

Wie gesagt, bei Interesse poste ich's komplett.
Mfg, Michael