zoukankan      html  css  js  c++  java
  • 用Delphi创建windows服务程序

    Windows 2000/XP和2003等支持一种叫做"服务程序"的东西.程序作为服务启动有以下几个好处:
    (1)不用登陆进系统即可运行.
    (2)具有SYSTEM特权.所以你在进程管理器里面是无法结束它的.
    笔者在2003年为一公司开发机顶盒项目的时候,曾经写过课件上传和媒体服务,下面就介绍一下如何用Delphi7创建一个Service程序.
    运行Delphi7,选择菜单 File-->New-->Other--->Service Application.将生成一个服务程序的框架.将工程保存为 ServiceDemo.dpr和Unit_Main.pas,然后回到主框架.我们注意到,Service有几个属性.其中以下几个是我们比较常用的:
    (1)DisplayName:服务的显示名称
    (2)Name:服务名称.
    我们在这里将DisplayName的值改为"Delphi服务演示程序",Name改 为"DelphiService".编译这个项目,将得到 ServiceDemo.exe.这已经是一个服务程序了!进入CMD模式,切换致工程所在目 录,运行命令"ServiceDemo.exe /install",将提示服务安装成功!然后"net start DelphiService"将启 动这个服务.进入控制面版-->管理工具-->服务,将显示这个服务和当前状态.不过这个服务现在什么也干不了,因为我们还没有写代码:) 先"net stop DelphiService"停止再"ServiceDemo.exe /uninstall"删除这个服务.回到Delphi7 的IDE.
    我们的计划是为这个服务添加一个主窗口,运行后任务栏显示程序的图标,双击图标将显示主窗口,上面有一个按钮,点击该按钮将实现Ctrl+Alt+Del功能.
    实际上,服务程序莫认是工作于Winlogon桌面的,可以打开控制面板,查看我们刚才 那个服务的属性-->登陆,其中"允许服务与桌面交互 "是不打钩的.怎么办?呵呵,回到IDE,注意那个布尔属性:Interactive,当这 个属性为True的时候,该服务程序就可以与桌面交互了.
    File-->New-->Form为服务添加窗口FrmMain,单元保存为Unit_FrmMain,并且把这个窗口设置为手工创建.完成后的代码如下:
    unit Unit_Main;
    interface
    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, Unit_FrmMain;
    type
    TDelphiService = class(TService)
    procedure ServiceContinue(Sender: TService; var Continued: Boolean);
    procedure ServiceExecute(Sender: TService);
    procedure ServicePause(Sender: TService; var Paused: Boolean);
    procedure ServiceShutdown(Sender: TService);
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
    private
    { Private declarations }
    public
    function GetServiceController: TServiceController; override;
    { Public declarations }
    end;
    var
    DelphiService: TDelphiService;
    FrmMain: TFrmMain;
    implementation
    {$R *.DFM}
    procedure ServiceController(CtrlCode: DWord); stdcall;
    begin
    DelphiService.Controller(CtrlCode);
    end;
    function TDelphiService.GetServiceController: TServiceController;
    begin
    Result := ServiceController;
    end;
    procedure TDelphiService.ServiceContinue(Sender: TService;
    var Continued: Boolean);
    begin
    while not Terminated do
    begin
    Sleep(10);
    ServiceThread.ProcessRequests(False);
    end;
    end;
    procedure TDelphiService.ServiceExecute(Sender: TService);
    begin
    while not Terminated do
    begin
    Sleep(10);
    ServiceThread.ProcessRequests(False);
    end;
    end;
    procedure TDelphiService.ServicePause(Sender: TService;
    var Paused: Boolean);
    begin
    Paused := True;
    end;
    procedure TDelphiService.ServiceShutdown(Sender: TService);
    begin
    gbCanClose := true;
    FrmMain.Free;
    Status := csStopped;
    ReportStatus();
    end;
    procedure TDelphiService.ServiceStart(Sender: TService;
    var Started: Boolean);
    begin
    Started := True;
    Svcmgr.Application.CreateForm(TFrmMain, FrmMain);
    gbCanClose := False;
    FrmMain.Hide;
    end;
    procedure TDelphiService.ServiceStop(Sender: TService;
    var Stopped: Boolean);
    begin
    Stopped := True;
    gbCanClose := True;
    FrmMain.Free;
    end;
    end.
    主窗口单元如下:
    unit Unit_FrmMain;
    interface
    uses
    Windows, Messages, SysUtils, Variants, Classes, ShellApi, Graphics, Controls, Forms,
    Dialogs, ExtCtrls, StdCtrls;
    const
    WM_TrayIcon = WM_USER + 1234;
    type
    TFrmMain = class(TForm)
    Timer1: TTimer;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormDestroy(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    private
    { Private declarations }
    IconData: TNotifyIconData;
    procedure AddIconToTray;
    procedure DelIconFromTray;
    procedure TrayIconMessage(var Msg: TMessage); message WM_TrayIcon;
    procedure SysButtonMsg(var Msg: TMessage); message WM_SYSCOMMAND;
    public
    { Public declarations }
    end;
    var
    FrmMain: TFrmMain;
    gbCanClose: Boolean;
    implementation
    {$R *.dfm}
    procedure TFrmMain.FormCreate(Sender: TObject);
    begin
    FormStyle := fsStayOnTop;
    SetWindowLong(Application.Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
    gbCanClose := False;
    Timer1.Interval := 1000;
    Timer1.Enabled := True;
    end;
    procedure TFrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
    CanClose := gbCanClose;
    if not CanClose then
    begin
    Hide;
    end;
    end;
    procedure TFrmMain.FormDestroy(Sender: TObject);
    begin
    Timer1.Enabled := False;
    DelIconFromTray;
    end;
    procedure TFrmMain.AddIconToTray;
    begin
    ZeroMemory(@IconData, SizeOf(TNotifyIconData));
    IconData.cbSize := SizeOf(TNotifyIconData);
    IconData.Wnd := Handle;
    IconData.uID := 1;
    IconData.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
    IconData.uCallbackMessage := WM_TrayIcon;
    IconData.hIcon := Application.Icon.Handle;
    IconData.szTip := Delphi服务演示程序;
    Shell_NotifyIcon(NIM_ADD, @IconData);
    end;
    procedure TFrmMain.DelIconFromTray;
    begin
    Shell_NotifyIcon(NIM_DELETE, @IconData);
    end;
    procedure TFrmMain.SysButtonMsg(var Msg: TMessage);
    begin
    if (Msg.wParam = SC_CLOSE) or
    (Msg.wParam = SC_MINIMIZE) then Hide
    else inherited; // 执行默认动作
    end;
    procedure TFrmMain.TrayIconMessage(var Msg: TMessage);
    begin
    if (Msg.LParam = WM_LBUTTONDBLCLK) then Show();
    end;
    procedure TFrmMain.Timer1Timer(Sender: TObject);
    begin
    AddIconToTray;
    end;
    procedure SendHokKey;stdcall;
    var
    HDesk_WL: HDESK;
    begin
    HDesk_WL := OpenDesktop (Winlogon, 0, False, DESKTOP_JOURNALPLAYBACK);
    if (HDesk_WL <> 0) then
    if (SetThreadDesktop (HDesk_WL) = True) then
    PostMessage(HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG (MOD_ALT or MOD_CONTROL, VK_DELETE));
    end;
    procedure TFrmMain.Button1Click(Sender: TObject);
    var
    dwThreadID : DWORD;
    begin
    CreateThread(nil, 0, @SendHokKey, nil, 0, dwThreadID);
    end;
    end.
    补充:
    (1)关于更多服务程序的演示程序,请访问以下Urlhttp://www.torry.net/pages.php?id=226,上面包含了多个演示如何控制和管理系统服务的代码.
    (2)请切记:Windows实际上存在多个桌面.例如屏幕传输会出现白屏,可能有两个原因:一是系统处于锁定或未登陆桌面,二是处于屏幕保护桌面.这时候要将当前桌面切换到该桌面才能抓屏.
    (3)关于服务程序与桌面交互,还有种动态切换方法.大概单元如下:
    unit ServiceDesktop;
    interface
    function InitServiceDesktop: boolean;
    procedure DoneServiceDeskTop;
    implementation
    uses Windows, SysUtils;
    const
    DefaultWindowStation = WinSta0;
    DefaultDesktop = Default;
    var
    hwinstaSave: HWINSTA;
    hdeskSave: HDESK;
    hwinstaUser: HWINSTA;
    hdeskUser: HDESK;
    function InitServiceDesktop: boolean;
    var
    dwThreadId: DWORD;
    begin
    dwThreadId := GetCurrentThreadID;
    // Ensure connection to service window station and desktop, and
    // save their handles.
    hwinstaSave := GetProcessWindowStation;
    hdeskSave := GetThreadDesktop(dwThreadId);
    hwinstaUser := OpenWindowStation(DefaultWindowStation, FALSE, MAXIMUM_ALLOWED);
    if hwinstaUser = 0 then
    begin
    OutputDebugString(PChar(OpenWindowStation failed + SysErrorMessage(GetLastError)));
    Result := false;
    exit;
    end;
    if not SetProcessWindowStation(hwinstaUser) then
    begin
    OutputDebugString(SetProcessWindowStation failed);
    Result := false;
    exit;
    end;
    hdeskUser := OpenDesktop(DefaultDesktop, 0, FALSE, MAXIMUM_ALLOWED);
    if hdeskUser = 0 then
    begin
    OutputDebugString(OpenDesktop failed);
    SetProcessWindowStation(hwinstaSave);
    CloseWindowStation(hwinstaUser);
    Result := false;
    exit;
    end;
    Result := SetThreadDesktop(hdeskUser);
    if not Result then
    OutputDebugString(PChar(SetThreadDesktop + SysErrorMessage(GetLastError)));
    end;
    procedure DoneServiceDeskTop;
    begin
    // Restore window station and desktop.
    SetThreadDesktop(hdeskSave);
    SetProcessWindowStation(hwinstaSave);
    if hwinstaUser <> 0 then
    CloseWindowStation(hwinstaUser);
    if hdeskUser <> 0 then
    CloseDesktop(hdeskUser);
    end;
    initialization
    InitServiceDesktop;
    finalization
    DoneServiceDesktop;
    end.
    (4)关于安装服务如何添加服务描述.有两种方法:一是修改注册表.服务的详细信息都位 于HKEY_LOCAL_MACHINE"SYSTEM" ControlSet001"Services"下面,例如我们刚才那个服务就位于 HKEY_LOCAL_MACHINE"SYSTEM" ControlSet001"Services"DelphiService下.第二种方法就是 先用QueryServiceConfig2函数获取服务信息,然后ChangeServiceConfig2来改变描述.用Delphi实现的话,单元 如下:
    unit WinSvcEx;
    interface
    uses Windows, WinSvc;
    const
    //
    // Service config info levels
    //
    SERVICE_CONFIG_DESCRIPTION = 1;
    SERVICE_CONFIG_FAILURE_ACTIONS = 2;
    //
    // DLL name of imported functions
    //
    AdvApiDLL = advapi32.dll;
    type
    //
    // Service description string
    //
    PServiceDescriptionA = ^TServiceDescriptionA;
    PServiceDescriptionW = ^TServiceDescriptionW;
    PServiceDescription = PServiceDescriptionA;
    {$EXTERNALSYM _SERVICE_DESCRIPTIONA}
    _SERVICE_DESCRIPTIONA = record
    lpDescription : PAnsiChar;
    end;
    {$EXTERNALSYM _SERVICE_DESCRIPTIONW}
    _SERVICE_DESCRIPTIONW = record
    lpDescription : PWideChar;
    end;
    {$EXTERNALSYM _SERVICE_DESCRIPTION}
    _SERVICE_DESCRIPTION = _SERVICE_DESCRIPTIONA;
    {$EXTERNALSYM SERVICE_DESCRIPTIONA}
    SERVICE_DESCRIPTIONA = _SERVICE_DESCRIPTIONA;
    {$EXTERNALSYM SERVICE_DESCRIPTIONW}
    SERVICE_DESCRIPTIONW = _SERVICE_DESCRIPTIONW;
    {$EXTERNALSYM SERVICE_DESCRIPTION}
    SERVICE_DESCRIPTION = _SERVICE_DESCRIPTIONA;
    TServiceDescriptionA = _SERVICE_DESCRIPTIONA;
    TServiceDescriptionW = _SERVICE_DESCRIPTIONW;
    TServiceDescription = TServiceDescriptionA;
    //
    // Actions to take on service failure
    //
    {$EXTERNALSYM _SC_ACTION_TYPE}
    _SC_ACTION_TYPE = (SC_ACTION_NONE, SC_ACTION_RESTART, SC_ACTION_REBOOT, SC_ACTION_RUN_COMMAND);
    {$EXTERNALSYM SC_ACTION_TYPE}
    SC_ACTION_TYPE = _SC_ACTION_TYPE;
    PServiceAction = ^TServiceAction;
    {$EXTERNALSYM _SC_ACTION}
    _SC_ACTION = record
    aType : SC_ACTION_TYPE;
    Delay : DWORD;
    end;
    {$EXTERNALSYM SC_ACTION}
    SC_ACTION = _SC_ACTION;
    TServiceAction = _SC_ACTION;
    PServiceFailureActionsA = ^TServiceFailureActionsA;
    PServiceFailureActionsW = ^TServiceFailureActionsW;
    PServiceFailureActions = PServiceFailureActionsA;
    {$EXTERNALSYM _SERVICE_FAILURE_ACTIONSA}
    _SERVICE_FAILURE_ACTIONSA = record
    dwResetPeriod : DWORD;
    lpRebootMsg : LPSTR;
    lpCommand : LPSTR;
    cActions : DWORD;
    lpsaActions : ^SC_ACTION;
    end;
    {$EXTERNALSYM _SERVICE_FAILURE_ACTIONSW}
    _SERVICE_FAILURE_ACTIONSW = record
    dwResetPeriod : DWORD;
    lpRebootMsg : LPWSTR;
    lpCommand : LPWSTR;
    cActions : DWORD;
    lpsaActions : ^SC_ACTION;
    end;
    {$EXTERNALSYM _SERVICE_FAILURE_ACTIONS}
    _SERVICE_FAILURE_ACTIONS = _SERVICE_FAILURE_ACTIONSA;
    {$EXTERNALSYM SERVICE_FAILURE_ACTIONSA}
    SERVICE_FAILURE_ACTIONSA = _SERVICE_FAILURE_ACTIONSA;
    {$EXTERNALSYM SERVICE_FAILURE_ACTIONSW}
    SERVICE_FAILURE_ACTIONSW = _SERVICE_FAILURE_ACTIONSW;
    {$EXTERNALSYM SERVICE_FAILURE_ACTIONS}
    SERVICE_FAILURE_ACTIONS = _SERVICE_FAILURE_ACTIONSA;
    TServiceFailureActionsA = _SERVICE_FAILURE_ACTIONSA;
    TServiceFailureActionsW = _SERVICE_FAILURE_ACTIONSW;
    TServiceFailureActions = TServiceFailureActionsA;
    ///////////////////////////////////////////////////////////////////////////
    // API Function Prototypes
    ///////////////////////////////////////////////////////////////////////////
    TQueryServiceConfig2 = function (hService : SC_HANDLE; dwInfoLevel : DWORD; lpBuffer : pointer;
    cbBufSize : DWORD; var pcbBytesNeeded) : BOOL; stdcall;
    TChangeServiceConfig2 = function (hService : SC_HANDLE; dwInfoLevel : DWORD; lpInfo : pointer) : BOOL; stdcall;
    var
    hDLL : THandle ;
    LibLoaded : boolean ;
    var
    OSVersionInfo : TOSVersionInfo;
    {$EXTERNALSYM QueryServiceConfig2A}
    QueryServiceConfig2A : TQueryServiceConfig2;
    {$EXTERNALSYM QueryServiceConfig2W}
    QueryServiceConfig2W : TQueryServiceConfig2;
    {$EXTERNALSYM QueryServiceConfig2}
    QueryServiceConfig2 : TQueryServiceConfig2;
    {$EXTERNALSYM ChangeServiceConfig2A}
    ChangeServiceConfig2A : TChangeServiceConfig2;
    {$EXTERNALSYM ChangeServiceConfig2W}
    ChangeServiceConfig2W : TChangeServiceConfig2;
    {$EXTERNALSYM ChangeServiceConfig2}
    ChangeServiceConfig2 : TChangeServiceConfig2;
    implementation
    initialization
    OSVersionInfo.dwOSVersionInfoSize := SizeOf(OSVersionInfo);
    GetVersionEx(OSVersionInfo);
    if (OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT) and (OSVersionInfo.dwMajorVersion >= 5) then
    begin
    if hDLL = 0 then
    begin
    hDLL:=GetModuleHandle(AdvApiDLL);
    LibLoaded := False;
    if hDLL = 0 then
    begin
    hDLL := LoadLibrary(AdvApiDLL);
    LibLoaded := True;
    end;
    end;
    if hDLL <> 0 then
    begin
    @QueryServiceConfig2A := GetProcAddress(hDLL, QueryServiceConfig2A);
    @QueryServiceConfig2W := GetProcAddress(hDLL, QueryServiceConfig2W);
    @QueryServiceConfig2 := @QueryServiceConfig2A;
    @ChangeServiceConfig2A := GetProcAddress(hDLL, ChangeServiceConfig2A);
    @ChangeServiceConfig2W := GetProcAddress(hDLL, ChangeServiceConfig2W);
    @ChangeServiceConfig2 := @ChangeServiceConfig2A;
    end;
    end
    else
    begin
    @QueryServiceConfig2A := nil;
    @QueryServiceConfig2W := nil;
    @QueryServiceConfig2 := nil;
    @ChangeServiceConfig2A := nil;
    @ChangeServiceConfig2W := nil;
    @ChangeServiceConfig2 := nil;
    end;
    finalization
    if (hDLL <> 0) and LibLoaded then
    FreeLibrary(hDLL);
    end.
    unit winntService;
    interface
    uses
    Windows,WinSvc,WinSvcEx;
    function InstallService(const strServiceName,strDisplayName,strDescription,strFilename: string):Boolean;
    //eg:InstallService(服务名称,显示名称,描述信息,服务文件);
    procedure UninstallService(strServiceName:string);
    implementation
    function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;
    asm
    PUSH EDI
    PUSH ESI
    PUSH EBX
    MOV ESI,EAX
    MOV EDI,EDX
    MOV EBX,ECX
    XOR AL,AL
    TEST ECX,ECX
    JZ @@1
    REPNE SCASB
    JNE @@1
    INC ECX
    @@1: SUB EBX,ECX
    MOV EDI,ESI
    MOV ESI,EDX
    MOV EDX,EDI
    MOV ECX,EBX
    SHR ECX,2
    REP MOVSD
    MOV ECX,EBX
    AND ECX,3
    REP MOVSB
    STOSB
    MOV EAX,EDX
    POP EBX
    POP ESI
    POP EDI
    end;
    function StrPCopy(Dest: PChar; const Source: string): PChar;
    begin
    Result := StrLCopy(Dest, PChar(Source), Length(Source));
    end;
    function InstallService(const strServiceName,strDisplayName,strDescription,strFilename: string):Boolean;
    var
    //ss : TServiceStatus;
    //psTemp : PChar;
    hSCM,hSCS:THandle;
    srvdesc : PServiceDescription;
    desc : string;
    //SrvType : DWord;
    lpServiceArgVectors:pchar;
    begin
    Result:=False;
    //psTemp := nil;
    //SrvType := SERVICE_WIN32_OWN_PROCESS and SERVICE_INTERACTIVE_PROCESS;
    hSCM:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);//连接服务数据库
    if hSCM=0 then Exit;//MessageBox(hHandle,Pchar(SysErrorMessage(GetLastError)),服务程序管理器,MB_ICONERROR+MB_TOPMOST);
    hSCS:=CreateService( //创建服务函数
    hSCM, // 服务控制管理句柄
    Pchar(strServiceName), // 服务名称
    Pchar(strDisplayName), // 显示的服务名称
    SERVICE_ALL_ACCESS, // 存取权利
    SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS,// 服务类型 SERVICE_WIN32_SHARE_PROCESS
    SERVICE_AUTO_START, // 启动类型
    SERVICE_ERROR_IGNORE, // 错误控制类型
    Pchar(strFilename), // 服务程序
    nil, // 组服务名称
    nil, // 组标识
    nil, // 依赖的服务
    nil, // 启动服务帐号
    nil); // 启动服务口令
    if hSCS=0 then Exit;//MessageBox(hHandle,Pchar(SysErrorMessage(GetLastError)),Pchar(Application.Title),MB_ICONERROR+MB_TOPMOST);
    if Assigned(ChangeServiceConfig2) then
    begin
    desc := Copy(strDescription,1,1024);
    GetMem(srvdesc,SizeOf(TServiceDescription));
    GetMem(srvdesc^.lpDescription,Length(desc) + 1);
    try
    StrPCopy(srvdesc^.lpDescription, desc);
    ChangeServiceConfig2(hSCS,SERVICE_CONFIG_DESCRIPTION,srvdesc);
    finally
    FreeMem(srvdesc^.lpDescription);
    FreeMem(srvdesc);
    end;
    end;
    lpServiceArgVectors := nil;
    if not StartService(hSCS, 0, lpServiceArgVectors) then //启动服务
    Exit; //MessageBox(hHandle,Pchar(SysErrorMessage(GetLastError)),Pchar(Application.Title),MB_ICONERROR+MB_TOPMOST);
    CloseServiceHandle(hSCS); //关闭句柄
    Result:=True;
    end;
    procedure UninstallService(strServiceName:string);
    var
    SCManager: SC_HANDLE;
    Service: SC_HANDLE;
    Status: TServiceStatus;
    begin
    SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
    if SCManager = 0 then Exit;
    try
    Service := OpenService(SCManager, Pchar(strServiceName), SERVICE_ALL_ACCESS);
    ControlService(Service, SERVICE_CONTROL_STOP, Status);
    DeleteService(Service);
    CloseServiceHandle(Service);
    finally
    CloseServiceHandle(SCManager);
    end;
    end;
    end.
    (5)如何暴力关闭一个服务程序,实现我们以前那个"NT工具箱"的功能?首先,根据进程名称来杀死进程是用以下函数:
    uses Tlhelp32;
    function KillTask(ExeFileName: string): Integer;
    const
    PROCESS_TERMINATE = 01;
    var
    ContinueLoop: BOOL;
    FSnapshotHandle: THandle;
    FProcessEntry32: TProcessEntry32;
    begin
    Result := 0;
    FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
    ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
    while Integer(ContinueLoop) <> 0 do
    begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
    UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
    UpperCase(ExeFileName))) then
    Result := Integer(TerminateProcess(
    OpenProcess(PROCESS_TERMINATE,
    BOOL(0),
    FProcessEntry32.th32ProcessID),
    0));
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
    end;
    CloseHandle(FSnapshotHandle);
    end;
    但是对于服务程序,它会提示"拒绝访问".其实只要程序拥有Debug权限即可:
    function EnableDebugPrivilege: Boolean;
    function EnablePrivilege(hToken: Cardinal; PrivName: string; bEnable: Boolean): Boolean;
    var
    TP: TOKEN_PRIVILEGES;
    Dummy: Cardinal;
    begin
    TP.PrivilegeCount := 1;
    LookupPrivilegeValue(nil, pchar(PrivName), TP.Privileges[0].Luid);
    if bEnable then
    TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
    else TP.Privileges[0].Attributes := 0;
    AdjustTokenPrivileges(hToken, False, TP, SizeOf(TP), nil, Dummy);
    Result := GetLastError = ERROR_SUCCESS;
    end;
    var
    hToken: Cardinal;
    begin
    OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
    result:=EnablePrivilege(hToken, SeDebugPrivilege, True);
    CloseHandle(hToken);
    end;
    使用方法:
    EnableDebugPrivilege;//提升权限
    KillTask(xxxx.exe);//关闭该服务?p align="right">(Delphi共和国转载)
  • 相关阅读:
    编程作业4.1:神经网络反向传播(BP算法)
    700. Search in a Binary Search Tree
    671. Second Minimum Node In a Binary Tree
    653. Two Sum IV
    606. Construct String from Binary Tree
    590. N-ary Tree Postorder Traversal
    589. N-ary Tree Preorder Traversal
    617. Merge Two Binary Trees
    SHELL 变量
    egrep 正则表达式
  • 原文地址:https://www.cnblogs.com/baoguo/p/1352406.html
Copyright © 2011-2022 走看看