Newsgroup: it.comp.lang.delphi
Titolo: CGI ed esecuzione di applicazioni standard Windows.

Buongiorno a tutto il NG.
Grazie al vostro aiuto e soprattutto a Morde, ho costruito un CGI che mi 
permette di fare il login e trasferire dei files dal client al server.
Ora ho il problema che dovrei lanciare un'applicazione windows che 
dovrebbe elaborare i files caricati, salvarmi il risultato in un file di 
testo e chiudersi, ma questo non accade.
Ho provato in diversi modi con ShellExecuteEx, WaitForSingleObject e 
GetExitCodeProcess, ma non riesco ad avviare nessuna applicazione 
esterna, neanche notepad.exe.
C'ï¿œ qualcuno che ha giï¿œ avuto esperienze simili ? Potete aiutarmi ? 
Avete un'idea?
 
Grazie 1000
 
Juri
 
D2010, Win7, PHP, Linux, Win2008.

 esterna, neanche notepad.exe.
 
Che significa "non riesco"?
Posta un po di codice è spiega bene chi fa cosa o almeno chi dovrebbe fare cosa.
 
A.

 dovrebbe elaborare i files caricati
 
Dove si trova l'applicazione e dove si trova il programma che la lancia?
Se tutti e due sono sul server devi poterlo fare.
Chiarisci l'architettura: chi fa cosa, e quando.
Ciao
 
-- 
morde
Android
QT 4.7
Delphi (5,6,7.. expired)
Firebird Database
 

> Chiarisci l'architettura: chi fa cosa, e quando.
 
VIOLAZIONE DI COPIRAIT..... AHAHAHAHAHAHAHAHAHAH!
 
 
A.


 
Empatia all'opera ;)


..cmq ieri le hostess 90-60-90 non c'erano.... :-(((
 
A.

 Empatia all'opera ;)
 
Come si suol dire "I gran dementi pensano alla stessa maniera." ;)
 
ciao
Giacomo

 ..cmq ieri le hostess 90-60-90 non c'erano.... :-(((
 
Meglio! Cosi' non ti sei distratto! :)
 
Racconta un po', per noi che ieri non ce l'abbiamo fatta a partecipare...
 
ciao
Giacomo

 Meglio! Cosi' non ti sei distratto! :)
 
mavaf....! :-D  La faccio breve...
 
*** xe3 delphi
 
1) Cose nuove utili
Editor visuale per definire i livebindings che recupera i bindings creati a mano in xe2
record helper
compilazione NATIVA per macOSs e iOS. Non si passa piu' da x-code!
Gesture e taction+tactionlist su FireMonkey.
In xe2 NON C'ERANO......
Dicono che hanno migliorato performance e stabilita' di firemonkey
 
3) cosa NON C'E'
Compilatore a 64 bit per c++ builder. Uscira' tra un po.
Supporto linux 
 
4) Cose nuove la cui utilita' per me e' dubbia
Puoi creare applicazioni che hanno il lookandfeel delle app RT di windows 8.
Ma (fortunatamente) hai *solo* l'estetica: la app resta una app win32 o win64
 
**** HTML5 Builder
 
Sostituisce ed espande radPHp.
Cosi' a occhio mi e' sembrato utilizzabile anche da uno come me che non distingue una cosa scritta in javascript da una strofa oscena scritta in aramaico....
Quello che Daniele Teti ha fatto in modo visuale ha generato file SEPARATI per i vari pezzi che compongono la pagina web, cosa secondo me molto positiva.
E' importante capire che html5 builder non c'entra un cazzen con delphi.
Quindi, non hai cose tipo tdataset, i livebindings etc...
Ieri questa cosa non era molto chiara per alcuni dei presenti.
 
 
Hanno fatto vedere 2 (si, prp 2 di numero) slide di un "qualcosa" di nuovo destinato allo sviluppo mobile (ios, blackbarry, android....).
Di piu non si sa.
 
Impressioni:
 
Su html5 builder non mi sbilancio: non sono in grado
su xe3 le novita' sono un po "striminzite" rispetto a xe2 che ha introdotto parecchie news.
 
Windows 8:
Le app RT le puoi prendere solo  dallo store di zio billy.
Se apri una app rt e poi un altra, quella che non ha il "focus" si ferma.
Infine, le cosa carine:
a) le API per RT sono diverse dalle API win32 o Win64
b) Silverlight non è compatibile con RT
c) se non ho capito male, al momento non esiste NIENTE per sviluppare su Windows8 Phone o Mobile o come kaz si chiama...
d) se vuoi sviluppare su RT, sei talmente limitato che si fa prima a dire quello che PUOI fare....
 
La sensazione e' che in casa microsoft ci sia molta confusione.
 

 La sensazione e' che in casa microsoft ci sia molta confusione.
 
Confusione non credo, nel senso che la strategia è abbastanza mirata: secondo me, il problema è che - trattandosi di un momento cruciale - sono costretti a non perdere ulteriore tempo e a forzare la mano per uscire con un prodotto che, nonostante gli innumerevoli cambiamenti, recuperi mercato sia nel lato mobile e tablet, sia nel lato PC.
 
Appena Windows 8 comincerà a diffondersi un po', vedremo come sarà l'accoglimento da parte degli utenti.
 
Dal punto di vista dello sviluppo Delphi, almeno per Windows 8, direi che non abbiamo nulla di ché preoccuparti, né in termini di compatibilità (visto che tutte le applicazioni native nel desktop girano tranquillamente), né dal punto di vista della percezione (visto che si possono adottare stili appropriati al sistema, per chi lo ritiene necessario), né dal punto di vista funzionale (dato che si possono creare applicazioni standard oppure servizi come server DataSnap e affini), né dal punto di vista multimediale (visto l'ampio supporto introdotto in questo senso nella libreria FireMonkey).
 
Ciao!
 
-- 
MARCO BREVEGLIERI
#Home: 
http://www.marco.breveglieri.name
 
#Blog: 
http://www.compilaquindiva.net
 

 [...]
 
A proposito di slide, eccone altre interessanti:
http://edn.embarcadero.com/article/42544
 


Cerco di spegare meglio:
- l'applicazione ed il CGI sono installati nello stesso sistema;
- il CGI fa uso di SOAP per il login ed il trasferimento di files;
- il login ed il trasferimento funzionano
- il CGI dovrebbe eseguire l'applicazione in locale tramite la seguente 
funzione:
/// <summary>
/// Executes an external program or opens a document with its
/// standard application.</summary>
/// <param name="FileName">Full path of application or document.</param>
/// <param name="Parameters">Command line arguments.</param>
/// <param name="ExitCode">Exitcode of application (only avaiable
/// if Wait > 0).</param>
/// <param name="Wait">[milliseconds] Maximum of time to wait,
/// until application has finished. After reaching this timeout,
/// the application will be terminated and False is returned as
/// result. 0 = don't wait on application, return immediately.</param>
/// <param name="Hide">If True, application runs invisible in the
/// background.</param>
/// <returns>True if application could be started successfully, False
/// if app could not be started or timeout was reached.</returns>
function Sto_ShellExecute(const FileName, Parameters: String;
   var ExitCode: DWORD; const Wait: DWORD = 0; const Hide: boolean = False)
   : boolean;
var
   myInfo: SHELLEXECUTEINFO;
   iWaitRes: DWORD;
begin
   // prepare SHELLEXECUTEINFO structure
   ZeroMemory(@myInfo, SizeOf(SHELLEXECUTEINFO));
   myInfo.cbSize := SizeOf(SHELLEXECUTEINFO);
   myInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_NO_UI;
   myInfo.lpFile := PChar(FileName);
   myInfo.lpParameters := PChar(Parameters);
   if Hide then
     myInfo.nShow := SW_HIDE
   else
     myInfo.nShow := SW_SHOWNORMAL;
   // start file
   ExitCode := 0;
   Result := ShellExecuteEx(@myInfo);
   // if process could be started
   if Result then
   begin
     // wait on process ?
     if (Wait > 0) then
     begin
       iWaitRes := WaitForSingleObject(myInfo.hProcess, Wait);
       // timeout reached ?
       if (iWaitRes = WAIT_TIMEOUT) then
       begin
         Result := False;
         TerminateProcess(myInfo.hProcess, 0);
       end;
       // get the exitcode
       GetExitCodeProcess(myInfo.hProcess, ExitCode);
     end;
     // close handle, because SEE_MASK_NOCLOSEPROCESS was set
     CloseHandle(myInfo.hProcess);
   end;
end;
 
- l'applicazione lanciata da riga di comando funziona, elabora i files e 
si chiude;
- nel log dell'applicazione risulta che non è mai stata avviata dal CGI;
- ho eseguito un test cercando di avviare notepad.exe e ha dato esito 
negativo
 
Spero possiate aiutarmi
 
Grazie 1000
 
Juri

 
..magari l'utente sotto il quale gira la cgi (system) fa casino per chiamare shellexecute...? Se lanci TU l'applicazione usi un utente diverso?
 
A parte cio', se la cgi deve restituire al client l'exit code della app lanciata via shellexecute, ok.
Altrimenti: LC CGI (ED IL CLIENT) STANNO LI AD ASPETTARE UN QUALCOSA DI CUI NON GLIENE FREGA UN KAZZEN......
 
 
A.


Ho pensato la stessa cosa, in una macchina test ho provato a 
darepermessi di lettura, scrittura ed esecuzione a everyone, sia 
all'appplicazione che al CGI, ma nulla di fatto.
unico risultato č:
- iWaitRes = 258
- ExitCode = 259
 
ma l'applicazione non risulta essere mai avviata
 
J.

 all'appplicazione che al CGI, ma nulla di fatto.
 
Secondo me non è prp la stessa cosa.
Io proverei a usare questa:
 
CreateProcessAsUser
 
The CreateProcessAsUser function creates a new process and its primary thread. The new process then executes a specified executable file. The CreateProcessAsUser function is similar to the CreateProcess function, except that the new process runs in the security context of the user represented by the hToken parameter. By default, the new process is non-interactive, that is, it runs on a desktop that is not visible and cannot receive user input. Also, by default, the new process inherits the environment of the calling process, rather than the environment associated with the specified user.
 
 
A.

 negativo
 
Forse non si applica. Credo dipenda dalle impostazioni del tuo web
server, e dai permessi su file e directory. Se usi IIS, verifica che
il cgi possa avviare dei processi esterni. Se usi l'autenticazione
integrata Win, potrebbe essere utile attribuire permessi di lettura
sui file all'utente che esegue il processo.
(
p.es
, per eseguire script su file uploadati dagli utenti, avevo
dovuto dare il seguente permesso su cmd
CACLS %COMSPEC% /E /G "%USERDOMAIN%\Domain Users":R)
 
Saluti
Paolo Arosio

Ti 6 perso le hostess 90-60-90....... :-D
 
A.

 Ti 6 perso le hostess 90-60-90....... :-D
 
Salvati, non ci freghi: c'erano piů maschi lě che in un monastero
benedettino
 
http://blog.marcocantu.com/blog/rad_studio_xe3_tour_milan_rome.html
 
 
Ciao
 
-- 
 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it
 
 
 

 
http://blog.marcocantu.com/blog/rad_studio_xe3_tour_milan_rome.html
 
 
 
..ma tu nu poco poco i kaz tuoi no, eh??? :-D
 
A.

Ho provato ad usare CreateProcessAs User, ed ora ottengo il messaggio di 
sistema: client non dispone dell'autorizzazione necessaria.
Il problema penso sia in IIS, in quanto il UserLogon funziona 
perfettamente e utilizzo credenziali di amministratore, le stesse che mi 
permettono di lanciare l'applicazione da riga di comando.
Dove devo verificare in IIS che il mio CGI abbia l'autorizzazione ad 
eseguire un applicazione esterna (sempre nello stesso computer)?
 
Grazie a tutti
 
Juri

Grazie Paolo,
penso la tua spiegazione sia la più consona, soprattutto dopo che ho 
fatto qualche esperimento:
- inizialmente ho tentato di eseguire l'applicazione attraverso 
ShellExecuteEx, ma non ho avuto successo.
- in questi giorni ho provato anche con CreateProcessAsUser e l'unico 
messaggio che ottengo è quello che mi informa sul fatto che l'utente non 
ha i permessi di esecuzione.
- ho provato a dare permessi di esecuzione sul file e di accesso alle 
cartelle dell'appplicazione all'utente Everyone, ma nessun risultato.
 
Pensi ci sia qualche configurazione che ho dimenticato su IIS7 che 
autorizzi il mio CGI ad eseguire applicazioni esterne ? Mi sai dare 
qualche indicazione (non ho molta esperienza con IIS)
 
Grazie
 
 
Ciao
 
Juri


Non sono un esperto di IIS, quindi non saprei puntare il dito su una
cosa e dire è lì.
Se la tua applicazione web riesce a salvare i file in una directory
specifica, potresti aggirare il problema creando un servizio che stia
in ascolto di variazioni nella directory (Find*ChangeNotification?) e
in caso di presenza dei file li elabori e li rimuova.
 
Riguardo ai permessi, IUSR è un po' particolare, credo. Prova a
assegnare i permessi solo a quell'utente, se l'applicazione consente
l'accesso anonimo.
Purtroppo non riesco a ritrovare il riferimento alla pagina che mi
risolse il problema (che era di eseguire uno script tcl a seguito
dell'upload di file in una certa directory), probabilmente qualche
blog o wiki page sul php.
 
Saluti
Paolo Arosio

Ho provato a dare i permessi sia a IUSR che a Everyone, sia alla 
cartella del CGI che alla cartella dell'applicazione, ma nessun risultato.
A questo punto sono a chiedere se q. che ha pi� esperienza e magari � 
dalle parti di Venezia pu� occuparsi di risolvermi il problema, 
ovviamente dietro congruo compenso, ho esaurito il tempo a mia 
disposizione e non riesco a continuare questo progetto.
 
Grazie
 
Juri

 Ho provato a dare i permessi sia a IUSR che a Everyone
 
IIS segue un set di restrizioni aggiuntive che non sono direttamente 
correlate agli utenti o proprietari del processo.
Hai provato a leggere quanto indicato qui sotto?
- 
http://technet.microsoft.com/en-us/library/cc730912%28v=ws.10%29.aspx
 
 
 
-- 
TeeBX VoIP communication platform (coming soon)
http://code.google.com/p/teebx/
 
-----------------------------------------------
Lightweight++ Business Friendly++ Open++

Gi� letto, ma non ho risolto nulla che io sia in grado di capire ... poi 
non comprendo a che livello venga eseguito il blocco dell'applicazione: 
infatti posso eseguire il CGI e lui legge e scrive in una cartella in 
cui vanno salvati dei files, ma non posso fargli eseguire 
un'applicazione esterna ...
Di seguito le funzioni che ho provato ad utilizzare per lanciare 
l'applicazione esterna da CGI:
 
function Sto_ShellExecute(const FileName, Parameters: String;
   var ExitCode: DWORD; const Wait: DWORD = 0; const Hide: boolean = False)
   : boolean;
var
   myInfo: SHELLEXECUTEINFO;
   iWaitRes: DWORD;
begin
   // prepare SHELLEXECUTEINFO structure
   ZeroMemory(@myInfo, SizeOf(SHELLEXECUTEINFO));
   myInfo.cbSize := SizeOf(SHELLEXECUTEINFO);
   myInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_NO_UI;
   myInfo.lpFile := PChar(FileName);
   {********** DEBUG **********}
   DebugWrite('myInfo.lpFile : ' + FileName);
   {********** DEBUG **********}
   //myInfo.lpParameters := PChar(Parameters);
   myInfo.lpParameters := nil;
   {********** DEBUG **********}
   DebugWrite('myInfo.lpParameters : ' + Parameters);
   {********** DEBUG **********}
   //myInfo.lpVerb := 'RunAs';
   {********** DEBUG **********}
   DebugWrite('myInfo.lpVerb : ' + myInfo.lpVerb);
   {********** DEBUG **********}
   if Hide then
     myInfo.nShow := SW_HIDE
   else
     myInfo.nShow := SW_SHOWNORMAL;
   // start file
   ExitCode := 0;
   Result := ShellExecuteEx(@myInfo);
   {********** DEBUG **********}
   DebugWrite('ShellExecuteEx result: ' + BoolToStr(Result));
   {********** DEBUG **********}
   DebugWrite('myInfo.hInstApp : ' + IntToStr(myInfo.hInstApp));
   {********** DEBUG **********}
   case myInfo.hInstApp of
     ERROR_FILE_NOT_FOUND: DebugWrite('Error: File not found');
     ERROR_PATH_NOT_FOUND: DebugWrite('Error: Path Not Found');
     ERROR_DDE_FAIL: DebugWrite('Error: DDE transaction failed');
     ERROR_NO_ASSOCIATION: DebugWrite('Error: There is no application 
associated with the given filename extension');
     ERROR_ACCESS_DENIED: DebugWrite('Error: Access Denied');
     ERROR_DLL_NOT_FOUND: DebugWrite('Error: DLL Not Found');
     ERROR_CANCELLED: DebugWrite('Error: The function prompted the user 
for the location of the application, but the user cancelled the request.');
     ERROR_NOT_ENOUGH_MEMORY: DebugWrite('Error: Out Of Memory');
     ERROR_SHARING_VIOLATION: DebugWrite('Error: Sharing Violation');
   end;
   // if process could be started
   if Result then
   begin
     // wait on process ?
     if (Wait > 0) then
     begin
       iWaitRes := WaitForSingleObject(myInfo.hProcess, Wait);
       {********** DEBUG **********}
       DebugWrite('WaitRes: ' + IntToStr(iWaitRes));
       {********** DEBUG **********}
       // timeout reached ?
       if (iWaitRes = WAIT_TIMEOUT) then
       begin
         {********** DEBUG **********}
         DebugWrite('WaitRes: TimeOut');
         {********** DEBUG **********}
         Result := False;
         TerminateProcess(myInfo.hProcess, 0);
       end;
       // get the exitcode
       GetExitCodeProcess(myInfo.hProcess, ExitCode);
       {********** DEBUG **********}
       DebugWrite('ExitCode: ' + IntToStr(ExitCode));
       {********** DEBUG **********}
     end;
     // close handle, because SEE_MASK_NOCLOSEPROCESS was set
     CloseHandle(myInfo.hProcess);
   end
   else
     ExitCode := 1;
end;
 
ed inoltre
 
 
function WinExecAsUser(FileName: string; username: string; password:
string; Visibility: integer): Boolean;
var { V1 by Pat Ritchey, V2 by P.Below }
   zAppName          : array[0..512] of char;
   StartupInfo       : TStartupInfo;
   ProcessInfo       : TProcessInformation;
   h                 : thandle;
begin { WinExecAndWait32V2 }
   Result := True;
   StrPCopy(zAppName, FileName);
   FillChar(StartupInfo, Sizeof(StartupInfo), #0);
   StartupInfo.cb := Sizeof(StartupInfo);
   //StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
   //StartupInfo.wShowWindow := Visibility;
   if not LogonUser(pchar(username), '.', pchar(Password),
     LOGON32_LOGON_INTERACTIVE,
     LOGON32_PROVIDER_DEFAULT, h) then
     begin
       {********** DEBUG **********}
       DebugWrite('"a": ' + SysErrorMessage(GetLastError));
       {********** DEBUG **********}
       Result := false;
       Exit;
     end;
   CreateProcessAsUser(h, nil,
     zAppName, { pointer to command line string }
     nil, { pointer to process security attributes }
     nil, { pointer to thread security attributes }
     false, { handle inheritance flag }
     CREATE_NEW_CONSOLE or { creation flags }
     CREATE_NEW_PROCESS_GROUP,
     //NORMAL_PRIORITY_CLASS,
     nil, { pointer to new environment block }
     nil, { pointer to current directory name }
     StartupInfo, { pointer to STARTUPINFO }
     ProcessInfo); { pointer to PROCESS_INF }
   if GetLastError <> 0 then
   begin
     {********** DEBUG **********}
     DebugWrite('"b": ' + SysErrorMessage(GetLastError));
     {********** DEBUG **********}
     Result := false;
   end;
end;
 
Idee ?