5


5

アプリケーションが実行する意図があることを認識する方法\ファイルを実行しますか?

ファイルがアプリケーションによって実行または実行されるときに、イベントを認識して起動する必要があります。 Windowsプロシージャをフックすることでそれができることは知っていますが、Windowsのどのプロシージャまたはイベントが起動するかはわかりません。 たとえば、自動実行ファイルが実行されると、アプリケーションはウイルス対策アプリケーションのようにそれを認識する必要があります。

フックが私の目的に役立つかどうかはわかりませんが、解決策がフックされない場合は、本当の解決策を教えてください。

1 Answer


12


http://msdn.microsoft.com/en-us/library/ff559951%28VS.85%29.aspx [PsSetCreateProcessNotifyRoutine]を使用してみてください。この関数は、ドライバーが提供するコールバックルーチンを追加または削除します。プロセスが作成または削除されるたびに呼び出されるルーチンのリスト。

このリンクはC ++で書かれた非常に素晴らしいサンプルを見つけることができます

更新

別のオプションは、WMIイベントを使用することです。http://msdn.microsoft.com/en-us/library/aa394372%28VS.85%29.aspx [Win32_Process]クラス、http://msdn.microsoft.comを確認してください。 /en-us/library/aa393864%28v=VS.85%29.aspx[ExecNotificationQuery]メソッドおよびhttp://msdn.microsoft.com/en-us/library/aa393711%28v=VS.85%29。 aspx [SWbemEventSource.NextEvent]関数。

delphi 7およびWindows 7でテストされたこのサンプルを確認してください。DelphiIDEの外部からこのアプリケーションを実行するか、EOleException例外の例外通知を無効にする必要があります(http://edn.embarcadero.com/article/32015[link]を確認してください) )、IDEによってインターセプトされる「EOleException」を回避します。

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.