PDA

Ver la Versión Completa : Cerrar otra aplicación con ventana invisible


Lord Delfos
03-02-2008, 23:25:28
Hola de nuevo.

A ver si alguien sabe esto.

Tengo dos programas. Uno corre normalmente y el otro en la SysTray.

La cosa es que cuando uno arranca el programa normal, éste cierra el que está corriendo en la SysTray.

Originalmente le enviaba un mensaje WM_CLOSE con SendMessage, pero resulta que si la ventana no está visible... bueno, explota.

He estado buscando en Internet pero, la verdad, no he encontrado algo que funcione realmente bien y no sean tres unidades de 400 líneas con partes en assembler y un librito para rezar mientras se compila... :(

¿Alguna idea? ¿Alguna punta por donde comenzar?

Gracias miles.

dec
03-02-2008, 23:49:24
Hola,

Tal vez "matar el proceso" de la aplicación, pero, ten en cuenta que matar un proceso implica que la aplicación en cuestión no se cerrará en condiciones, es decir, "no se enterará" de que ha sido "asesinada", si no me equivoco...


uses
TlHelp32;

function MatarProcesos(nombre: string): boolean;
var
moduleEntry: TModuleEntry32;
processEntry: TProcessEntry32;
hSnapshot, hProcess: cardinal;
begin
result := false;
moduleEntry.dwSize := SizeOf(TModuleEntry32);
processEntry.dwSize := SizeOf(TProcessEntry32);
hSnapshot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS,0);
if Process32First(hSnapshot,processEntry) then
begin
repeat
if (lstrcmpi(PChar(nombre),@processEntry.szExeFile) = 0) then
begin
hProcess := OpenProcess(PROCESS_TERMINATE,
false,processEntry.th32ProcessID);
result := TerminateProcess(hProcess,0);
CloseHandle(hProcess);
end;
until not Process32Next(hSnapshot,processEntry);
end;
CloseHandle(hSnapshot);
end;


Y ten en cuenta además que lo anterior mataría todos los procesos con el mismo nombre, es decir, que si algún ejecutable se llama como el de la aplicación que quieres "matar", también este será "asesinado" sin piedad. En definitiva, que no sé si te servirá de algo o qué.

Al González
04-02-2008, 07:15:39
Pues yo creo que con esta rutina de Dec no tendrás que rezar nadita Lord. No la he probado pero tiene muy buena pinta. Excelente código David.

Hay por ahí un Begin y un End y un par de paréntesis que son innecesarios, y quizá convendría asegurar a los CloseHandle con un Try...Finally. Serían mis únicas observaciones.

Un abrazo rutinario.

Al González.

dec
04-02-2008, 15:06:59
Hola,

Es muy posible que sea como dices Al. De hecho ese código no lo escribí yo (a tanto no he llegado) sino que lo adaptaría de alguno que encontré por ahí, pero, que, por el motivo que sea, no puedo citar, puesto que en el original (cierto proyecto mío) tampoco cito a su autor... y eso no puede querer decir (salvo excepciones) que no recuerdo al autor, ¡o que yo mismo lo escribí! Quién sabe... no, esto último no será. :)

Lord Delfos
05-02-2008, 01:10:08
¡Gracias Dec!

Voy a probar este codiguín a ver qué sale. Lo del nombre no es tan problemático, porque como el programa en sí no se ve, puedo inventar nombes medios complicados...

Gracias de nuevo y saludongos.

vejerf
22-04-2008, 17:02:04
Buenas,
Buscando algún método para matar a una aplicación he dado con este hilo. Mi intención es "matar" al Google Earth cuando cierro mi aplicación ya que mi aplicación hace uso del GE. Al usar el método sugerido por Dec el GE no termina de cerrarse. Ocurre que finaliza la aplicación, pero da un error quedando como en segundo plano. El error dice que esa funcionalidad sólo está prevista para los suscriptores de Google Earth Plus. No hay algún método que sea aún más agresivo y que lo elimine como hace el administrador de tareas???

Gracias...

alquimista
23-04-2008, 00:40:07
En mi mata programas utilizo la siguiente rutina, sacada de internet y modificada algo:
POr supuesto no es perfecta pero mata los programas

function KillTask(ExeFileName: string): Integer;

var

foto: Cardinal;
datos: tagPROCESSENTRY32;
p: array[0..512] of char;

function QuitarSaltosLinea(Strs: String; CharReplace:String=#0):String;
var
Str:string;
begin
Str := AnsiReplaceStr(Strs, #$D, CharReplace);
Result := AnsiReplaceStr(Str, #$A, CharReplace);
end;

begin
Result:=0;
ExeFileName:=QuitarSaltosLinea(ExeFileName);
strpcopy(p,ExeFileName);

datos.dwSize := sizeOF(tagPROCESSENTRY32);
foto := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
while Process32Next(foto, datos) do
begin
if (UpperCase(datos.szExeFile) = UpperCase(p)) then
begin
Result := Integer(TerminateProcess(
OpenProcess(
PROCESS_TERMINATE,
BOOL(1), datos.th32ProcessID), 0));
end;

end;
CloseHandle(foto);
end;

para el WinXp o NT uses tlhelp32;

Si alguno de los programas se resiste se puede usar esto para ayudar:

function EnablePrivilege(PrivilegeName: PChar; Enable: Boolean): Boolean;
var
hToken: THandle;
Tp: TOKEN_PRIVILEGES;
Luid: TLargeInteger;
begin
Result:= FALSE;
if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or
TOKEN_QUERY or TOKEN_READ or TOKEN_WRITE or TOKEN_ALL_ACCESS, hToken) then
if LookupPrivilegeValue(nil,PrivilegeName,Luid) then
begin
Tp.PrivilegeCount:= 1;
Tp.Privileges[0].Luid:= Luid;
if Enable then
Tp.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED
else
Tp.Privileges[0].Attributes:= 0;
Result:= AdjustTokenPrivileges(hToken,FALSE,Tp,0,nil,PDWORD(nil)^);
CloseHandle(hToken);
end;
end;


EnablePrivilege('SeDebugPrivilege', TRUE);

No se exactamente que es lo que hace pero creo que me sirvio


Ya me cuentas.
:D:D

vejerf
23-04-2008, 18:33:14
:confused::confused::confused:
Gracias por tu ayuda... pero al final no me funcionó...:(:(:(
Me da el mismo problema que con la función de dec... no termina de cerrarse... Aghhh es que no hay forma en esta vida de acabar de una vez por todas con el Google Earth jejeje

Gracias