PDA

View Full Version : سوال: بستن پروسه با تابع TerminateProcess



Mask
چهارشنبه 23 آذر 1390, 20:37 عصر
با سلام.
چطوری میتونم با استفاده از تابع TerminateProcess در یونیت windows یه پروسه رو ببندم.
نمیدونم چرا کد زیر کار نمیده.


Function NTSetPrivilege(Const sPrivilege: string; Const bEnabled: Boolean): Boolean;
var
hToken: THandle;
TokenPriv: TOKEN_PRIVILEGES;
PrevTokenPriv: TOKEN_PRIVILEGES;
ReturnLength: Cardinal;
begin
Result := True;
// Only for Windows NT/2000/XP and later.
if not (Win32Platform = VER_PLATFORM_WIN32_NT) then Exit;
Result := False;

// obtain the processes token
if OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
begin
try
// Get the locally unique identifier (LUID) .
if LookupPrivilegeValue(nil, PChar(sPrivilege),
TokenPriv.Privileges[0].Luid) then
begin
TokenPriv.PrivilegeCount := 1; // one privilege to set

case bEnabled of
True: TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
False: TokenPriv.Privileges[0].Attributes := 0;
end;

ReturnLength := 0; // replaces a var parameter
PrevTokenPriv := TokenPriv;

// enable or disable the privilege

AdjustTokenPrivileges(hToken, False, TokenPriv, SizeOf(PrevTokenPriv),
PrevTokenPriv, ReturnLength);
end;
finally
CloseHandle(hToken);
end;
end;
// test the return value of AdjustTokenPrivileges.
Result := GetLastError = ERROR_SUCCESS;
if not Result then
raise Exception.Create(SysErrorMessage(GetLastError));
end;


function NameToPid(ExeNames: PChar): DWord;
function DeleteExe(sProcessNames: string): string;
var i: DWord;
j: DWord;
begin
SetLength(Result,Length(sProcessNames));
result := '';
j := 0;
for i := 1 to length(sProcessNames) do
begin
if (Copy(sProcessNames,i,6) = ('.EXE'#13#10)) then
j := 4;
if (j > 0) then
Dec(j) else
Result := Result+sProcessNames[i];
end;
end;
var
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
ContinueLoop : Boolean;
sExeSearch : String;
sExeProcess : String;
i : integer;
begin
Result := 0;
sExeSearch := DeleteExe(uppercase(#13#10+exenames+#13#10));
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle,FProcessEntry32);
while ContinueLoop do
begin
sExeProcess := uppercase(extractfilename(FProcessEntry32.szExeFil e));
i := pos(sExeProcess,sExeSearch);
if (i > 0) and
(sExeSearch[i-1] = #10) and
(sExeSearch[i+length(sExeProcess)] = #13) then
result := FProcessEntry32.th32ProcessID;
ContinueLoop := Process32Next(FSnapshotHandle,FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
NTSetPrivilege('SeDebugPrivilege',true);
TerminateProcess(OpenProcess(PROCESS_QUERY_INFORMA TION or PROCESS_VM_READ,False,NameToPid('notepad.exe')),0) ;
end;

BORHAN TEC
جمعه 25 آذر 1390, 15:22 عصر
من قدیما از کد زیر استفاده کرده بودم و جواب میده :
procedure TfrmMain.BlockProc(ProcID: Cardinal);
const
TERMINATE_PROCESS = $0001;
begin
TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0), ProcID), 0);
Sleep(60);
cboUsbDrivesChange(nil);
end;
متاسفانه الان وقت کافی برای دیباگ کردن برنامه شما را ندارم ولی 100% مشکل برنامه شما مربوط به تابع NameToPid است که ID پروسه مربوطه را نمی تواند تشخیص دهد.

vcldeveloper
جمعه 25 آذر 1390, 21:28 عصر
چطوری میتونم با استفاده از تابع TerminateProcess در یونیت windows یه پروسه رو ببندم.


var
Process : TProcessItem;
begin
Process := ProcessInformation.RunningProcesses.FindByName('no tepad.exe');
if Assigned(Process) then
Process.TerminateProcess;
end;



نمیدونم چرا کد زیر کار نمیده.
با فرض بر اینکه NameToPid مقدار درستی برگشت میده، تابع OpenProcess نیاز به مجوز PROCESS_TERMINATE داره، که شما بهش همچین مجوزی ندادید. فراخوانی توابع API ویندوز را داخل Win32Check قرار بدید، که متوجه بشید چه تابعی، چرا با مشکل مواجه شده. کد مربوطه از سورس TProcessInfo :


function TProcessItem.TerminateProcess: Boolean;
var
hProcess : THandle;
begin
Result := False;
hProcess := OpenProcess(PROCESS_TERMINATE,False,FProcessID);
if hProcess > 0 then
try
Result := Win32Check(Windows.TerminateProcess(hProcess,0));
finally
CloseHandle(hProcess);
end;
end;