Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Filexists e PC lenti

77 views
Skip to first unread message

Luigis

unread,
Nov 27, 2023, 6:26:23 AM11/27/23
to
Via ShellExecAndWait presente nella libreria Jcl eseguo un file .bat che
tramite la libreria OpenSSL toglie la firma da un file della fattura
elettronica trasformandolo in un file .xml in chiaro.

Subito dopo eseguo una verifica dell'esistenza del file in chiaro:

if FileExists(fe.xml) then ...

ma su alcuni vecchi pc, lenti, la funzione restituisce false anche se il
file viene effettivamente creato solo che dal filesystem sembra essere
rilevato in ritardo.

Ho provato anche a mettere una pausa di un secondo (sleep(1000)) prima
della chiamata a FileExists ma non risolvo.

Qualche suggerimento?

Grazie.

Alessandro B.

unread,
Nov 28, 2023, 1:25:42 AM11/28/23
to
Ciao,
sembra che l'applicazione non attenda il completamento del processo batch che viene eseguito.
Potrebbe essere un problema del file batch?

Alessandro

MBulu

unread,
Nov 28, 2023, 1:43:05 AM11/28/23
to
Magari il batch lancia in "modo asincrono" il programma che toglie la
firma?

Ciao, Mario

Alberto Salvati

unread,
Nov 28, 2023, 2:21:04 AM11/28/23
to
Per prima cosa, quando dici "ma su alcuni vecchi pc, lenti", cosa intendi? Questi pc hanno dischi SSD?
Poi, succede su TUTTI questi "vecchi" pc? E sta cosa è SISTEMATICA o capita a capa di kaz?
Ancora, sarebbe utile che tu condividessi il contenuto del file batch...
Poi, hai verificato che quel particolare uso di OpenSSL non abbia un qualche parametro che indichi se l'esecuzione deve essere sincrona etc etc?
*** Nota: Magari c'è una opzione che imposta degli attributi una volta generato il file in chiaro...? ***

Su 2 piedi mi vengono in mente 3 cose:

1) invece di usare fileexists provare ad usare ShellApi.
Non sai cosa è e/o come si usa? Google rulez!

2) invece di usare fileexists usare un hook legato ad eventi del file system. Non ho approfondito ma magari c'è qualche evento che puoi usare.
https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shchangenotifyregister
https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shchangenotify
*** C'è di sicuro un evento legato alla modifica degli attributi di un file. ***

3) Mollare il batch e usare quanto descritto qua...è in c# ma, trattandosi di una chiamata al sistema operativo, la conversione in delphi è semplice:

https://www.fluxbytes.com/csharp/remove-digital-signature-from-a-file-using-c/

A.


Luigis

unread,
Nov 28, 2023, 3:24:22 AM11/28/23
to
Il 28/11/2023 07:43, MBulu ha scritto:
>
> Magari il batch lancia in "modo asincrono" il programma che toglie la
> firma?
>
Questo il codice del file .bat:

copy %1 %3
set OPENSSL_CONF=OpenSSL102q\openssl.cfg
set OPENSSL_DIR=OpenSSL102q\
Openssl102q\openssl cms -verify -in %1 -noverify -inform DER -out %2

if exist %2 goto FINE

:FILE64
copy %3 %1
del %3
Openssl102q\openssl enc -d -A -base64 -in %1 -out %3
Openssl102q\openssl smime -verify -in %3 -noverify -inform DER -out %2

:FINE
del %3

Il file .bat funziona perfettamente sia su PC prestanti che su PC lenti.

La successiva chiamata a FileExists su PC prestanti restituisce True sui
PC lenti a seconda del carico di lavoro restituisce False.

Grazie.

Luigis

unread,
Nov 28, 2023, 3:27:25 AM11/28/23
to
Questo è il codice della funzione presente nella libreria Jcl:

function ShellExecAndWait(const FileName: string; const Parameters: string;
const Verb: string; CmdShow: Integer; const Directory: string): Boolean;
var
Sei: TShellExecuteInfo;
Res: LongBool;
Msg: tagMSG;
begin
ResetMemory(Sei, SizeOf(Sei));
Sei.cbSize := SizeOf(Sei);
Sei.fMask := SEE_MASK_DOENVSUBST or SEE_MASK_FLAG_NO_UI or
SEE_MASK_NOCLOSEPROCESS or
SEE_MASK_FLAG_DDEWAIT;
Sei.lpFile := PChar(FileName);
Sei.lpParameters := PCharOrNil(Parameters);
Sei.lpVerb := PCharOrNil(Verb);
Sei.nShow := CmdShow;
Sei.lpDirectory := PCharOrNil(Directory);
{$TYPEDADDRESS ON}
Result := ShellExecuteEx(@Sei);
{$IFNDEF TYPEDADDRESS_ON}
{$TYPEDADDRESS OFF}
{$ENDIF ~TYPEDADDRESS_ON}
if Result then
begin
WaitForInputIdle(Sei.hProcess, INFINITE);
while WaitForSingleObject(Sei.hProcess, 10) = WAIT_TIMEOUT do
repeat
Msg.hwnd := 0;
Res := PeekMessage(Msg, Sei.Wnd, 0, 0, PM_REMOVE);
if Res then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
until not Res;
CloseHandle(Sei.hProcess);
end;
end;


Grazie.

Alberto Salvati

unread,
Nov 28, 2023, 3:51:34 AM11/28/23
to

> set OPENSSL_CONF=OpenSSL102q\openssl.cfg


...e il cfg...?
Hai verificato i parametri? Se si, c'è qualcosa che potrebbe avere impatti sul funzionamento sincrono/asincrono?



> Openssl102q\openssl smime -verify -in %3 -noverify -inform DER -out %2
Come sopra: Hai verificato i parametri? Se si, c'è qualcosa che potrebbe avere impatti sul funzionamento sincrono/asincrono?

> Il file .bat funziona perfettamente sia su PC prestanti che su PC lenti.

Ancora:
1) cosa vuol dire "lento"?
2) Perchè non fai un test con shellapi?

A.

Alessandro B.

unread,
Nov 28, 2023, 4:08:13 AM11/28/23
to
Io proverei a verificare se quando esci dalla procedura batch il file è disponibile.
Prova ad aggiungere una riga di log alla fine del file, qualcosa tipo

DIR >> filelog.txt

Almeno sei sicuro che all'uscita dalla procedura il file esiste o meno

Luigis

unread,
Nov 28, 2023, 5:40:19 AM11/28/23
to
Con questo suggerimento credo di aver individuato il problema:

Il file .bat viene chiamato per togliere la firma di una fattura
elettronica.

Il file della fattura elettronica viene consegnato al software facendo
il drag da Thunderbird ed il codice Delphi utilizzato è questo:

FileCount:= DragQueryFile (hDrop , $FFFFFFFF, nil, 0);

for I:= 0 to FileCount - 1 do begin
NameLen:= DragQueryFile(hDrop, I, nil, 0) + 1;
SetLength(S, NameLen);
DragQueryFile(hDrop, I, Pointer(S), NameLen);

ImportaXml(S, True);
end;

ImportaXml(S, True) è la procedura che chiama il file .bat.

Con il suggerimento di Alessandro ho scoperto che il file (S) alla
chiamata del file .bat non è presente nel filesystem.

Come posso forzare/attendere la presenza del file "draggato" nel filesystem?
Ho messo un timeout di 50 secondi sul file .bat ma non risolve.

Grazie.

Alessandro B.

unread,
Nov 28, 2023, 7:37:29 AM11/28/23
to
> Come posso forzare/attendere la presenza del file "draggato" nel filesystem?
> Ho messo un timeout di 50 secondi sul file .bat ma non risolve.

Potresti mettere un loop che attenda la presenza del file prima di procedere
Per evitare un loop infinito potresti verificare ogni N secondi se il file è presente per un massimo di M tentativi / secondi
(es. ogni 2 secondi per 100 tentativi, quindi 200 secondi massimo)
Ovviamente se il file "compare" prima esci subito dal loop

Luigis

unread,
Nov 28, 2023, 10:08:20 AM11/28/23
to
Se all'inizio del file .bat inserisco queste tre righe:
:INIZIO
if not exist %1 timeout /T 1 /nobreak
if not exist %1 GOTO INIZIO

non esce più :(

Se dall'interno del codice Delphi metto:

While Not FileExists(AFile) do
begin
sleep(1000);
end;

Esce immediatamente perché il file AFile, che è il file del DragDrop da
Thunderbird, risulta esistere (FileExists restituisce True) anche se
nella cartella Temp non c'è :(

Grazie.

Alessandro B.

unread,
Nov 28, 2023, 10:42:04 AM11/28/23
to
forse ho letto male, ma mi sembrava che il codice della chiamata
ImportaXml(S, True);
non fosse codice script/batch

Non conosco la logica del tuo programma, ma se hai questo tipo di problema devi cercare dove puoi fare i test che ti servono.
Lato batch è un po' complesso (anche se credo si possa possa fare)

Forse è più semplice spezzare in due il batch, in uno estrai il file da Thunderbird (o quello che sarà l'origine), nel secondo lanci la rimozione della firma
In mezzo, con codice Delphi, puoi inserire i controlli che ti servono

Alessandro

Luigis

unread,
Nov 28, 2023, 11:05:47 AM11/28/23
to
Il 28/11/2023 16:42, Alessandro B. ha scritto:
> forse ho letto male, ma mi sembrava che il codice della chiamata
> ImportaXml(S, True);
> non fosse codice script/batch
>
No, però se testo FileExists(S) qui Delphi mi restituisce True anche se
nel filesystem il file non c'è ed il file .bat va in errore perché il
file (S) non lo trova :(

In tutti i PC prestanti non esce alcun problema è solo su alcuni PC
lenti/carichi di lavoro che il problema si presenta.

>
> Forse è più semplice spezzare in due il batch, in uno estrai il file da Thunderbird

Il file da Thunederbird non viene estratto dal file .bat ma da Delphi
con il DragQueryFile poi il file estratto viene dato in pasto alla
procedura ImportaXml(S) che se firmato tramite il file .bat rimuove la
firma e lo elabora.

Il file .bat, infatti, si occupa solo di rimuovere la firma e di
convertire il file se codificato in base64.

Grazie.


Alessandro B.

unread,
Nov 28, 2023, 11:56:25 AM11/28/23
to
> No, però se testo FileExists(S) qui Delphi mi restituisce True anche se
> nel filesystem il file non c'è ed il file .bat va in errore perché il
> file (S) non lo trova :(
>
Questo mi pare strano...
Puoi provare con una alternativa per vedere se il file esiste, utilizzando TSearchRec

Luigis

unread,
Nov 29, 2023, 3:46:09 AM11/29/23
to
Appena provato ed è lo stesso :(

Se il PC è carico di lavoro FindFirst restituisce Zero ma il file nel
filesystem non c'è :(

Grazie.

MBulu

unread,
Nov 29, 2023, 12:32:27 PM11/29/23
to
On Wed, 29 Nov 2023 09:45:06 +0100, Luigis wrote:

>
> Se il PC è carico di lavoro FindFirst restituisce Zero ma il file nel
> filesystem non c'è :(


Invece di fare la findfirst, priva così: allì'intreno di una try ...
except, fai come se dovessi aprire quel file come un file di testo in sola
lettura, con una assign ed una reset.
Se riesce ad aprirlo, il file esiste (lo chiudi subito), se non ci riesce,
va nella "except".

Quello che ho scritto sopra, lo metti in un ciclo, da dove esce solo
quando è riuscito ad aprire e richiudere il file
Ora puoi lanciare il tuo bat

Ciao, Mario


Luigis

unread,
Nov 29, 2023, 1:40:06 PM11/29/23
to
Fatto così:
for I:= 0 to FileCount - 1 do begin
NameLen:= DragQueryFile(hDrop, I, nil, 0) + 1;
SetLength(S, NameLen);
DragQueryFile(hDrop, I, Pointer(S), NameLen);

try
InFile := Trim(s);
AssignFile(F, InFile);
Reset(F);
CloseFile(F);

ImportaXml(S, True);
except
Showmessage('Apertura Fallita: Il File Non esiste');
end;
DragFinish(hDrop);
end;

Non risolve il problema sui PC lenti, il software si comporta
esattamente come con il FileExists. :(

PC lento = PC con AMD Athlon di circa 11 anni fa che riproduce due video
da RaiPlay mentre eseguo il test.
Lo stesso PC lento se scarico di lavoro non presenta il problema.
Ho anche indagato l'eventuale "intrusione" dell'antivirus Bitdefender
disattivandolo ma non risolve il problema :(

Grazie.

Alberto Salvati

unread,
Nov 30, 2023, 1:46:36 AM11/30/23
to
Quel tuo codice è scritto piuttosto male. Parti dal presupposto che l'unico probolema possa essere che il file non esiste e nascondi i messaggi delle eccezioni.
L'informazione piu' importante di un software è l'errore. Quindi, comincia da qua:

mostri i messaggifa abbastanza


var
allow: boolean;


.................


InFile := Trim(s);
allow := true;
try
AssignFile(F, InFile);
try
Reset(F);


except
on E:Exception do begin
allow := false;
ShowMessage('ERROR ON READING FILE:' + Infile + ' ' + E.ClassName + ' ' + E.Message);
end;

finally
closefile(f);
end;

if (allow) then begin
try
ImportaXml(infile, True);

except
on E:Exception do begin
ShowMessage('ERROR IMPORTING FILE:' + Infile + ' ' + E.ClassName + ' ' + E.Message);
end;

......


A parte che per sapere cosa vuol dire "pc lento" ci sono voluti almeno 10 post.... credi che a forza di insistere con queste strategie alla fine risolverai?
Ti ho suggerito alcune alternative: le hai provate o no? Se no, PERCHE?

A.


Luigis

unread,
Nov 30, 2023, 6:51:36 AM11/30/23
to
Forse ho trovato il problema: Thunderbird.

Sembra che Thunderbird sia affetto da uno o più bug sul Drag&Drop sia in
uscita che in ingresso :( Forse risolti.

Ma a causa di problemi con la gestione delle PEC questo Thunderbird,
attualmente in versione 60.9.1 non verrà aggiornato e non potrò
verificare se effettivamente il problema scomparirà.

Grazie.

MBulu

unread,
Nov 30, 2023, 1:40:39 PM11/30/23
to
On Wed, 29 Nov 2023 19:40:02 +0100, Luigis wrote:

>
> Non risolve il problema sui PC lenti, il software si comporta
> esattamente come con il FileExists. :(
>
> PC lento = PC con AMD Athlon di circa 11 anni fa che riproduce due video
> da RaiPlay mentre eseguo il test.
> Lo stesso PC lento se scarico di lavoro non presenta il problema.
> Ho anche indagato l'eventuale "intrusione" dell'antivirus Bitdefender
> disattivandolo ma non risolve il problema :(
>

Domanda scema: i "PC veloci" e quelli "lenti" hanno lo stesso file system?
Magari il problema è lì !

Ciao, Mario

Luigis

unread,
Nov 30, 2023, 2:01:24 PM11/30/23
to
Il 30/11/2023 19:40, MBulu ha scritto:
>
> Domanda scema: i "PC veloci" e quelli "lenti" hanno lo stesso file system?
> Magari il problema è lì !

Lo avevo già testato e no, non dipende da questo :(

Normalmente hanno NTFS ma anche in presenza di FAT32 il problema si
presenta in entrambi i casi :(

Grazie.
0 new messages