 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
sisabb Lt JG

Registrado: 07 Ago 2003Mensajes: 71
|
Publicado: Lun 14 Jun, 2010 1:38 pm Asunto: Matar un Servicio |
|
|
Tengo creado un servicio y que en un momento determinado deja de atender a traves de un ServerSocket.
Si efectuo un Net Stop del servicio, a veces funciona correctamente pero otras se queda intentando parar este pero no lo consigue, o no se si no tengo la suficiente paciencia pues pasa un excesivo tiempo y termino por ir a los procesos en el Administrador de Tareas de Windows y mato el proceso.
Al ver que esto funciona, queria optar por fabricar un programa que primero matase el proceso para a continuación efectuar el Net Start del servicio.
He efectuado todo tipo de codificación para matar procesos que he encotrado, pero no consigo matar el proceso
He aquí dos de las funciones que utilizo:
int KILL_PROC_BY_NAME(const char *szToTerminate)
// Created: 6/23/2000 (RK)
// Last modified: 3/10/2002 (RK)
// Please report any problems or bugs to kochhar@physiology.wisc.edu
// The latest version of this routine can be found at:
// http://www.neurophys.wisc.edu/ravi/software/killproc/
// Terminate the process "szToTerminate" if it is currently running
// This works for Win/95/98/ME and also Win/NT/2000/XP
// The process name is case-insensitive, i.e. "notepad.exe" and "NOTEPAD.EXE"
// will both work (for szToTerminate)
// Return codes are as follows:
// 0 = Process was successfully terminated
// 603 = Process was not currently running
// 604 = No permission to terminate process
// 605 = Unable to load PSAPI.DLL
// 602 = Unable to terminate process for some other reason
// 606 = Unable to identify system type
// 607 = Unsupported OS
// 632 = Invalid process name
// 700 = Unable to get procedure address from PSAPI.DLL
// 701 = Unable to get process list, EnumProcesses failed
// 702 = Unable to load KERNEL32.DLL
// 703 = Unable to get procedure address from KERNEL32.DLL
// 704 = CreateToolhelp32Snapshot failed
// Change history:
// modified 3/8/2002 - Borland-C compatible if BORLANDC is defined as
// suggested by Bob Christensen
// modified 3/10/2002 - Removed memory leaks as suggested by
// Jonathan Richard-Brochu (handles to Proc and Snapshot
// were not getting closed properly in some cases)
{
BOOL bResult,bResultm;
DWORD aiPID[1000],iCb=1000,iNumProc,iV2000=0;
DWORD iCbneeded,i,iFound=0;
char szName[MAX_PATH],szToTermUpper[MAX_PATH];
HANDLE hProc,hSnapShot,hSnapShotm;
OSVERSIONINFO osvi;
HINSTANCE hInstLib;
int iLen,iLenP,indx;
HMODULE hMod;
PROCESSENTRY32 procentry;
MODULEENTRY32 modentry;
// Transfer Process name into "szToTermUpper" and
// convert it to upper case
iLenP=strlen(szToTerminate);
if(iLenP<1 || iLenP>MAX_PATH) return 632;
for(indx=0;indx<iLenP;indx++)
szToTermUpper[indx]=toupper(szToTerminate[indx]);
szToTermUpper[iLenP]=0;
// PSAPI Function Pointers.
BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
DWORD, LPDWORD );
DWORD (WINAPI *lpfGetModuleBaseName)( HANDLE, HMODULE,
LPTSTR, DWORD );
// ToolHelp Function Pointers.
HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;
BOOL (WINAPI *lpfModule32First)(HANDLE,LPMODULEENTRY32) ;
BOOL (WINAPI *lpfModule32Next)(HANDLE,LPMODULEENTRY32) ;
// First check what version of Windows we're in
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
bResult=GetVersionEx(&osvi);
if(!bResult) // Unable to identify system version
return 606;
// At Present we only support Win/NT/2000/XP or Win/9x/ME
if((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) &&
(osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS))
return 607;
if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT)
{
// Win/NT or 2000 or XP
// Load library and get the procedures explicitly. We do
// this so that we don't have to worry about modules using
// this code failing to load under Windows 9x, because
// it can't resolve references to the PSAPI.DLL.
hInstLib = LoadLibraryA("PSAPI.DLL");
if(hInstLib == NULL)
return 605;
// Get procedure addresses.
lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))
GetProcAddress( hInstLib, "EnumProcesses" ) ;
lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
DWORD, LPDWORD)) GetProcAddress( hInstLib,
"EnumProcessModules" ) ;
lpfGetModuleBaseName =(DWORD (WINAPI *)(HANDLE, HMODULE,
LPTSTR, DWORD )) GetProcAddress( hInstLib,
"GetModuleBaseNameA" ) ;
if(lpfEnumProcesses == NULL ||
lpfEnumProcessModules == NULL ||
lpfGetModuleBaseName == NULL)
{
FreeLibrary(hInstLib);
return 700;
}
bResult=lpfEnumProcesses(aiPID,iCb,&iCbneeded);
if(!bResult)
{
// Unable to get process list, EnumProcesses failed
FreeLibrary(hInstLib);
return 701;
}
// How many processes are there?
iNumProc=iCbneeded/sizeof(DWORD);
// Get and match the name of each process
for(i=0;i<iNumProc;i++)
{
// Get the (module) name for this process
strcpy(szName,"Unknown");
// First, get a handle to the process
hProc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,
aiPID[i]);
// Now, get the process name
if(hProc)
{
if(lpfEnumProcessModules(hProc,&hMod,sizeof(hMod),&iCbneeded) )
{
iLen=lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH);
}
}
CloseHandle(hProc);
// We will match regardless of lower or upper case
//#ifdef BORLANDC
if(strcmp(strupr(szName),szToTermUpper)==0)
//#else
// if(strcmp(_strupr(szName),szToTermUpper)==0)
//#endif
{
// Process found, now terminate it
iFound=1;
// First open for termination
hProc=OpenProcess(PROCESS_TERMINATE,FALSE,aiPID[i]);
if(hProc)
{
if(TerminateProcess(hProc,0))
{
// process terminated
CloseHandle(hProc);
FreeLibrary(hInstLib);
return 0;
}
else
{
// Unable to terminate process
CloseHandle(hProc);
FreeLibrary(hInstLib);
return 602;
}
}
else
{
// Unable to open process for termination
FreeLibrary(hInstLib);
return 604;
}
}
}
}
if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
{
// Win/95 or 98 or ME
hInstLib = LoadLibraryA("Kernel32.DLL");
if( hInstLib == NULL )
return 702;
// Get procedure addresses.
// We are linking to these functions of Kernel32
// explicitly, because otherwise a module using
// this code would fail to load under Windows NT,
// which does not have the Toolhelp32
// functions in the Kernel 32.
lpfCreateToolhelp32Snapshot=
(HANDLE(WINAPI *)(DWORD,DWORD))
GetProcAddress( hInstLib,
"CreateToolhelp32Snapshot" ) ;
lpfProcess32First=
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
GetProcAddress( hInstLib, "Process32First" ) ;
lpfProcess32Next=
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
GetProcAddress( hInstLib, "Process32Next" ) ;
lpfModule32First=
(BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))
GetProcAddress( hInstLib, "Module32First" ) ;
lpfModule32Next=
(BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))
GetProcAddress( hInstLib, "Module32Next" ) ;
if( lpfProcess32Next == NULL ||
lpfProcess32First == NULL ||
lpfModule32Next == NULL ||
lpfModule32First == NULL ||
lpfCreateToolhelp32Snapshot == NULL )
{
FreeLibrary(hInstLib);
return 703;
}
// The Process32.. and Module32.. routines return names in all uppercase
// Get a handle to a Toolhelp snapshot of all the systems processes.
hSnapShot = lpfCreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS, 0 ) ;
if( hSnapShot == INVALID_HANDLE_VALUE )
{
FreeLibrary(hInstLib);
return 704;
}
// Get the first process' information.
procentry.dwSize = sizeof(PROCESSENTRY32);
bResult=lpfProcess32First(hSnapShot,&procentry);
// While there are processes, keep looping and checking.
while(bResult)
{
// Get a handle to a Toolhelp snapshot of this process.
hSnapShotm = lpfCreateToolhelp32Snapshot(
TH32CS_SNAPMODULE, procentry.th32ProcessID) ;
if( hSnapShotm == INVALID_HANDLE_VALUE )
{
CloseHandle(hSnapShot);
FreeLibrary(hInstLib);
return 704;
}
// Get the module list for this process
modentry.dwSize=sizeof(MODULEENTRY32);
bResultm=lpfModule32First(hSnapShotm,&modentry);
// While there are modules, keep looping and checking
while(bResultm)
{
if(strcmp(modentry.szModule,szToTermUpper)==0)
{
// Process found, now terminate it
iFound=1;
// First open for termination
hProc=OpenProcess(PROCESS_TERMINATE,FALSE,procentry.th32ProcessID);
if(hProc)
{
if(TerminateProcess(hProc,0))
{
// process terminated
CloseHandle(hSnapShotm);
CloseHandle(hSnapShot);
CloseHandle(hProc);
FreeLibrary(hInstLib);
return 0;
}
else
{
// Unable to terminate process
CloseHandle(hSnapShotm);
CloseHandle(hSnapShot);
CloseHandle(hProc);
FreeLibrary(hInstLib);
return 602;
}
}
else
{
// Unable to open process for termination
CloseHandle(hSnapShotm);
CloseHandle(hSnapShot);
FreeLibrary(hInstLib);
return 604;
}
}
else
{ // Look for next modules for this process
modentry.dwSize=sizeof(MODULEENTRY32);
bResultm=lpfModule32Next(hSnapShotm,&modentry);
}
}
//Keep looking
CloseHandle(hSnapShotm);
procentry.dwSize = sizeof(PROCESSENTRY32);
bResult = lpfProcess32Next(hSnapShot,&procentry);
}
CloseHandle(hSnapShot);
}
if(iFound==0)
{
FreeLibrary(hInstLib);
return 603;
}
FreeLibrary(hInstLib);
return 0;
}
//----------------------------------------------------------------------------------------------
int __fastcall TForm1::Termina_Proceso(String FileName)
{
// Hay que añadir: #include <tlhelp32>
bool ContinueLoop;
HANDLE FSnapshotHandle;
PROCESSENTRY32 FProcessEntry32;
FSnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize = sizeof(FProcessEntry32);
ContinueLoop = Process32First(FSnapshotHandle, &FProcessEntry32);
while(ContinueLoop)
{
if((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) == UpperCase(FileName))|| (UpperCase(FProcessEntry32.szExeFile) == UpperCase(FileName)))
{
TerminateProcess(OpenProcess(PROCESS_TERMINATE, 0, FProcessEntry32.th32ProcessID), 0);
}
ContinueLoop = Process32Next(FSnapshotHandle, &FProcessEntry32);
}
CloseHandle(FSnapshotHandle);
return 0;
}
Pero no consigo matar dicho Servicio, que por contra si puedo desde el administrador de Tareas.
¿Alguien sabe si es que al ser un servicio, tiene que se de algún otro modo diferente?
Saludos. |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Lun 14 Jun, 2010 9:15 pm Asunto: |
|
|
Prueba con lo siguiente: (también dependiendo del servicio necesitaras que tu programa se ejecute como administrador para que funcione)
| Código: | /*---------------------------------------------------------------------------
KillService :: Esta función permite "matar" un servicio utilizando su nombre
de ejecución como identificación, devuelve 1 en caso de exito
ó 0 en caso contrario. Por ejemplo, tenemos el "sqlservr.exe"
ejecutandose, usariamos esta función del siguiente modo
para cerrarlo: KillService("sqlservr.exe");
---------------------------------------------------------------------------*/
int KillService(String fileName)
{
////---> Hay que añadir: #include <tlhelp32.h>
// Habilitamos los privilegios necesarios..
HANDLE token;
TOKEN_PRIVILEGES tkp = {1};
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
{
if (LookupPrivilegeValue(0, SE_DEBUG_NAME, &tkp.Privileges[0].Luid))
{
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(token, FALSE, &tkp, sizeof(tkp), 0, 0);
//bool privilegesOk = (GetLastError() == ERROR_SUCCESS);
}
CloseHandle(token);
}
// Buscamos y matamos el servicio..
PROCESSENTRY32 processEntry32 = { sizeof(processEntry32) };
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
bool ContinueLoop = Process32First(snapshot, &processEntry32);
while (ContinueLoop)
{
if (!CompareText(ExtractFileName(processEntry32.szExeFile), fileName))
{
return TerminateProcess(OpenProcess(PROCESS_TERMINATE, 0,
processEntry32.th32ProcessID), 0);
}
ContinueLoop = Process32Next(snapshot, &processEntry32);
}
CloseHandle(snapshot);
return 0;
} |
Ultima edición por _Leo el Mar 15 Jun, 2010 3:59 pm, editado 1 vez |
|
| Volver arriba |
|
 |
sisabb Lt JG

Registrado: 07 Ago 2003Mensajes: 71
|
Publicado: Mar 15 Jun, 2010 7:09 am Asunto: Matar un servicio |
|
|
Gracias Leo, como siempre funciona perfectamente.
Imaginaba que seria tema de privilegios, aunque no estaba seguro, y no sabia como hacerlo. |
|
| Volver arriba |
|
 |
|
|
No puedes publicar temas nuevos en este foro No puedes responder a temas en este foro No puedes editar tus mensajes en este foro No puedes borrar tus mensajes en este foro No puedes votar en las encuestas de este foro
|
© 2002–2026 Club Builder · Funciona con phpBB.
|