如何用Delphi启/禁用服务程序,主意不是启动,顺便问下SPI是什么,听说是网络,哪里又有资料那
RT
谢谢大家,详细一些

解决方案 »

  1.   

    http://borland.mblogger.cn/aiirii/posts/2893.aspx相關 Api:ChangeServiceConfigThe ChangeServiceConfig function changes the configuration parameters of a service.To change the optional configuration parameters, use the ChangeServiceConfig2 function.
    BOOL ChangeServiceConfig(
      SC_HANDLE hService,
      DWORD dwServiceType,
      DWORD dwStartType,
      DWORD dwErrorControl,
      LPCTSTR lpBinaryPathName,
      LPCTSTR lpLoadOrderGroup,
      LPDWORD lpdwTagId,
      LPCTSTR lpDependencies,
      LPCTSTR lpServiceStartName,
      LPCTSTR lpPassword,
      LPCTSTR lpDisplayName
    );reference: http://www.bugtraq.ru/cgi-bin/forum.mcgi?type=sb&b=2&m=104683sample:procedure ConfigService(ServiceName: string; fDisable: boolean; lpDesc: string);
    type
      PQueryServiceLockStatus = ^TQueryServiceLockStatus;
    const
      SERVICE_CONFIG_DESCRIPTION: DWord = 1;
    var
      DynChangeServiceConfig2: function(
        hService: SC_HANDLE; // handle to service
        dwInfoLevel: DWORD; // information level
        lpInfo: Pointer): Bool; StdCall; // new data
        
      sclLock: SC_LOCK;
      lpqslsBuf: PQueryServiceLockStatus; //LPQUERY_SERVICE_LOCK_STATUS;
      dwBytesNeeded, dwStartType: DWORD;
      schSCManager, schService: SC_Handle;
      aLibHndl: THandle;
      TempP: PChar;
      ret: boolean;
    begin
      schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);  if schSCManager = 0 then raise Exception.Create(SysErrorMessage(GetLastError));
      // Need to acquire database lock before reconfiguring.
      sclLock := LockServiceDatabase(schSCManager);
      try
        // If the database cannot be locked, report the details. 
        if (sclLock = nil) then
        begin
          // Exit if the database is not locked by another process.
          if (GetLastError() <> ERROR_SERVICE_DATABASE_LOCKED) then
            raise Exception.Create(SysErrorMessage(GetLastError));      // Allocate a buffer to get details about the lock.      lpqslsBuf := PQueryServiceLockStatus(LocalAlloc(LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS) + 256));
          if (lpqslsBuf = nil) then
            raise Exception.Create(SysErrorMessage(GetLastError));      // Get and print the lock status information.      if not (QueryServiceLockStatus(
            schSCManager,
            lpqslsBuf^,
            sizeof(QUERY_SERVICE_LOCK_STATUS) + 256,
            dwBytesNeeded)) then
            raise Exception.Create(SysErrorMessage(GetLastError));      if (lpqslsBuf^.fIsLocked > 0) then
          begin
            OutputDebugString(pchar('Locked by: ' + lpqslsBuf^.lpLockOwner +
              ' duration: ' + IntToStr(lpqslsBuf^.dwLockDuration) + ' seconds'));
          end
          else
            OutputDebugString(pchar('No longer locked'));      LocalFree(cardinal(lpqslsBuf));
          raise Exception.Create(SysErrorMessage(GetLastError));
        end;    // The database is locked, so it is safe to make changes.
        // Open a handle to the service.
        schService := OpenService(
          schSCManager, // SCManager database
          pchar(ServiceName), //'Sample_Srv', // name of service
          SERVICE_CHANGE_CONFIG); // need CHANGE access
        if (schService = 0) then
          raise Exception.Create(SysErrorMessage(GetLastError));    try
          if fDisable then
            dwStartType := SERVICE_DISABLED
          else
            dwStartType := SERVICE_DEMAND_START;      // Make the changes.
          // display name: no change
          if not (ChangeServiceConfig(
            schService, // handle of service
            SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS, //SERVICE_NO_CHANGE, // service type: no change
            dwStartType, // change service start type
            SERVICE_NO_CHANGE, // error control: no change
            nil, // binary path: no change
            nil, // load order group: no change
            nil, // tag ID: no change
            nil, // dependencies: no change
            nil, // account name: no change
            nil, // password: no change
            nil)) then
          begin
            raise Exception.Create(SysErrorMessage(GetLastError));
          end
          else
            OutputDebugString('ChangeServiceConfig SUCCESS');      //  sdBuf.lpDescription := lpDesc;
          aLibHndl := GetModuleHandle(advapi32);
          ret := aLibHndl <> 0;
          if not ret then Exit;
          try
          DynChangeServiceConfig2 := GetProcAddress(aLibHndl, 'ChangeServiceConfig2A');
          ret := @DynChangeServiceConfig2 <> nil;
          if not ret then Exit;
          TempP := PChar(lpDesc); //ChangeServiceConfig2      ret := DynChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, @TempP);      if not ret then
            raise Exception.Create(SysErrorMessage(GetLastError))
          else
            OutputDebugString('ChangeServiceConfig2 SUCCESS');
          finally
            FreeLibrary(aLibHndl);
          end;
        finally
          CloseServiceHandle(schService);
        end;
      finally
        // Release the database lock.
        UnlockServiceDatabase(sclLock);
        // Close the handle to the service.
        CloseServiceHandle(schService);
      end;
    end;procedure TForm1.btnConfigServiceClick(Sender: TObject);
    var
      sN, sStatus: string;
      i: integer;
    begin
      sN := lbServices.Items[lbServices.ItemIndex];
      i := Pos('---', sN);
      delete(sN, 1, i + 2);
      edit1.Text := sn;
      ConfigService(Sn, false, 'service test by ari');
    end;
      

  2.   

    ChangeServiceConfig到是可以,我记得advapi32的其他的一个函数可以轻松搞定,
    具体还真忘了,开启服务的还有印象
    找到服务的句柄hService后用StartService(),
    就搞定了,不过还是需要用循环测试QueryServiceStatus()的,用以证明已开启服务关闭的也可以两句搞定的,呵呵实在忘了,》》如何用Delphi启/禁用服务程序,主意不是启动
    你说的是不是START_PENDING状态?