P
Also denn, hier der Code.
Einfach ein neues Projekt erstellen, zwei TListBox (LBServices, LBStatus), ein TStaticText (STNumServ) und ein TButton (BListServices) drauf ziehen und den folgenden Code einbauen.
void __fastcall TForm1::BListServicesClick(TObject *Sender)
{
ListServices();
}
//---------------------------------------------------------------------------
AnsiString TForm1::LastErrorMsg(DWORD LastError)
{
AnsiString ErrorMessage;
LPVOID MsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
LastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &MsgBuf,
0,
NULL
);
ErrorMessage=(char*)MsgBuf;
LocalFree(MsgBuf);
return Trim(ErrorMessage);
}
//---------------------------------------------------------------------------
void TForm1::ListServices(void)
{
ENUM_SERVICE_STATUS *Services;
DWORD LastError;
DWORD ServBufSize;
DWORD BytesNeeded;
DWORD NumServ;
DWORD ResumeHandle=0;
SC_HANDLE SCM_DB_Handle;
LBStatus->Clear();
LBServices->Clear();
// Service Control Manager öffnen
if((SCM_DB_Handle=OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))==NULL)
{ LBStatus->Items->Add(LastErrorMsg(GetLastError()));
return;
}
ServBufSize=10240;
Services=(ENUM_SERVICE_STATUS*)new char[ServBufSize];
//while(EnumServicesStatus(SCM_DB_Handle, SERVICE_WIN32 | SERVICE_DRIVER, SERVICE_ACTIVE | SERVICE_INACTIVE, Services, ServBufSize, &BytesNeeded, &NumServ, &ResumeHandle)==false)
while(EnumServicesStatus(SCM_DB_Handle, SERVICE_WIN32, SERVICE_ACTIVE | SERVICE_INACTIVE, Services, ServBufSize, &BytesNeeded, &NumServ, &ResumeHandle)==false)
{ if((LastError=GetLastError())!=ERROR_MORE_DATA)
{ LBStatus->Items->Add(LastErrorMsg(LastError));
break;
}
ShowServices(Services, NumServ);
}
ShowServices(Services, NumServ);
CloseServiceHandle(SCM_DB_Handle);
delete Services;
}
//---------------------------------------------------------------------------
void TForm1::ShowServices(ENUM_SERVICE_STATUS *Services, DWORD NumServ)
{
unsigned int x;
AnsiString ServiceType;
AnsiString ServiceState;
ENUM_SERVICE_STATUS *Service;
if(NumServ==0) return;
for(x=0; x<NumServ; x++)
{ Service=Services+x;
// Service Typ dekodieren
switch(Service->ServiceStatus.dwServiceType & ~SERVICE_INTERACTIVE_PROCESS)
{ case SERVICE_WIN32_OWN_PROCESS : ServiceType="WIN32 service, own process";
break;
case SERVICE_WIN32_SHARE_PROCESS: ServiceType="WIN32 service, shared process";
break;
case SERVICE_KERNEL_DRIVER : ServiceType="NT device driver";
break;
case SERVICE_FILE_SYSTEM_DRIVER : ServiceType="NT file system driver";
break;
default : ServiceType.sprintf("typ %04X", Service->ServiceStatus.dwServiceType);
}
if(Service->ServiceStatus.dwServiceType & SERVICE_INTERACTIVE_PROCESS!=0)
ServiceType="interact with desktop "+ServiceType;
// Service Status dekodieren
switch(Service->ServiceStatus.dwCurrentState)
{ case SERVICE_STOPPED : ServiceState="stopped";
break;
case SERVICE_START_PENDING : ServiceState="start pending";
break;
case SERVICE_STOP_PENDING : ServiceState="stop pending";
break;
case SERVICE_RUNNING : ServiceState="running";
break;
case SERVICE_CONTINUE_PENDING: ServiceState="continue pending";
break;
case SERVICE_PAUSE_PENDING : ServiceState="pause pending";
break;
case SERVICE_PAUSED : ServiceState="paused";
break;
default : ServiceState.sprintf("unknown %04X", Service->ServiceStatus.dwCurrentState);
}
LBServices->Items->Add("["+(AnsiString)Service->lpServiceName+"] "+(AnsiString)Service->lpDisplayName+" ---> "+ServiceType+" "+ServiceState);
}
STNumServ->Caption=LBServices->Items->Count;
}
Auf diese Art und Weise probiere ich meistens API Funktionen aus. So sieht man wenigstens erst mal was und kann darauf aufbauen. Das Teil hab ich übrigens gerade nochmal mit BCB6 getestet, funktioniert einwandfrei
Kleiner Tipp, ins endgültige Programm nicht unbedingt einfach alles blindlings so übernehmen wie ich es gemacht habe. Die Funktionen hab ich wie gesagt nur mal so zum Testen gestrickt, damit überhaupt mal was zu sehen ist. Es ist nichts Endgültiges und Fertiges
[ Dieser Beitrag wurde am 06.04.2003 um 11:48 Uhr von Peter editiert. ]