Avatar billede tkandersen Nybegynder
03. august 2003 - 20:07 Der er 8 kommentarer

ExecProgram / ShellExecute - unit??

Jeg har set at ShellExecute ligger i ShellAPI.dcu - hvor ligger ExecProgram?

Jeg har søgt i Windows SDK hjælpen fra Delphi, men mangler lige hvilken unit jeg skal have med for at kunne bruge ExecProgram.
Avatar billede janbb Juniormester
03. august 2003 - 20:32 #1
Der er noget der hedder winexec(det er nok det du mener). :-)
Avatar billede dkn Nybegynder
03. august 2003 - 22:08 #2
winexec liger i windows.pas...
Avatar billede borrisholt Novice
04. august 2003 - 08:55 #3
Der er ikke en kommando der hedder ExecProgram. du skal bruge ShellExecute for at exekvere et program fra dit eget.
Avatar billede tkandersen Nybegynder
04. august 2003 - 11:47 #4
Aahh - ok? - Der stod blot at der var en makro ved navn ExecProgram i Delphi's Help(menu), Windows SDK. (Delphi 6).
Så lige at WinExec er med for bagud kompatibilitet - det anbefales at benytte CreateProcess i stedet for.
Jeg ville faktisk køre kommandoen 'net stop "....."' - er der en bedre måde at gøre det på ? Er der et direkte kald til at stoppe og starte services og hvor jeg samtidig kan aflæse status på navngivne services?
Avatar billede Slettet bruger
04. august 2003 - 11:51 #5
Så kan du bruge denne funktion:

procedure ExecuteShellCommand(cmdline: string; hidden: Boolean);
const
  flags: array [Boolean] of Integer = (SW_SHOWNORMAL, SW_HIDE);
var
  cmdbuffer: array [0..MAX_PATH] of Char;
begin
  GetEnvironmentVariable('COMSPEC', cmdBUffer, SizeOf(cmdBuffer));
  StrCat(cmdbuffer, ' /C ');
  StrPCopy(StrEnd(cmdbuffer), cmdline);
  WinExec(cmdbuffer, flags[hidden]);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  ExecuteShellCommand('net stop etellerandet', True);
end;
Avatar billede Slettet bruger
04. august 2003 - 11:53 #6
Avatar billede tkandersen Nybegynder
04. august 2003 - 13:09 #7
Tak for svarene...
Vil lige lade den stå hvis der er nogen der kan komme med en løsning på WinNT service kald (status, start, stop) - selvom det egentlig er sekundært sådan som jeg har formuleret spørgsmålet.
Hvis det er et spørgsmål om points så smider jeg gerne ekstra på.

Men winexec vil jeg nok ikke bruge da den kun er med for kompatibiliteten.
Fik lavet ShellExecute i aftes - jf. også hvad borrisholt skrev her til morgen - det var den mest indlysende, men jeg kunne bare ikke finde 'ExecProgram' makroen i Delphi.
Avatar billede borrisholt Novice
04. august 2003 - 13:41 #8
unit Services;

interface

uses
  classes, // TStrings
  windows, //DWORD
  WinSvc, // TEnumServiceStatus
  SysUtils; //StrPas

const
  cnMaxServices = 4096;
  SERVICE_KERNEL_DRIVER = $00000001;
  SERVICE_FILE_SYSTEM_DRIVER = $00000002;
  SERVICE_ADAPTER = $00000004;
  SERVICE_RECOGNIZER_DRIVER = $00000008;
  SERVICE_DRIVER = (SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER or SERVICE_RECOGNIZER_DRIVER);
  SERVICE_WIN32_OWN_PROCESS = $00000010;
  SERVICE_WIN32_SHARE_PROCESS = $00000020;
  SERVICE_WIN32 = (SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS);
  SERVICE_INTERACTIVE_PROCESS = $00000100;
  SERVICE_TYPE_ALL = (SERVICE_WIN32 or SERVICE_ADAPTER or SERVICE_DRIVER or SERVICE_INTERACTIVE_PROCESS);

type
  TSvcA = array[0..cnMaxServices] of TEnumServiceStatus;
  PSvcA = ^TSvcA;

function ServiceGetList(slServicesList: TStrings; sMachine: string = ''; dwServiceType: DWORD = SERVICE_WIN32; dwServiceState: DWord = SERVICE_STATE_ALL): Boolean;
//-------------------------------------
// Gets a list of services
//
// return TRUE if successful
//
// sMachine:
//  machine name, ie: \\SERVER
//  empty = local machine
//
// dwServiceType
//  SERVICE_WIN32,
//  SERVICE_DRIVER or
//  SERVICE_TYPE_ALL
//
// dwServiceState
//  SERVICE_ACTIVE,
//  SERVICE_INACTIVE or
//  SERVICE_STATE_ALL
//
// slServicesList
//  TStrings variable to storage
//
//-------------------------------------

function ServiceGetStatus(sMachine, sService: string): Integer;
//-------------------------------------
// get service status
//
// return status code if successful
// -1 if not
//
// return codes:
//  SERVICE_STOPPED
//  SERVICE_RUNNING
//  SERVICE_PAUSED
//
// following return codes
// are used to indicate that
// the service is in the
// middle of getting to one
// of the above states:
//  SERVICE_START_PENDING
//  SERVICE_STOP_PENDING
//  SERVICE_CONTINUE_PENDING
//  SERVICE_PAUSE_PENDING
//
// sMachine:
//  machine name, ie: \\SERVER
//  empty = local machine
//
// sService
//  service name, ie: Alerter
//-------------------------------------

function ServiceRunning(sMachine, sService: string): Boolean;
//-------------------------------------
// return TRUE if the specified
// service is running, defined by
// the status code SERVICE_RUNNING.
// return FALSE if the service
// is in any other state, including
// any pending states
//-------------------------------------

function ServiceStart(sMachine, sService: string): Boolean;
//-------------------------------------
// start service
//
// return TRUE if successful
//
// sMachine:
//  machine name, ie: \\SERVER
//  empty = local machine
//
// sService
//  service name, ie: Alerter
//-------------------------------------

function ServiceStop(sMachine, sService: string): Boolean;
//-------------------------------------
// stop service
//
// return TRUE if successful
//
// sMachine:
//  machine name, ie: \\SERVER
//  empty = local machine
//
// sService
//  service name, ie: Alerter
//-------------------------------------

function ServiceStopped(sMachine, sService: string): Boolean;
//-------------------------------------
// return TRUE if the specified
// service was stopped, defined by
// the status code SERVICE_STOPPED.
//-------------------------------------

implementation

function ServiceGetList(slServicesList: TStrings; sMachine: string = ''; dwServiceType: DWORD = SERVICE_WIN32; dwServiceState: DWord = SERVICE_STATE_ALL): Boolean;
var
  j: Integer;
  schm: SC_Handle;
  ssa: PSvcA;
  nBytesNeeded, nServices, nResumeHandle: DWord;
begin
  Result := False;
  schm := OpenSCManager(pChar(sMachine), nil, SC_MANAGER_ALL_ACCESS); // connect to the service control manager

  if (schm > 0) then // if successful...
  begin
    nResumeHandle := 0;
    New(ssa);
    EnumServicesStatus(schm, dwServiceType, dwServiceState, ssa^[0], SizeOf(ssa^), nBytesNeeded, nServices, nResumeHandle);

    // Assume that our initial array was large enough to hold all entries. add code to enumerate if necessary.

    for j := 0 to nServices - 1 do
      slServicesList.Add(StrPas(ssa^[j].lpDisplayName));
    Result := True;
    Dispose(ssa);
    CloseServiceHandle(schm); // close service control manager handle
  end;
end;

function ServiceGetStatus(sMachine, sService: string): Integer;
var
  schm,
    schs: SC_Handle;
  ss: TServiceStatus;
  dwStat: Integer;
begin
  dwStat := -1;
  schm := OpenSCManager(pChar(sMachine), nil, SC_MANAGER_CONNECT);
  if (schm > 0) then // if successful...
  begin
    schs := OpenService(schm, pChar(sService), SERVICE_QUERY_STATUS);
    if (schs > 0) then // if successful...
      if (QueryServiceStatus(schs, ss)) then
        dwStat := ss.dwCurrentState;
    CloseServiceHandle(schs);
    CloseServiceHandle(schm);
  end;
  Result := dwStat;
end;

function ServiceRunning(sMachine, sService: string): Boolean;
begin
  Result := SERVICE_RUNNING = ServiceGetStatus(sMachine, sService);
end;

function ServiceStopped(sMachine, sService: string): Boolean;
begin
  Result := SERVICE_STOPPED = ServiceGetStatus(sMachine, sService);
end;

function ServiceStart(sMachine, sService: string): Boolean;
var
  schm, schs: SC_Handle;
  ss: TServiceStatus;
  psTemp: pChar;
  dwChkP: DWord;
begin
  ss.dwCurrentState := 0;
  schm := OpenSCManager(pChar(sMachine), nil, SC_MANAGER_CONNECT);

  if (schm > 0) then // if successful...
  begin
    schs := OpenService(schm, pChar(sService), SERVICE_START or SERVICE_QUERY_STATUS);
    if (schs > 0) then // if successful...
    begin
      psTemp := nil;
      if (StartService(schs, 0, psTemp)) then
      begin
        if (QueryServiceStatus(schs, ss)) then
        begin
          while (SERVICE_RUNNING <> ss.dwCurrentState) do
          begin
            dwChkP := ss.dwCheckPoint;
            SleepEx(ss.dwWaitHint, False);

            if (not QueryServiceStatus(schs, ss)) then
              break;

            if (ss.dwCheckPoint < dwChkP) then
              break;
          end;
        end;
      end;
      CloseServiceHandle(schs);
    end;
    CloseServiceHandle(schm);
  end;

  Result := SERVICE_RUNNING = ss.dwCurrentState;
end;

function ServiceStop(sMachine, sService: string): Boolean;
var
  schm, schs: SC_Handle;
  ss: TServiceStatus;
  dwChkP: DWord;
begin
  schm := OpenSCManager(pChar(sMachine), nil, SC_MANAGER_CONNECT);

  if (schm > 0) then // if successful...
  begin
    schs := OpenService(schm, pChar(sService), SERVICE_STOP or SERVICE_QUERY_STATUS);
    if (schs > 0) then // if successful...
    begin
      if (ControlService(schs, SERVICE_CONTROL_STOP, ss)) then
      begin
        if (QueryServiceStatus(schs, ss)) then
        begin
          while (SERVICE_STOPPED <> ss.dwCurrentState) do
          begin
            dwChkP := ss.dwCheckPoint;
            SleepEx(ss.dwWaitHint, False);

            if (not QueryServiceStatus(schs, ss)) then
              break;

            if (ss.dwCheckPoint < dwChkP) then
              break;
          end;
        end;
      end;
      CloseServiceHandle(schs);
    end;
    CloseServiceHandle(schm);
  end;
  Result := SERVICE_STOPPED = ss.dwCurrentState;
end;

end.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester