如何从Delphi中的服务名/句柄中找到进程标识? [英] How can I find the process id from the service name/handle in Delphi?
问题描述
请注意我有只接受这个解决方案,以便接受一个完整的delphi代码解决方案,所有这一切都归功于Jk,因为我指出了正确的路径。
-
好的,我已经能够弄清楚如何使用Jk的答案,并在delphi中提出了这个解决方案。
为了参考,这是Jk提供的链接:
我的解决方案:
单元演示;
接口
使用
Windows,Forms,SysUtils,
StdCtrls,WinSvc,Controls,Classes;
类型
//基本演示用法的表单
TForm6 =类(TForm)
Button1:TButton;
Memo1:TMemo;
procedure Button1Click(Sender:TObject);
结束
//定义为用作返回缓冲区的记录
_SERVICE_STATUS_PROCESS = record
dwServiceType:DWORD;
dwCurrentState:DWORD;
dwControlsAccepted:DWORD;
dwWin32ExitCode:DWORD;
dwServiceSpecificExitCode:DWORD;
dwCheckPoint:DWORD;
dwWaitHint:DWORD;
dwProcessId:DWORD;
dwServiceFlags:DWORD;
结束
//函数原型
函数QueryServiceStatusEx(
SC_HANDLE:SC_Handle;
SC_STATUS_TYPE:Cardinal;
out lpBuffer:_SERVICE_STATUS_PROCESS;
cbBufSize:DWORD;
out pcbBytesNeeded:LPDWORD
):BOOL;标准
//内部设置函数
函数GetPid(sService:String; sMachine:String =''):Cardinal;
var
Form6:TForm6;
实现
{$ R * .dfm}
const
// windows api库
advapi32 ='advapi32.dll';
//定义api调用
函数QueryServiceStatusEx; external advapi32 name'QueryServiceStatusEx';
//演示用法
程序TForm6.Button1Click(Sender:TObject);
begin
Memo1.Lines.Add(IntToStr(Integer(GetPid('Service'))))
end;
函数GetPid(sService:String; sMachine:String =''):Cardinal;
var
schm,
schs:SC_Handle;
SC_STATUS_TYPE:红衣主教;
lpBuffer:_SERVICE_STATUS_PROCESS;
cbBufSize:DWORD;
pcbBytesNeeded:LPDWORD;
begin
//打开服务管理器(在WinSvc中定义)
schm:= OpenSCManager(PChar(sMachine),nil,SC_MANAGER_CONNECT);
//将状态类型设置为SC_STATUS_PROCESS_INFO
//这是当前支持的唯一值
SC_STATUS_TYPE:= $ 00000000;
//将缓冲区大小设置为记录的大小
cbBufSize:= sizeof(_SERVICE_STATUS_PROCESS);
if(schm> 0)then
begin
//获取服务句柄
schs:= OpenService(schm,PChar(sService),SERVICE_QUERY_STATUS);
if(schs> 0)then
begin
//调用函数
QueryServiceStatusEx(
schs,
SC_STATUS_TYPE,
lpBuffer,
cbBufSize,
pcbBytesNeeded);
CloseServiceHandle(schs);
结束
CloseServiceHandle(schm);
结束
结果:= lpBuffer.dwProcessId;
结束
结束。
请注意,不包括所有外部命名和其他必需品。
I have the service name for a windows service in delphi, and I know how to get the handle from that as well. What I need to do is stop a service, and if the stop fails for some reason I need to kill the process associated with the service. The problem is that I have multiple services running from the same executable, so I can't use the executable name to kill the process. This means I need the process id to kill the proper associated process. How can I get this id or some way to kill the proper process from the service name or handle?
Please note I have only accepted this solution so that a full delphi code solution is accepted, all due thanks to Jk though for pointing me on the correct path.
--
Ok, I've been able to figure out how to use the answer by Jk and have come up with this solution in delphi.
For reference, this is the link provided by Jk:
My Solution:
unit Demo;
interface
uses
Windows, Forms, SysUtils,
StdCtrls, WinSvc, Controls, Classes;
type
//Form for basic demo usage
TForm6 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
end;
//Record defined for use as return buffer
_SERVICE_STATUS_PROCESS = record
dwServiceType: DWORD;
dwCurrentState: DWORD;
dwControlsAccepted: DWORD;
dwWin32ExitCode: DWORD;
dwServiceSpecificExitCode: DWORD;
dwCheckPoint: DWORD;
dwWaitHint: DWORD;
dwProcessId: DWORD;
dwServiceFlags: DWORD;
end;
//Function Prototype
function QueryServiceStatusEx(
SC_HANDLE: SC_Handle;
SC_STATUS_TYPE: Cardinal;
out lpBuffer: _SERVICE_STATUS_PROCESS;
cbBufSize: DWORD;
out pcbBytesNeeded: LPDWORD
): BOOL; stdcall;
//internal setup function
function GetPid(sService: String; sMachine: String = '') : Cardinal;
var
Form6: TForm6;
implementation
{$R *.dfm}
const
// windows api library
advapi32 = 'advapi32.dll';
//define the api call
function QueryServiceStatusEx; external advapi32 name 'QueryServiceStatusEx';
//for demo usage
procedure TForm6.Button1Click(Sender: TObject);
begin
Memo1.Lines.Add(IntToStr(Integer(GetPid('Service'))))
end;
function GetPid(sService: String; sMachine: String = '') : Cardinal;
var
schm,
schs: SC_Handle;
SC_STATUS_TYPE: Cardinal;
lpBuffer: _SERVICE_STATUS_PROCESS;
cbBufSize: DWORD;
pcbBytesNeeded: LPDWORD;
begin
//open the service manager (defined in WinSvc)
schm := OpenSCManager(PChar(sMachine), nil, SC_MANAGER_CONNECT);
//set the status type to SC_STATUS_PROCESS_INFO
//this is currently the only value supported
SC_STATUS_TYPE := $00000000;
//set the buffer size to the size of the record
cbBufSize := sizeof(_SERVICE_STATUS_PROCESS);
if (schm>0) then
begin
//grab the service handle
schs := OpenService(schm, PChar(sService), SERVICE_QUERY_STATUS);
if (schs>0) then
begin
//call the function
QueryServiceStatusEx(
schs,
SC_STATUS_TYPE,
lpBuffer,
cbBufSize,
pcbBytesNeeded);
CloseServiceHandle(schs);
end;
CloseServiceHandle(schm);
end;
Result := lpBuffer.dwProcessId;
end;
end.
Please note that not all external naming and other necessities are included.
这篇关于如何从Delphi中的服务名/句柄中找到进程标识?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!