如何验证进程名称(部分名称,例如:notep* for notepad.exe)是否存在并创建一个循环以在运行时终止该进程?批处理很简单:
:a
taskkill -f -im notep*
goto a
有什么帮助吗?
如何验证进程名称(部分名称,例如:notep* for notepad.exe)是否存在并创建一个循环以在运行时终止该进程?批处理很简单:
:a
taskkill -f -im notep*
goto a
有什么帮助吗?
您可以使用异步 WMI 事件(如__InstanceCreationEvent)来检测进程何时启动以及使用Win32_Process
WMI 类和Terminate
终止进程的方法。
您可以编写这样的 WQL 语句来检测任何带有“notep”字符串的进程的启动。
Select * From __InstanceCreationEvent Within 1 Where TargetInstance ISA "Win32_Process" And TargetInstance.Name like "notep%"
试试这个样本
{$APPTYPE CONSOLE}
uses
Windows,
{$IF CompilerVersion > 18.5}
Forms,
{$IFEND}
OleServer,
SysUtils,
ActiveX,
ComObj,
Variants;
type
TSWbemSinkOnObjectReady = procedure(ASender: TObject; const objWbemObject: OleVariant;
const objWbemAsyncContext: OleVariant) of object;
TSWbemSinkOnCompleted = procedure(ASender: TObject; iHResult: TOleEnum;
const objWbemErrorObject: OleVariant;
const objWbemAsyncContext: OleVariant) of object;
TSWbemSinkOnProgress = procedure(ASender: TObject; iUpperBound: Integer; iCurrent: Integer;
const strMessage: WideString;
const objWbemAsyncContext: OleVariant) of object;
TSWbemSinkOnObjectPut = procedure(ASender: TObject; const objWbemObjectPath: OleVariant;
const objWbemAsyncContext: OleVariant) of object;
ISWbemSink = interface(IDispatch)
['{75718C9F-F029-11D1-A1AC-00C04FB6C223}']
procedure Cancel; safecall;
end;
TSWbemSink = class(TOleServer)
private
FOnObjectReady: TSWbemSinkOnObjectReady;
FOnCompleted: TSWbemSinkOnCompleted;
FOnProgress: TSWbemSinkOnProgress;
FOnObjectPut: TSWbemSinkOnObjectPut;
FIntf: ISWbemSink;
function GetDefaultInterface: ISWbemSink;
protected
procedure InitServerData; override;
procedure InvokeEvent(DispID: TDispID; var Params: TVariantArray); override;
public
procedure Connect; override;
procedure ConnectTo(svrIntf: ISWbemSink);
procedure Disconnect; override;
procedure Cancel;
property DefaultInterface: ISWbemSink read GetDefaultInterface;
published
property OnObjectReady: TSWbemSinkOnObjectReady read FOnObjectReady write FOnObjectReady;
property OnCompleted: TSWbemSinkOnCompleted read FOnCompleted write FOnCompleted;
property OnProgress: TSWbemSinkOnProgress read FOnProgress write FOnProgress;
property OnObjectPut: TSWbemSinkOnObjectPut read FOnObjectPut write FOnObjectPut;
end;
TWmiAsyncEvent = class
private
FWQL : string;
FSink : TSWbemSink;
FLocator : OleVariant;
FServices : OleVariant;
procedure EventReceived(ASender: TObject; const objWbemObject: OleVariant; const objWbemAsyncContext: OleVariant);
public
procedure Start;
constructor Create;
Destructor Destroy;override;
end;
{ TSWbemSink }
procedure TSWbemSink.Cancel;
begin
DefaultInterface.Cancel;
end;
procedure TSWbemSink.Connect;
var
punk: IUnknown;
begin
if FIntf = nil then
begin
punk := GetServer;
ConnectEvents(punk);
Fintf:= punk as ISWbemSink;
end;
end;
procedure TSWbemSink.ConnectTo(svrIntf: ISWbemSink);
begin
Disconnect;
FIntf := svrIntf;
ConnectEvents(FIntf);
end;
procedure TSWbemSink.Disconnect;
begin
if Fintf <> nil then
begin
DisconnectEvents(FIntf);
FIntf := nil;
end;
end;
function TSWbemSink.GetDefaultInterface: ISWbemSink;
begin
if FIntf = nil then
Connect;
Assert(FIntf <> nil, 'DefaultInterface is NULL. Component is not connected to Server. You must call "Connect" or "ConnectTo" before this operation');
Result := FIntf;
end;
procedure TSWbemSink.InitServerData;
const
CServerData: TServerData = (
ClassID: '{75718C9A-F029-11D1-A1AC-00C04FB6C223}';
IntfIID: '{75718C9F-F029-11D1-A1AC-00C04FB6C223}';
EventIID: '{75718CA0-F029-11D1-A1AC-00C04FB6C223}';
LicenseKey: nil;
Version: 500);
begin
ServerData := @CServerData;
end;
procedure TSWbemSink.InvokeEvent(DispID: TDispID; var Params: TVariantArray);
begin
case DispID of
-1: Exit; // DISPID_UNKNOWN
1: if Assigned(FOnObjectReady) then
FOnObjectReady(Self,
Params[0] {const ISWbemObject},
Params[1] {const ISWbemNamedValueSet});
2: if Assigned(FOnCompleted) then
FOnCompleted(Self,
Params[0] {WbemErrorEnum},
Params[1] {const ISWbemObject},
Params[2] {const ISWbemNamedValueSet});
3: if Assigned(FOnProgress) then
FOnProgress(Self,
Params[0] {Integer},
Params[1] {Integer},
Params[2] {const WideString},
Params[3] {const ISWbemNamedValueSet});
4: if Assigned(FOnObjectPut) then
FOnObjectPut(Self,
Params[0] {const ISWbemObjectPath},
Params[1] {const ISWbemNamedValueSet});
end; {case DispID}
end;
//Detect when a key was pressed in the console window
function KeyPressed:Boolean;
var
lpNumberOfEvents : DWORD;
lpBuffer : TInputRecord;
lpNumberOfEventsRead : DWORD;
nStdHandle : THandle;
begin
Result:=false;
nStdHandle := GetStdHandle(STD_INPUT_HANDLE);
lpNumberOfEvents:=0;
GetNumberOfConsoleInputEvents(nStdHandle,lpNumberOfEvents);
if lpNumberOfEvents<> 0 then
begin
PeekConsoleInput(nStdHandle,lpBuffer,1,lpNumberOfEventsRead);
if lpNumberOfEventsRead <> 0 then
begin
if lpBuffer.EventType = KEY_EVENT then
begin
if lpBuffer.Event.KeyEvent.bKeyDown then
Result:=true
else
FlushConsoleInputBuffer(nStdHandle);
end
else
FlushConsoleInputBuffer(nStdHandle);
end;
end;
end;
{ TWmiAsyncEvent }
constructor TWmiAsyncEvent.Create;
const
strServer ='localhost';
strNamespace ='root\CIMV2';
strUser ='';
strPassword ='';
begin
inherited Create;
CoInitializeEx(nil, COINIT_MULTITHREADED);
FLocator := CreateOleObject('WbemScripting.SWbemLocator');
FServices := FLocator.ConnectServer(strServer, strNamespace, strUser, strPassword);
FSink := TSWbemSink.Create(nil);
FSink.OnObjectReady := EventReceived;
FWQL:='Select * From __InstanceCreationEvent Within 1 '+
'Where TargetInstance ISA "Win32_Process" And TargetInstance.Name like "notep%"';
end;
destructor TWmiAsyncEvent.Destroy;
begin
if FSink<>nil then
FSink.Cancel;
FLocator :=Unassigned;
FServices :=Unassigned;
FSink.Free;
CoUninitialize;
inherited;
end;
procedure TWmiAsyncEvent.EventReceived(ASender: TObject;
const objWbemObject: OleVariant;
const objWbemAsyncContext: OleVariant);
var
PropVal: OLEVariant;
FOutParams : OLEVariant;
begin
PropVal := objWbemObject;
Writeln(Format('Detected Process %s Pid %d',[String(PropVal.TargetInstance.Name), Integer(PropVal.TargetInstance.ProcessId)]));
Writeln('Killing');
FOutParams:=PropVal.TargetInstance.Terminate(VarEmpty);
Writeln(Format('ReturnValue %s',[FOutParams]));
end;
procedure TWmiAsyncEvent.Start;
begin
Writeln('Listening events...Press Any key to exit');
FServices.ExecNotificationQueryAsync(FSink.DefaultInterface,FWQL,'WQL', 0);
end;
var
AsyncEvent : TWmiAsyncEvent;
begin
try
AsyncEvent:=TWmiAsyncEvent.Create;
try
AsyncEvent.Start;
//The next loop is only necessary in this sample console sample app
//In VCL forms Apps you don't need use a loop
while not KeyPressed do
begin
{$IF CompilerVersion > 18.5}
Sleep(100);
Application.ProcessMessages;
{$IFEND}
end;
finally
AsyncEvent.Free;
end;
except
on E:EOleException do
Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
end.
在 Delphi 中枚举正在运行的进程将有助于枚举进程。
当你找到你要找的那个时,发布一条WM_QUIT
消息SendMessageTimeout
,让它有机会很好地关闭,如果它不使用TerminateProcess
,则强制关闭它。
如果我要做这样的事情,我会把整个事情放在一个TThread
,这样它就可以在后台扫描进程而不会干扰我的应用程序的用户界面。
这不是您狭隘问题的确切答案。如果是windows平台,为什么需要做这样的一周检查。使用组策略并在 Windows Settings\Security Settings\Software Restriction Policies\Additional Rules 下创建文件或路径规则以阻止要执行的程序
欢呼范
这段代码正是你所要求的。把它放在一个计时器里。
function GetText(Wnd: HWND): string;
var
textlength: Integer;
Text: PChar;
begin
textlength := SendMessage(Wnd, WM_GETTEXTLENGTH, 0, 0);
if textlength = 0 then
Result := ''
else
begin
GetMem(Text, textlength + 1);
SendMessage(Wnd, WM_GETTEXT, textlength + 1, Integer(Text));
Result := Text;
FreeMem(Text);
end;
end;
function EnumWindowsProc(Wnd: HWND; lParam: lParam): BOOL; stdcall;
begin
Result := True;
if (IsWindowVisible(Wnd) or IsIconic(Wnd)) and
((GetWindowLong(Wnd, GWL_HWNDPARENT) = 0) or (GetWindowLong(Wnd, GWL_HWNDPARENT)
= GetDesktopWindow)) and (GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = 0)
then
Form1.ListBox1.Items.Add('Handle: ' + IntToStr(Wnd) + ',Text: ' + GetText(Wnd));
if (GetText(Wnd) = 'Untitled - Notepad') then
begin
SendMessage(Wnd, WM_SYSCOMMAND, SC_CLOSE, 0);
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
Param: Longint;
begin
EnumWindows(@EnumWindowsProc, Param);
end;