Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Matar un Servicio

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Matar un Servicio Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Matar un servicio Responder citando

Gracias Leo, como siempre funciona perfectamente.

Imaginaba que seria tema de privilegios, aunque no estaba seguro, y no sabia como hacerlo.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mostrar mensajes de anteriores:   
Cambiar a:  
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


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.