Newsgroup: it.comp.lang.visual-basic
Titolo: X conoscitori di API e sistema.

Ho la necessita' di fare una applicazione che, fra l'altro, deve
intercettare il caricamento di specifici programmi: es. il solitario.
In altre parole, al caricamento di una applicazione, Windows deve notificare
alla mia applicazione, il programma che sta per essere caricato, e se e' il
caso la mia applicazione deve interrompere il caricamento stesso.
Qualcuno ha qualche idea in proposito?
Come posso intercettare il caricamento di una applicazione?
Grazie
--
----------------------------------------------
Daniele Dini       MailTo:
dan...@riccione.net
  Analista/Programmatore
  Progettista Software
PIXEL Informatica
  Soluzioni Hardware & Software
Viale Castrocaro , 11
47838 Riccione (RN) ITALY
Telefono  (0039) 0541 660013
Fax  (0039) 0541 660014
Web: 
http://www.riccione.net
----------------------------------------------

Come posso intercettare il caricamento di una applicazione?
In visual basic non è possibile. Occorre utilizzare gli hook, ovvero
procedure che si inseriscono nel sistema e intercettano alcuni eventi, come
l'apertura di una finestra top-level, che corrisponde quasi sempre all'avvio
di una applicazione. Uno hook di questo genere è detto di sistema e, a causa
della separazione degli spazi di indirizzamento in Win32, non può essere
implementato in un programma eseguibile ma solo tramite una DLL (che viene
mappata nello address space dei processi che la richiamano). Dal momento che
il VB non è in grado di creare DLL (non si sta parlando delle DLL ActiveX,
ma delle DLL standard come quelle che contengono le API di Windows), in
questo linguaggio è possibile implementare solo hook limitati al processo,
non hook di sistema. Per realizzare questi ultimi è necessario creare una
DLL in C.

 DLL in C.
La "larghezza di cattura" degli eventi e lo spazio del processo non
hanno, a mio avviso,
nessuna relazione fra loro....
Ciao
Roberto

Copia-e-incolla dalla documentazione ufficiale del Windows SDK:
A hook procedure can be global, monitoring messages for all threads in the
system, or it can be thread specific, monitoring messages for only an
individual thread. A global hook procedure can be called in the context of
any application, so the procedure must be in a separate dynamic-link library
(DLL) module. A thread specific hook procedure is called only in the context
of the associated thread. If an application installs a hook procedure for
one of its own threads, the hook procedure can be in either the same module
as the rest of the application's code or in a DLL. If the application
installs a hook procedure for a thread of a different application, the
procedure must be in a DLL.


Ma che e' 'sta storia??
Se lo viene a sapere il mio programma poi finisce che non funziona
piu'... :))
Ciao
Roberto

 
Rileggendo la documentazione ho scoperto qual e' il cavillo:
Prob. VB installa la mia procedura di hook nello spazio globale, lo
stesso spazio che l'SDK identifica, a mio parere limitatamente, con "una
DLL". Non deve per forza essere una DLL, basta che sia un thread globale
e non locale all'applicazione, tutto qui. 
Comunque il programma funziona....
Ciao, Roberto

...


 
Lo trovi sul sito comune (appena lo mettera' in linea il WEBmaster).
Quella e' una versione che intercetta solo i messaggi di tastiera e
mouse,
Io ne ho anche una versione che intercetta TUTTI i tipi di messaggi, ma
rallenta dell'80% le prestazioni di sistema, trovandosi a gestire una
coda enorme di informazioni.. e quella si che andrebbe scritta in C++ o
Delphi (magari solo la callback) ma piu' che altro per motivi di
velocità!!!!
Ciao

...
Sul sito comune ho trovato il progetto sviluppato da Massimo D'Antoni ed
Ettore Maronese, tratto da uno degli esempi di MSDN, che realizza uno hook
di tastiera a livello di applicazione, ovvero utilizzando App.ThreadID come
ultimo parametro della SetWindowsHookEx. Sostituendo questo parametro con
uno 0&, tentando di ottenere uno hook globale, si ottiene solo un General
Protection Fault non appena premi un tasto quando il focus appartiene ad
un'altra applicazione. Mi spiace contraddirti, ma tutta la documentazione,
ufficiale e non, č concorde in questo, cosě come gli autori di
programmazione Windows piů autorevoli, da Charles Petzold a Jeffrey Ritcher,
fino all'italiano Dino Esposito.
Tu parli di "thread globale e non locale all'applicazione". Cosa intendi
esattamente? Un thread esiste solo ed unicamente nello address space del
processo che lo ha creato, e puň comunicare con altro solo tramite i
meccanismi previsti dal sistema (memory mapped file, handle ad oggetti di
sincronizzazione, e pochi altri).
Quando vedrň il tuo codice funzionante ci crederň (e probabilmente cambierň
mestiere!)
Ciao.

 mestiere!)
Te lo mando subito.... ma non sei obbligato a cambiare mestiere,
continua pure a servire l'umanita' come programmatore, in fondo le mie
topiche le ho prese anch'io... la documentazione l'avevo letta anch'io,
e infatti un mio progetto e' rimasto congelato per 1 anno, ma poi ho
voluto provare lo stesso a vedere se esisteva magari una "mezza" strada
per ottenere questa cosa....
Ciao

>caso la mia applicazione deve interrompere il caricamento stesso....
richiedeva uno hook di tipo WH_SHELL, che non credo funzioni allo stesso
modo di WH_JOURNAL, che in  questo caso non è utilizzabile, perchè
intercetta solo messaggi di mouse e tastiera, a meno di non tentare di
intercettare i messaggi inviati alle finestre di Explorer (inteso come la
shell di Win, non Internet explorer!). Proverò.
Ciao.

Scusa, se non ho capito male hai usato WM_JOURNAL per fare un hook di
tastiera?
Poiché si tratta di poche righe di codice, perché non le posti qui?
Grazie anticipate.
Domenico


 
Cospita, funziana, e anche bene!
A questo punto mi chiedo:
Vale la pena di tenere sul Sito Comune la richiesta di realizzazione di una DLL/OCX
che intercetta gli eventi di tipo system-global ?
Voi che dite, la lascio o la toglo?
Saluti
-- 
Hi, Ciao
Ettore                 By -MES-
http://freeweb.aspide.it/freeweb/ilmes
Il sito comune di programmatori VB
http://members.xoom.com/it_lang_vb

 
Io ho scritto anche una DLL in DELPHI per cercare di intercettare altri
eventi (non solo keystrokes o mouse) Funziona benissimo (nel senso che
non da GPF o roba del genere) ma continua ad intercettare solo gli
eventi diretti all'applicazione, con in piu' tutti i casini di
interfacciamento con VB... se qualcuno conosce, tra le diverse varianti
di SetWindowsHookEx qual e' la piu' giusta lo dica ora o mai piu'!!!!
(io ho provato   WH_CALLWNDPROC e   WH_SYSMSGFILTER )
Ciao

DLL in C.
premesso che in C si può fare tutto
mi spiace doverti dire che le versioni
4 e 5 possono fare altrettanto con
le hook di sistema: il primo con con DLL
esterne e il secondo direttamente.
Leggi sempre cosa v'è dopo !!!

 Leggi sempre cosa v'è dopo !!!
Io pero' ho scoperto che, WM_JOURNAL a parte, ogni thread si "forka"
anche le sue variabili, rendendo impossibile lo scambio di dati col
resto del programma quando la chiamata dell'hook avviene al di fuori
del thread del programma chiamante.... Il risultato e' che non si
impalla ma non funziona lo stesso.
Ho provato anche con la DLL, stesso risultato.
L'unica e' utilizzare un file su disco con nome predefinito, path
compresa.
Con la DLL funziona; adesso provo con VB
Ciao

Voi che dite, la lascio o la toglo?
Converrebbe lasciarla, però riferita alla gestione degli altri tipi di
eventi, non intercettabili dai WH_JOURNALxxx.

...

Il sistema consigliato per far comunicare processi differenti sono i file
memory mapped. Non sono difficili da creare e da usare (io l'ho fatto per la
dll scritta in PowerBasic), e non rischi di sporcare l'hard disk. Se può
essere utile posso fornire un pezzo di codice.
Ciao,
Domenico

 Se può essere utile posso fornire un pezzo di codice.
Ah, magari!!! Mandalo! :-)
Ciao
Roberto

 Con la DLL funziona; adesso provo con VB
Sai rispondermi alle seguenti domandine a riguardo dei comportamenti di una funzione di HOOK di sistema di VB5?
a) ti si impianta se accedi ad oggeti dell'applicazione ?
b) ti si impianta se accedi ad una variabile globale della applicazione (di tipo global) ?
c) ti si impianta se accedi ad una variabile globale solo del modulo (di tipo dim) ?
d) ti si impianta quando modifichi una variabile statica della funzione (di tipo static) ?
Dato che spesso alla applicazione basta sapere quali eventi globali accadono, penso che sia
sufficiente eseguire un PostMessage() ad un HWND della applicazione (un picture non visibile),
con un evento facilmente trappabile, tipo quello di KeyUp.
Oppure, se riesci a modificare variabili globali o locali del modulo, l'applicazione si puo' preoccupare di
andare a vedere periodicamente il contenuto di queste variaili.
Per ultimo, nel caso della static, si puo' richiamare la funzione di HOOK con parametri "Assurdi" per
indirla a scrivere (su ruchiesta) il contenuto della variabile static un una variabile globale.
Forse, se fai SendMessage() il SO si preoccupa di fare uno scambio di contesto tale da permetterti
di richiamare in modo sincrono una funzione del VB (es il KeyUp di prima) senza inchiorare nulla.
La soluzione del file mi sembra una "cagata" da disperati (ovviemente senza offesa)   :-))
Piuttosto preferirei il PostMessage().


 Piuttosto preferirei il PostMessage().
No, a questo punto ti dico che la soluzione e' una:  definire variabili
globali statiche all'interno della DLL (sviluppata con Delphi, per chi
legge) oppure avere un riferimento fisso (Dile, FindWindow() ... non
c'e' un sistema di memorizzare dati in memoria globale dandogli un nome
a piacere? Potrebbe chiamarsi.....
FindGlobalMemoryBlockByName("pippo_hook")!!!! 
Ciao