2010-08-15 22 views
5

Bir dosya yürütüldüğünde veya bir uygulama tarafından çalıştırıldığında bir olayı tanımam ve tetiklemem gerekir. Windows prosedürlerini çırparak yapabildiğimi biliyorum, ancak pencerelerin hangi prosedür veya olayının gerçekleştiğini bilmiyorum. Örneğin, bir otomatik çalıştırma dosyası yürütüldüğünde, uygulamam onu ​​tanımalı, Antivirüs uygulaması gibi.Bir Uygulamanın Yürütme Amaçlı Bir Dosya Nasıl Çalışır?

Çengelin benim amacım için yararlı olduğundan emin değilim, çözüm işe yaramazsa, lütfen bana gerçek bir çözüm verin.

cevap

12

PsSetCreateProcessNotifyRoutine'u kullanmayı deneyin; bu işlev, bir sürücü oluşturulduğunda veya silindiğinde çağrılacak bir rutinler listesiyle sürücünün sağladığı bir geri çağrı rutini ekler ya da kaldırır.

bu bağlantıyı Başka bir seçenek WMI olayları kullanmaktır

, Win32_Process sınıfını kontrol C++

Detecting Windows NT/2K process execution

UPDATE yazılmış çok güzel bir örnek int, ExecNotificationQuery yöntemi bulabilirsiniz

ve SWbemEventSource.NextEvent işlevi.

kontrol Delphi 7 ve Windows 7'de test bu örnek, sen Delphi IDE dışından bu uygulamayı çalıştırmak veya EOLEException istisna (bu link kontrol edin) için istisna bildirimini devre dışı bırakmalı EOleException wich tarafından durdurulur önlemek için IDE.

program GetWMI_InstanceCreationEvent; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils 
    ,Windows 
    ,ComObj 
    ,ActiveX 
    ,Variants; 


Function KeyPressed:boolean; //detect if an key is pressed 
var 
NumEvents : DWORD; 
ir   : _INPUT_RECORD; 
bufcount : DWORD; 
StdIn  : THandle; 
begin 
Result:=false; 
StdIn := GetStdHandle(STD_INPUT_HANDLE); 
NumEvents:=0; 
GetNumberOfConsoleInputEvents(StdIn,NumEvents); 
    if NumEvents<> 0 then 
    begin 
     PeekConsoleInput(StdIn,ir,1,bufcount); 
     if bufcount <> 0 then 
     begin 
      if ir.EventType = KEY_EVENT then 
      begin 
       if ir.Event.KeyEvent.bKeyDown then 
       result:=true 
       else 
       FlushConsoleInputBuffer(StdIn); 
      end 
      else 
      FlushConsoleInputBuffer(StdIn); 
     end; 
    end; 
end; 


function VarStrNUll(VarStr:OleVariant):string;//dummy function to handle null variants 
begin 
    Result:=''; 
    if not VarIsNull(VarStr) then 
    Result:=VarToStr(VarStr); 
end; 

function GetWMIObject(const objectName: String): IDispatch; //create a wmi object instance 
var 
    chEaten: Integer; 
    BindCtx: IBindCtx; 
    Moniker: IMoniker; 
begin 
    OleCheck(CreateBindCtx(0, bindCtx)); 
    OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker)); 
    OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result)); 
end; 

Procedure GetWin32_InstanceCreationEvent; 
var 
    objWMIService    : OLEVariant; 
    colMonitoredProcesses  : OLEVariant; 
    objLatestProcess   : OLEVariant; 
begin 
    objWMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2'); 
    colMonitoredProcesses  := objWMIService.ExecNotificationQuery('Select * From __InstanceCreationEvent Within 1 Where TargetInstance ISA ''Win32_Process'''); //Get the event listener 
    while not KeyPressed do 
    begin 
    try 
    objLatestProcess := colMonitoredProcesses.NextEvent(100);//set the max time to wait (ms) 
    except 
    on E:EOleException do 
    if EOleException(E).ErrorCode=HRESULT($80043001) then //Check for the timeout error wbemErrTimedOut 0x80043001 
    objLatestProcess:=Null 
    else 
    raise; 
    end; 

    if not VarIsNull(objLatestProcess) then 
    begin 
     Writeln('Process Started '+VarStrNUll(objLatestProcess.TargetInstance.Name)); 
     Writeln('CommandLine  '+VarStrNUll(objLatestProcess.TargetInstance.CommandLine)); 
     Writeln('PID    '+VarStrNUll(objLatestProcess.TargetInstance.ProcessID)); 
    end; 
    end; 
end; 



begin 
try  
    CoInitialize(nil); 
    try 
     Writeln('Press Any key to exit'); 
     GetWin32_InstanceCreationEvent; 
    finally 
    CoUninitialize; 
    end; 

except 
    on E:Exception do 
    Begin 
     Writeln(E.Classname, ': ', E.Message); 
     Readln; 
    End; 
    end; 
end. 
+0

çok teşekkürler PRUZ çok kullanışlı, ama bir soru var! Bir autorun dosyası (Autorun.inf) bir komut çalıştırmayı veya dosyayı çalıştırmayı denediğinde, işlemin yürütüldüğü adresi alabiliriz, ancak autorun dosya adresini nasıl alabilirim? Başka bir deyişle, Süreç ve işlemi yürüten nesnenin adresini almak istiyorum ... teşekkürler çok ... –

+0

@Mahmood_N, bu bağlantıyı kontrol edin http://msdn.microsoft.com/en- us/library/aa394372% 28VS.85% 29.aspx, kullanabileceğiniz tüm özellikleri görmek için 'ParentProcessId', ana işlemin PID değerini döndürür. pid'i aldığınızda, Windows API'sini veya WMI'yı kullanarak herhangi bir bilgiyi alabilirsiniz. – RRUZ

+0

Çok teşekkürler, istediğim buydu, Saygılarımızla ... –