Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour,
Dans le cadre de mon travail, je dois à partir d'une appli web ouvrir une appli développée en PB.
J'ai réussi à le faire en développant un plugin pour le navigateur cible qui embarque un dll appelée depuis du javascript.
Cependant, si une instance est déjà ouverte, une seconde s'ouvre, et ainsi de suite, ce qui devient gênant.
Ce que je souhaiterai faire, c'est que la nouvelle instance qui s'ouvre envoie un message à l'instance ouverte afin qu'elle se ferme.
Pour savoir si une instance est ouverte, je pense lire un fichier dans lequel sera renseigné le PID de l'instance ouverte ou -1 s'il n'y en a pas. S'il n'y en a pas (ie -1) alors j'écris le PID de l'instance en cours d'ouverture et je continue l'ouverture. Si j'ai un numéro de processus différent de -1 alors j'envoie un message à ce processus, j'écris mon PID et je continue l'ouverture de l'appli.
Est-ce que selon vous cela est facilement réalisable et si oui comment puis-je procéder (fonction d'envoie de message, mise en place d'un listener pour la réception d'un messsage, récupération du PID...) ?
Merci.
--
newbee
Dernière modification par newbee (20-06-2012 08:48:14)
Hors ligne
Bonjour,
Si tu parles bien d'une application PB en client lourd dont tu voudrais contrôler le nombre d'instances,
alors tu pourrais utiliser l'API windows pour rechercher le processus par son nom d'image (.exe) et forcer un kill dessus (TerminateProcess)
comme çà pas besoin de fichier temporaire, par contre, c'est assez violent comme fermeture...
Hors ligne
Il s'agit bien d'une application PB de type client lourd. En revanche, je trouve effectivement que ce système de fermeture est un peu brutal.
Je viens de fouiller un peu et peut-être que la meilleure solution serait de mettre un thread en écoute sur un port dès l'ouverture de la première instance, de renseigner le numéro de port d'écoute dans un fichier et dès qu'une nouvelle instance se lance elle cherche à écrire dans une socket à destination du thread en écoute et hop c'est bon.
Qu'en pensez-vous? cela est théorique et je ne sais absolument pas comment utiliser des sockets et si c'est possible. Des suggestions ou des exemples de code ?
Merci
Hors ligne
newbee a écrit:
Qu'en pensez-vous?
Que ça ressemble à la description d'une usine à gaz ?
Ça ne serait pas plus simple de rechercher si l'application est démarrée (en recherchant par le nom de la fenêtre ou par sa classe avec FindWindow) et si on la trouve de la remettre au premier plan (avec ShowWindow) ?
Hors ligne
En fait c'est juste de la communication TCP/IP mais si cela n'est pas possible, regardons ce que tu me propose.
Admettons que la recherche via FindWindow soit fructueuse, est-il possible de lui transmettre un message pour la fermer ? je ne cherche pas à la mettre en premier plan, car la nouvelle instance n'a pas forcément les mêmes paramètres de lancement.
Merci.
Dernière modification par newbee (19-06-2012 12:42:05)
Hors ligne
xlat a écrit:
tu pourrais utiliser l'API windows pour rechercher le processus par son nom d'image (.exe) et forcer un kill dessus (TerminateProcess)
Est-ce qu'à tout hazard tu pourrais m'expliquer comment appeler des fonctions de l'API Windows ou me mettre un extrait de code?
Merci
Hors ligne
Alors, quand on recherche une fonctionnalité qui n'est pas proposée par PB et qu'on a repéré sur le site MSDN une fonction fournie par Windows (ou un ensemble de fonctions) qui permet d'avoir cette fonctionnalité au niveau système, il faut déclarer le prototype de cette fonction à PB au moyen des Local external functions (pour un userobject ou une fonction globale) ou des global external functions (au niveau de l'appli entière).
Dans PB, une fois qu'on a ouvert un objet en édition, il faut aller dans l'onglet "declare instance variables" et changer dans la combo du haut "instance variables" par "global external functions" ou "local external functions" suivant l'objet et la visibilité qu'on souhaite avoir.
Pour cela il faut regarder le prototype C de la fonction donné sur MSDN et le convertir en syntaxe PB. Exemple avec FindWindow() : on a
HWND WINAPI FindWindow(__in_opt LPCTSTR lpClassName, __in_opt LPCTSTR lpWindowName);
- Le HWND nous indique que c'est une fonction qui retourne un DWORD (= en PB un unsigned long)
- WINAPI ne sert que si on utilise la fonction avec Visual C++, ici on peut l'ignorer
- FindWindow c'est le nom de la fonction
- LPCTSTR indique que lpClassName est un pointeur vers une string, __in_opt nous indique que c'est un paramètre d'entrée - c'est une notation supplémentaire récente et parfois on ne l'a pas dans les protoypes
- idem pour lpWindowName
Il faut également repérer dans la page de la doc
- quelle est la dll qui fournit cette fonction (ici User32.dll)
- pour les fonctions manipulant les chaines, il faut voir si la fonction prend du texte ansi, unicode, ou les 2. Ici on voit que sous le nom FindWindow on a 2 versions FindWindowW (Unicode) et FindWindowA (ANSI)
- si la fonction ne retourne rien (void) pour PB ce sera une Subroutine et non une Function
Le type de chaine est important parce que PB en interne gère des chaines "unicode" (pour être exact, encodées en utf-16-le) soit avec 2 octets par caractère et soit on peut appeler la fonction directement, soit PB doit convertir en ansi (= encodage windows cp-1252 - si le windows est en réglages occidentaux - avec 1 octet par caractère)
Ici on va parler des PB post-10.x qui sont unicode en interne (alors que PB 9 et avant étaient en ansi) Soit on déclare la fonction directment sous son nom final et ça donne
Function ULONG FindWindowW(string lpClassName, string lpWindowName) Library "User32.dll"
soit on veut l'utiliser dans PB avec son nom plus simple FindWindow et on utilise un alias
Function ULONG FindWindow(string lpClassName, string lpWindowName) Library "User32.dll" alias for "FindWindowW"
Enfin pour info, si on voulait utiliser la version ansi de la fonction (ou si on veut accéder à une fonction d'une dll qui ne connaît que les chaines ansi) on aurait dit (attention au A de FindWindowA et au ";ansi" qui indique qu'il y a conversion de texte)
Function ULONG FindWindow(string lpClassName, string lpWindowName) Library "User32.dll" alias for "FindWindowA;ansi"
PS: dans les cas où les fonctions utilisent des structures à la place de types simples (string, long, ...) il faut aussi déclarer des structures PB compatibles avec les structs C.
PS2: et dans les cas où la fonction doit écrire dans un buffer, il faut allouer le buffer dans PB. Habituellement on déclare une string et on la remplit avec la bonne taille avec la fonction space() avant d'appeler la dll.
Dernière modification par seki (20-06-2012 08:42:15)
Hors ligne
Parfait. Merci Seki, une explication claire et nette que je vais utiliser.
Merci pour toutes ces informations et votre aide.
Hors ligne
Histoire de montrer un peu plus de détails concrets, voici le code d'un userobject unvo_process_mgt que j'ai repris de Roland Smith et dans lequel j'avais ajouté la recherche de process.
Il suffit de créer un nouvel userobject unvo_process_mgt, de le fermer puis de rouvrir directement le code source pour y coller ce qui suit. Il y a
- la déclaration de fonctions permettant de démarrer, rechercher, arrêter des process windows
- la déclaration des structs nécessaires directement dans l'objet
forward global type unvo_process_mgt from nonvisualobject end type type processentry from structure within unvo_process_mgt end type type moduleentry from structure within unvo_process_mgt end type type process_memory_counters from structure within unvo_process_mgt end type type startupinfo from structure within unvo_process_mgt end type type shellexecuteinfo from structure within unvo_process_mgt end type type process_information from structure within unvo_process_mgt end type end forward type processentry from structure unsignedlong lpidprocess[500] end type type moduleentry from structure unsignedlong lpidmodule[100] end type type process_memory_counters from structure unsignedlong cb unsignedlong pagefaultcount unsignedlong peakworkingsetsize unsignedlong workingsetsize unsignedlong quotapeakpagedpoolusage unsignedlong quotapagedpoolusage unsignedlong QuotaPeakNonPagedPoolUsage unsignedlong QuotaNonPagedPoolUsage unsignedlong PagefileUsage unsignedlong PeakPagefileUsage end type type startupinfo from structure long cb string lpreserved string lpdesktop string lptitle long dwx long dwy long dwxsize long dwysize long dwxcountchars long dwycountchars long dwfillattribute long dwflags long wshowwindow long cbreserved2 long lpreserved2 ulong hstdinput ulong hstdoutput ulong hstderror end type type shellexecuteinfo from structure long cbsize long fmask long hwnd string lpverb string lpfile string lpparameters string lpdirectory long nshow long hinstapp long lpidlist string lpclass ulong hkeyclass ulong hicon ulong hmonitor ulong hprocess end type global type process_information from structure ulong hprocess ulong hthread long dwprocessid long dwthreadid end type global type unvo_process_mgt from nonvisualobject end type global unvo_process_mgt unvo_process_mgt type prototypes Function boolean CloseHandle (ref ulong hObject) Library "KERNEL32.DLL" Function Boolean EnumProcesses(REF processEntry Process, long cb, REF long cbNeeded ) Library "PSAPI.DLL" Function long OpenProcess( long dwDesiredAccess, boolean bInheritHandle,ulong dwProcessId) LIBRARY "KERNEL32.DLL" Function boolean EnumProcessModules( ulong hProcess, REF ModuleEntry Module, long cb, REF long lpcbNeeded ) LIBRARY "PSAPI.DLL" Function long GetModuleBaseNameW(ulong hProcess, ulong hModule, REF string lpBaseName,long nSize) LIBRARY "PSAPI.DLL" Function long GetModuleFileNameExW(ulong hProcess, ulong hModule, REF string lpBaseName,long nSize) LIBRARY "PSAPI.DLL" Function boolean GetProcessMemoryInfo(ulong hProcess, REF PROCESS_MEMORY_COUNTERS ppsmemCounters,long nSize) LIBRARY "PSAPI.DLL" FUNCTION boolean CreateProcess(string AppName, string CommLine, long l1, long l2, boolean binh, long creationflags, long l3, string dir, startupinfo startupinfo, ref process_information pi ) library 'kernel32.dll' alias for "CreateProcessW" FUNCTION long WaitForSingleObject ( ulong ul_Notification, long lmillisecs ) library "kernel32.dll" FUNCTION long GetExitCodeProcess(ulong hProcess,ref ulong lpExitCode) LIBRARY "kernel32.dll" Function boolean ShellExecuteEx (ref SHELLEXECUTEINFO lpExecInfo) Library "shell32.dll" Alias For "ShellExecuteExW" Function long ShellExecute ( long hWnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, long nShowCmd) library 'shell32' alias for 'ShellExecuteW' Function Boolean TerminateProcess (long hProcess,long uExitCode) Library "kernel32.dll" end prototypes type variables private: Boolean ib_terminate long il_millsecs ulong HandleP[] // Handle of the process constant ulong PROCESS_ALL_ACCESS = 2035711 ProcessEntry Process // Window structure (array of 500 ulong)...arbitrary value ! ModuleEntry Module // Window structure (array of 100 long)... idem PROCESS_MEMORY_COUNTERS pmc CONSTANT long INFINITE = -1 CONSTANT long WAIT_ABANDONED = 128 CONSTANT long WAIT_COMPLETE = 0 CONSTANT long WAIT_OBJECT_0 = 0 CONSTANT long WAIT_TIMEOUT = 258 CONSTANT long SW_HIDE = 0 CONSTANT long SW_SHOWNORMAL = 1 CONSTANT long SW_NORMAL = 1 CONSTANT long SW_SHOWMINIMIZED = 2 CONSTANT long SW_SHOWMAXIMIZED = 3 CONSTANT long SW_MAXIMIZE = 3 CONSTANT long SW_SHOWNOACTIVATE = 4 CONSTANT long SW_SHOW = 5 CONSTANT long SW_MINIMIZE = 6 CONSTANT long SW_SHOWMINNOACTIVE = 7 CONSTANT long SW_SHOWNA = 8 CONSTANT long SW_RESTORE = 9 CONSTANT long SW_SHOWDEFAULT = 10 CONSTANT long SW_FORCEMINIMIZE = 11 CONSTANT long SW_MAX = 11 CONSTANT long SW_SCROLLCHILDREN = 17 CONSTANT long SW_INVALIDATE = 18 CONSTANT long SW_ERASE = 20 //SW_MAX = 10 //SW_OTHERUNZOOM = 4 //SW_OTHERZOOM = 2 //SW_PARENTCLOSING = 1 //SW_PARENTOPENING = 3 CONSTANT long STARTF_USESHOWWINDOW = 1 CONSTANT long STARTF_USESIZE = 2 CONSTANT long STARTF_USEPOSITION = 4 CONSTANT long STARTF_USECOUNTCHARS = 8 CONSTANT long STARTF_USEFILLATTRIBUTE = 16 CONSTANT long STARTF_RUNFULLSCREEN = 32 CONSTANT long STARTF_FORCEONFEEDBACK = 64 CONSTANT long STARTF_FORCEOFFFEEDBACK = 128 CONSTANT long STARTF_USESTDHANDLES = 256 CONSTANT long STARTF_USEHOTKEY = 512 CONSTANT long CREATE_DEFAULT_ERROR_MODE = 67108864 CONSTANT long CREATE_FORCEDOS = 8192 CONSTANT long CREATE_NEW_CONSOLE = 16 CONSTANT long CREATE_NEW_PROCESS_GROUP = 512 CONSTANT long CREATE_NO_WINDOW = 134217728 CONSTANT long CREATE_SEPARATE_WOW_VDM = 2048 CONSTANT long CREATE_SHARED_WOW_VDM = 4096 CONSTANT long CREATE_SUSPENDED = 4 CONSTANT long CREATE_UNICODE_ENVIRONMENT = 1024 CONSTANT long DEBUG_PROCESS = 1 CONSTANT long DEBUG_ONLY_THIS_PROCESS = 2 CONSTANT long DETACHED_PROCESS = 8 CONSTANT long HIGH_PRIORITY_CLASS = 128 CONSTANT long IDLE_PRIORITY_CLASS = 64 CONSTANT long NORMAL_PRIORITY_CLASS = 32 CONSTANT long REALTIME_PRIORITY_CLASS = 256 end variables forward prototypes public function boolean of_findprocess (string as_procname) public function unsignedlong of_runandwait (string as_command, boolean ab_visible) public function integer of_shellexec (string as_command) public subroutine of_set_options (boolean ab_terminate, decimal adec_seconds) public function long of_shellrun (string as_filename, string as_shellverb, long al_showwindow) public function long of_shellrun (string as_filename, string as_shellverb, trigevent a_windowstate) public function long of_shellrun (string as_filename, string as_shellverb, windowstate a_windowstate) private function long of_run (string as_exefullpath, long al_showwindow, string as_initialdir) public function long of_run (string as_exefullpath, trigevent a_windowstate, string as_initialdir) public function long of_run (string as_exefullpath, windowstate a_windowstate, string as_initialdir) end prototypes public function boolean of_findprocess (string as_procname); long tailleP=2000 // Size of Process long TailleM=400 // Size of Module long NeededP // returned size of Process long NeededM // returned size of Module long resName // size of returned name of the module long ifx, ii // for looping through processes boolean resultP, resultM // return codes for EnumProcesses and EnumProcessModules string name // Name of the module boolean lb_found = false resultP=EnumProcesses(Process,TailleP,NeededP) if resultP=true then for ifx=1 to integer(NeededP / 4) HandleP[ifx] = OpenProcess(PROCESS_ALL_ACCESS,false,Process.lpIdProcess[iFX]) resultM = EnumProcessModules(HandleP[ifx], Module, TailleM, NeededM) if NeededM >= 4 then if GetProcessMemoryInfo( HandleP[ifx], pmc, 40 ) then /* ls_message = '' ls_message = "PageFaultCount: " + string(pmc.PageFaultCount) + '~r~n' + & + "PeakWorkingSetSize: " + string(pmc.PeakWorkingSetSize ) + '~r~n' & + "WorkingSetSize: " + string(pmc.WorkingSetSize ) + '~r~n' & + "QuotaPeakPagedPoolUsage: " + string(pmc.QuotaPeakPagedPoolUsage ) + '~r~n' & + "QuotaPagedPoolUsage: " + string(pmc.QuotaPagedPoolUsage ) + '~r~n' & + "QuotaPeakNonPagedPoolUsage: " + string(pmc.QuotaPeakNonPagedPoolUsage ) + '~r~n' & + "QuotaNonPagedPoolUsage: " + string(pmc.QuotaNonPagedPoolUsage) + '~r~n' & + "PagefileUsage: " + string(pmc.PagefileUsage ) + '~r~n' & + "PeakPagefileUsage: " + string(pmc.PeakPagefileUsage ) */ Name=space(254) resName=GetModuleBaseNameW(handleP[ifx], Module.lpidmodule[1], name ,254) //MessageBox( "Memory Info for : " + Name,ls_message) ii ++ //mle_1.text += "~r~nMemory Info for : " + Name + ls_un + ls_message + ls_un if name = as_procname then lb_found = true exit //for end if end if end if CloseHandle(HandleP[ifx]) next /* IF ii > 0 THEN mle_1.text = "Retrieved ProcessMemoryInfo for " + string(ii) + " processes~r~n" + mle_1.text END IF else MessageBox ("Memory Info","Fail calling EnumProcesses") */ end if return lb_found end function public function unsignedlong of_runandwait (string as_command, boolean ab_visible); boolean lb_Return long ll_Null, ll_CreationFlags, ll_Return ulong lul_ProcessReturn string ls_CurDir, ls_Null StartupInfo lstr_Start Process_information lstr_PI SetNull(ll_Null) SetNull(ls_Null) SetNull(ls_CurDir) lstr_Start.cb = 72 lstr_Start.dwFlags = STARTF_USESHOWWINDOW IF ab_Visible THEN lstr_Start.wShowWindow = 1 ELSE lstr_Start.wShowWindow = 0 END IF ll_CreationFlags = CREATE_NEW_CONSOLE + NORMAL_PRIORITY_CLASS lb_Return = CreateProcess (ls_Null, as_Command, ll_Null, ll_Null, FALSE,ll_CreationFlags, ll_Null, ls_CurDir, lstr_Start, lstr_PI) ll_Return = WaitForSingleObject (lstr_PI.hProcess, INFINITE) ll_Return = GetExitCodeProcess (lstr_PI.hProcess, lul_ProcessReturn) CloseHandle(lstr_PI.hProcess) CloseHandle(lstr_PI.hThread) RETURN lul_ProcessReturn end function public function integer of_shellexec (string as_command); //ShellExecute( 0, ls_Oper, ls_File, ls_Param, ls_Dir, ll_Show) return 0 end function public subroutine of_set_options (boolean ab_terminate, decimal adec_seconds);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_set_options // // PURPOSE: This function sets a timeout period so that it can stop // waiting after so many seconds. It also sets an option // to terminate the process if it is still running after // the timeout period expires. // // ARGUMENTS: ab_terminate - Terminate if still running // adec_seconds - Timeout period in seconds // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- ib_terminate = ab_terminate il_millsecs = adec_seconds * 1000 end subroutine public function long of_shellrun (string as_filename, string as_shellverb, long al_showwindow);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_ShellRun // // PURPOSE: This function starts the program that is defined to perform // the action on the file. It then waits for it to finish. // If a timeout period has been set, it optionally can terminate // the process. // // ARGUMENTS: as_exefullpath - Path of program to execute // as_shellverb - Shell action verb (blank for default) // ai_showwindow - Show window option // // RETURN: Return code of the program or: // -1 = Create Process failed // 258 = Process terminated after timeout // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- CONSTANT Long SEE_MASK_NOCLOSEPROCESS = 64 SHELLEXECUTEINFO lstr_sei uLong ll_ExitCode // initialize structure values lstr_sei.cbSize = 60 lstr_sei.fMask = SEE_MASK_NOCLOSEPROCESS lstr_sei.hWnd = Handle(this) lstr_sei.lpVerb = as_shellverb lstr_sei.lpFile = as_filename lstr_sei.nShow = al_showwindow If ShellExecuteEx(lstr_sei) Then // wait for the process to complete If il_millsecs > 0 Then // wait until process ends or timeout period expires ll_ExitCode = WaitForSingleObject(lstr_sei.hProcess, il_millsecs) // terminate process if not finished If ib_terminate And ll_ExitCode = WAIT_TIMEOUT Then TerminateProcess(lstr_sei.hProcess, -1) ll_ExitCode = WAIT_TIMEOUT Else // check for exit code GetExitCodeProcess(lstr_sei.hProcess, ll_ExitCode) End If Else // wait until process ends WaitForSingleObject(lstr_sei.hProcess, INFINITE) // check for exit code GetExitCodeProcess(lstr_sei.hProcess, ll_ExitCode) End If // close process and thread handles CloseHandle(lstr_sei.hProcess) Else // return failure ll_ExitCode = -1 End If Return ll_ExitCode end function public function long of_shellrun (string as_filename, string as_shellverb, trigevent a_windowstate);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_ShellRun // // PURPOSE: This function takes the Hide! enumerated value and // passes SW_HIDE to the form of the function that // actually does the processing. // // ARGUMENTS: as_exefullpath - Path of program to execute // as_shellverb - Shell action verb (blank for default) // a_windowstate - Show window option // // RETURN: Return code from processing // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- long ll_rtn CHOOSE CASE a_windowstate CASE Hide! // run the passed file ll_rtn = this.of_ShellRun(as_filename, as_shellverb, SW_HIDE) CASE ELSE // valid trigevent but invalid windowstate SetNull(ll_rtn) END CHOOSE Return ll_rtn end function public function long of_shellrun (string as_filename, string as_shellverb, windowstate a_windowstate);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_ShellRun // // PURPOSE: This function takes the Normal!, Maximized and // Minimized! enumerated values and passes the // corresponding value to the form of the function // that actually does the processing. // // ARGUMENTS: as_exefullpath - Path of program to execute // as_shellverb - Shell action verb (blank for default) // a_windowstate - Show window option // // RETURN: Return code from processing // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- long ll_rtn CHOOSE CASE a_windowstate CASE Normal! ll_rtn = this.of_ShellRun(as_filename, as_shellverb, SW_SHOWNORMAL) CASE Maximized! ll_rtn = this.of_ShellRun(as_filename, as_shellverb, SW_SHOWMAXIMIZED) CASE Minimized! ll_rtn = this.of_ShellRun(as_filename, as_shellverb, SW_SHOWMINIMIZED) END CHOOSE Return ll_rtn end function private function long of_run (string as_exefullpath, long al_showwindow, string as_initialdir);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_Run // // PURPOSE: This function starts the process and waits (or not) for it to // finish. If a timeout period has been set, it // optionally can terminate the process. // // ARGUMENTS: as_exefullpath - Path of program to execute // ai_showwindow - Show window option // as_initialdir - initial directory for run // // RETURN: Return code of the program or: // -1 = Create Process failed // 258 = Process terminated after timeout // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- // 31/01/2008 SeKi If il_millsecs < 0 then don't wait STARTUPINFO lstr_si PROCESS_INFORMATION lstr_pi long ll_null, ll_CreationFlags, ll_msecs ulong ll_ExitCode String ls_null string ls_inidir // initialize arguments SetNull(ll_null) SetNull(ls_null) lstr_si.cb = 72 lstr_si.dwFlags = STARTF_USESHOWWINDOW lstr_si.wShowWindow = al_showwindow ll_CreationFlags = CREATE_NEW_CONSOLE + NORMAL_PRIORITY_CLASS if trim(as_initialdir) <> "" then ls_inidir = as_initialdir else ls_inidir = ls_null end if // create process/thread and execute the passed program If CreateProcess(ls_null, as_exefullpath, ll_null, & ll_null, False, ll_CreationFlags, ll_null, & ls_inidir, lstr_si, lstr_pi) Then // wait for the process to complete If il_millsecs > 0 Then // wait until process ends or timeout period expires ll_ExitCode = WaitForSingleObject(lstr_pi.hProcess, il_millsecs) // terminate process if not finished If ib_terminate And ll_ExitCode = WAIT_TIMEOUT Then TerminateProcess(lstr_pi.hProcess, -1) ll_ExitCode = WAIT_TIMEOUT Else // check for exit code GetExitCodeProcess(lstr_pi.hProcess, ll_ExitCode) End If Elseif il_millsecs = 0 then // wait until process ends WaitForSingleObject(lstr_pi.hProcess, INFINITE) // check for exit code GetExitCodeProcess(lstr_pi.hProcess, ll_ExitCode) else // check for exit code GetExitCodeProcess(lstr_pi.hProcess, ll_ExitCode) End If // close process and thread handles CloseHandle(lstr_pi.hProcess) CloseHandle(lstr_pi.hThread) Else // return failure ll_ExitCode = -1 End If Return ll_ExitCode end function public function long of_run (string as_exefullpath, trigevent a_windowstate, string as_initialdir);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_Run // // PURPOSE: This function takes the Hide! enumerated value and // passes SW_HIDE to the form of the function that // actually does the processing. // // ARGUMENTS: as_exefullpath - Path of program to execute // a_windowstate - Show window option // as_initialdir - initial directory for run // // RETURN: Return code from processing // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- long ll_rtn CHOOSE CASE a_windowstate CASE Hide! // run the passed program ll_rtn = this.of_Run(as_exefullpath, SW_HIDE,as_initialdir) CASE ELSE // valid trigevent but invalid windowstate SetNull(ll_rtn) END CHOOSE Return ll_rtn end function public function long of_run (string as_exefullpath, windowstate a_windowstate, string as_initialdir);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_Run // // PURPOSE: This function takes the Normal!, Maximized and // Minimized! enumerated values and passes the // corresponding value to the form of the function // that actually does the processing. // // ARGUMENTS: as_exepath - Path of program to execute // a_windowstate - Show window option // as_initialdir - initial directory for run // // RETURN: Return code from processing // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- long ll_rtn CHOOSE CASE a_windowstate CASE Normal! ll_rtn = this.of_Run(as_exefullpath, SW_SHOWNORMAL,as_initialdir) CASE Maximized! ll_rtn = this.of_Run(as_exefullpath, SW_SHOWMAXIMIZED,as_initialdir) CASE Minimized! ll_rtn = this.of_Run(as_exefullpath, SW_SHOWMINIMIZED,as_initialdir) END CHOOSE Return ll_rtn end function on unvo_process_mgt.create call super::create TriggerEvent( this, "constructor" ) end on on unvo_process_mgt.destroy TriggerEvent( this, "destructor" ) call super::destroy end on
Hors ligne
seki a écrit:
Histoire de montrer un peu plus de détails concrets, voici le code d'un userobject unvo_process_mgt que j'ai repris de Roland Smith et dans lequel j'avais ajouté la recherche de process.
Il suffit de créer un nouvel userobject unvo_process_mgt, de le fermer puis de rouvrir directement le code source pour y coller ce qui suit. Il y a
- la déclaration de fonctions permettant de démarrer, rechercher, arrêter des process windows
- la déclaration des structs nécessaires directement dans l'objet
J'ai regardé cet objet, mais il n'y a pas la fonction pour arrêter des process windows... (bien que TerminateProcess soit déclaré en external function)
Tu aurais le bout de code correspondant ?
Hors ligne
EDIT: en recompilant l'objet pendant que je jouais avec je suis tombé sur un problème bizarre de surcharge de variable. J'ai modifié le nom de 2 variables d'instance pour pallier au problème.
erasorz a écrit:
J'ai regardé cet objet, mais il n'y a pas la fonction pour arrêter des process windows... (bien que TerminateProcess soit déclaré en external function)
Tu aurais le bout de code correspondant ?
En fait une fois qu'une fonction externe est déclarée dans un objet, ça devient une méthode de l'objet que tu peux appeler directement sans passer par une méthode "proxy".
Edit: je viens de jouer un peu avec ça et il est possible de spécifier dans les déclaration des external Private ou Protected pour limiter l'usage des fonctions externes.
Je n'avais plus regardé ce code depuis longtemps, c'est un bout qui a été mis en place et puis "oublié". En relisant je me dis qu'il mériterait d'être un peu remanié.
TerminateProcess() a besoin d'un handle de process mais si l'objet fournit de quoi énumérer les processus, il n'y avait pas de méthode simple pour rechercher un processus et retourner son handle. J'ai modifié of_FindProcess() pour retourner un handle quand on trouve une correspondance et ajouté of_ProcessExists() comme simple helper par dessus pour reprendre l'ancienne fonctionnalité de of_FindProcess à savoir retourner un booléen si on a trouvé.
Voici un exemple simple de démarrage de programme externe
unvo_process_mgt l_pm l_pm = create unvo_process_mgt //les 2 lignes suivantes équivalentes à run("notepad.exe", normal!) l_pm.of_set_options( false, -1) l_pm.of_run( "notepad.exe", normal!, "" /*possible aussi : "c:\temp"*/) destroy l_pm
Pour stopper on peut faire
unvo_process_mgt l_pm l_pm = create unvo_process_mgt ulong ul_hdl ul_hdl = l_pm.of_findprocess( "notepad.exe") //attention recherche simpliste : ce n'est peut-être pas la bonne instance... ;^) //il faudrait une version de of_run() qui retourne le pid ou handle créé if ul_hdl <> 0 then l_pm.terminateprocess( ul_hdl, 42 /*code de fin retourné au parent du process*/) destroy l_pm
Et une version un peu améliorée de l'objet. Enjoy !
forward global type unvo_process_mgt from nonvisualobject end type type processentry from structure within unvo_process_mgt end type type moduleentry from structure within unvo_process_mgt end type type process_memory_counters from structure within unvo_process_mgt end type type startupinfo from structure within unvo_process_mgt end type type shellexecuteinfo from structure within unvo_process_mgt end type type process_information from structure within unvo_process_mgt end type type stru_test from structure within unvo_process_mgt end type end forward type processentry from structure unsignedlong lpidprocess[500] end type type moduleentry from structure unsignedlong lpidmodule[100] end type type process_memory_counters from structure unsignedlong cb unsignedlong pagefaultcount unsignedlong peakworkingsetsize unsignedlong workingsetsize unsignedlong quotapeakpagedpoolusage unsignedlong quotapagedpoolusage unsignedlong QuotaPeakNonPagedPoolUsage unsignedlong QuotaNonPagedPoolUsage unsignedlong PagefileUsage unsignedlong PeakPagefileUsage end type type startupinfo from structure long cb string lpreserved string lpdesktop string lptitle long dwx long dwy long dwxsize long dwysize long dwxcountchars long dwycountchars long dwfillattribute long dwflags long wshowwindow long cbreserved2 long lpreserved2 ulong hstdinput ulong hstdoutput ulong hstderror end type type shellexecuteinfo from structure long cbsize long fmask long hwnd string lpverb string lpfile string lpparameters string lpdirectory long nshow long hinstapp long lpidlist string lpclass ulong hkeyclass ulong hicon ulong hmonitor ulong hprocess end type global type process_information from structure ulong hprocess ulong hthread long dwprocessid long dwthreadid end type type stru_test from structure string toto end type global type unvo_process_mgt from nonvisualobject end type global unvo_process_mgt unvo_process_mgt type prototypes Function boolean CloseHandle (ref ulong hObject) Library "KERNEL32.DLL" Function Boolean EnumProcesses(REF processEntry Process, long cb, REF long cbNeeded ) Library "PSAPI.DLL" Function long OpenProcess( long dwDesiredAccess, boolean bInheritHandle,ulong dwProcessId) LIBRARY "KERNEL32.DLL" Function boolean EnumProcessModules( ulong hProcess, REF ModuleEntry Module, long cb, REF long lpcbNeeded ) LIBRARY "PSAPI.DLL" Function long GetModuleBaseNameW(ulong hProcess, ulong hModule, REF string lpBaseName,long nSize) LIBRARY "PSAPI.DLL" Function long GetModuleFileNameExW(ulong hProcess, ulong hModule, REF string lpBaseName,long nSize) LIBRARY "PSAPI.DLL" Function boolean GetProcessMemoryInfo(ulong hProcess, REF PROCESS_MEMORY_COUNTERS ppsmemCounters,long nSize) LIBRARY "PSAPI.DLL" FUNCTION boolean CreateProcess(string AppName, string CommLine, long l1, long l2, boolean binh, long creationflags, long l3, string dir, startupinfo startupinfo, ref process_information pi ) library 'kernel32.dll' alias for "CreateProcessW" FUNCTION long WaitForSingleObject ( ulong ul_Notification, long lmillisecs ) library "kernel32.dll" FUNCTION long GetExitCodeProcess(ulong hProcess,ref ulong lpExitCode) LIBRARY "kernel32.dll" Function boolean ShellExecuteEx (ref SHELLEXECUTEINFO lpExecInfo) Library "shell32.dll" Alias For "ShellExecuteExW" Function long ShellExecute ( long hWnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, long nShowCmd) library 'shell32' alias for 'ShellExecuteW' Function Boolean TerminateProcess (long hProcess,long uExitCode) Library "kernel32.dll" end prototypes type variables private: Boolean ib_terminate long il_millsecs ulong HandleP[] // Handle of the process constant ulong PROCESS_ALL_ACCESS = 2035711 ProcessEntry i_Process // Window structure (array of 500 ulong)...arbitrary value ! ModuleEntry i_Module // Window structure (array of 100 long)... idem PROCESS_MEMORY_COUNTERS pmc CONSTANT long INFINITE = -1 CONSTANT long WAIT_ABANDONED = 128 CONSTANT long WAIT_COMPLETE = 0 CONSTANT long WAIT_OBJECT_0 = 0 CONSTANT long WAIT_TIMEOUT = 258 CONSTANT long SW_HIDE = 0 CONSTANT long SW_SHOWNORMAL = 1 CONSTANT long SW_NORMAL = 1 CONSTANT long SW_SHOWMINIMIZED = 2 CONSTANT long SW_SHOWMAXIMIZED = 3 CONSTANT long SW_MAXIMIZE = 3 CONSTANT long SW_SHOWNOACTIVATE = 4 CONSTANT long SW_SHOW = 5 CONSTANT long SW_MINIMIZE = 6 CONSTANT long SW_SHOWMINNOACTIVE = 7 CONSTANT long SW_SHOWNA = 8 CONSTANT long SW_RESTORE = 9 CONSTANT long SW_SHOWDEFAULT = 10 CONSTANT long SW_FORCEMINIMIZE = 11 CONSTANT long SW_MAX = 11 CONSTANT long SW_SCROLLCHILDREN = 17 CONSTANT long SW_INVALIDATE = 18 CONSTANT long SW_ERASE = 20 //SW_MAX = 10 //SW_OTHERUNZOOM = 4 //SW_OTHERZOOM = 2 //SW_PARENTCLOSING = 1 //SW_PARENTOPENING = 3 CONSTANT long STARTF_USESHOWWINDOW = 1 CONSTANT long STARTF_USESIZE = 2 CONSTANT long STARTF_USEPOSITION = 4 CONSTANT long STARTF_USECOUNTCHARS = 8 CONSTANT long STARTF_USEFILLATTRIBUTE = 16 CONSTANT long STARTF_RUNFULLSCREEN = 32 CONSTANT long STARTF_FORCEONFEEDBACK = 64 CONSTANT long STARTF_FORCEOFFFEEDBACK = 128 CONSTANT long STARTF_USESTDHANDLES = 256 CONSTANT long STARTF_USEHOTKEY = 512 CONSTANT long CREATE_DEFAULT_ERROR_MODE = 67108864 CONSTANT long CREATE_FORCEDOS = 8192 CONSTANT long CREATE_NEW_CONSOLE = 16 CONSTANT long CREATE_NEW_PROCESS_GROUP = 512 CONSTANT long CREATE_NO_WINDOW = 134217728 CONSTANT long CREATE_SEPARATE_WOW_VDM = 2048 CONSTANT long CREATE_SHARED_WOW_VDM = 4096 CONSTANT long CREATE_SUSPENDED = 4 CONSTANT long CREATE_UNICODE_ENVIRONMENT = 1024 CONSTANT long DEBUG_PROCESS = 1 CONSTANT long DEBUG_ONLY_THIS_PROCESS = 2 CONSTANT long DETACHED_PROCESS = 8 CONSTANT long HIGH_PRIORITY_CLASS = 128 CONSTANT long IDLE_PRIORITY_CLASS = 64 CONSTANT long NORMAL_PRIORITY_CLASS = 32 CONSTANT long REALTIME_PRIORITY_CLASS = 256 end variables forward prototypes public function unsignedlong of_runandwait (string as_command, boolean ab_visible) public function integer of_shellexec (string as_command) public subroutine of_set_options (boolean ab_terminate, decimal adec_seconds) public function long of_shellrun (string as_filename, string as_shellverb, long al_showwindow) public function long of_shellrun (string as_filename, string as_shellverb, trigevent a_windowstate) public function long of_shellrun (string as_filename, string as_shellverb, windowstate a_windowstate) private function long of_run (string as_exefullpath, long al_showwindow, string as_initialdir) public function long of_run (string as_exefullpath, trigevent a_windowstate, string as_initialdir) public function long of_run (string as_exefullpath, windowstate a_windowstate, string as_initialdir) public function boolean of_processexists (string as_procname) public function unsignedlong of_findprocess (string as_procname) end prototypes public function unsignedlong of_runandwait (string as_command, boolean ab_visible); boolean lb_Return long ll_Null, ll_CreationFlags, ll_Return ulong lul_ProcessReturn string ls_CurDir, ls_Null StartupInfo lstr_Start Process_information lstr_PI SetNull(ll_Null) SetNull(ls_Null) SetNull(ls_CurDir) lstr_Start.cb = 72 lstr_Start.dwFlags = STARTF_USESHOWWINDOW IF ab_Visible THEN lstr_Start.wShowWindow = 1 ELSE lstr_Start.wShowWindow = 0 END IF ll_CreationFlags = CREATE_NEW_CONSOLE + NORMAL_PRIORITY_CLASS lb_Return = CreateProcess (ls_Null, as_Command, ll_Null, ll_Null, FALSE,ll_CreationFlags, ll_Null, ls_CurDir, lstr_Start, lstr_PI) ll_Return = WaitForSingleObject (lstr_PI.hProcess, INFINITE) ll_Return = GetExitCodeProcess (lstr_PI.hProcess, lul_ProcessReturn) CloseHandle(lstr_PI.hProcess) CloseHandle(lstr_PI.hThread) RETURN lul_ProcessReturn end function public function integer of_shellexec (string as_command); //ShellExecute( 0, ls_Oper, ls_File, ls_Param, ls_Dir, ll_Show) return 0 end function public subroutine of_set_options (boolean ab_terminate, decimal adec_seconds);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_set_options // // PURPOSE: This function sets a timeout period so that it can stop // waiting after so many seconds. It also sets an option // to terminate the process if it is still running after // the timeout period expires. // // ARGUMENTS: ab_terminate - Terminate if still running // adec_seconds - Timeout period in seconds // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- ib_terminate = ab_terminate il_millsecs = adec_seconds * 1000 end subroutine public function long of_shellrun (string as_filename, string as_shellverb, long al_showwindow);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_ShellRun // // PURPOSE: This function starts the program that is defined to perform // the action on the file. It then waits for it to finish. // If a timeout period has been set, it optionally can terminate // the process. // // ARGUMENTS: as_exefullpath - Path of program to execute // as_shellverb - Shell action verb (blank for default) // ai_showwindow - Show window option // // RETURN: Return code of the program or: // -1 = Create Process failed // 258 = Process terminated after timeout // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- CONSTANT Long SEE_MASK_NOCLOSEPROCESS = 64 SHELLEXECUTEINFO lstr_sei uLong ll_ExitCode // initialize structure values lstr_sei.cbSize = 60 lstr_sei.fMask = SEE_MASK_NOCLOSEPROCESS lstr_sei.hWnd = Handle(this) lstr_sei.lpVerb = as_shellverb lstr_sei.lpFile = as_filename lstr_sei.nShow = al_showwindow If ShellExecuteEx(lstr_sei) Then // wait for the process to complete If il_millsecs > 0 Then // wait until process ends or timeout period expires ll_ExitCode = WaitForSingleObject(lstr_sei.hProcess, il_millsecs) // terminate process if not finished If ib_terminate And ll_ExitCode = WAIT_TIMEOUT Then TerminateProcess(lstr_sei.hProcess, -1) ll_ExitCode = WAIT_TIMEOUT Else // check for exit code GetExitCodeProcess(lstr_sei.hProcess, ll_ExitCode) End If Else // wait until process ends WaitForSingleObject(lstr_sei.hProcess, INFINITE) // check for exit code GetExitCodeProcess(lstr_sei.hProcess, ll_ExitCode) End If // close process and thread handles CloseHandle(lstr_sei.hProcess) Else // return failure ll_ExitCode = -1 End If Return ll_ExitCode end function public function long of_shellrun (string as_filename, string as_shellverb, trigevent a_windowstate);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_ShellRun // // PURPOSE: This function takes the Hide! enumerated value and // passes SW_HIDE to the form of the function that // actually does the processing. // // ARGUMENTS: as_exefullpath - Path of program to execute // as_shellverb - Shell action verb (blank for default) // a_windowstate - Show window option // // RETURN: Return code from processing // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- long ll_rtn CHOOSE CASE a_windowstate CASE Hide! // run the passed file ll_rtn = this.of_ShellRun(as_filename, as_shellverb, SW_HIDE) CASE ELSE // valid trigevent but invalid windowstate SetNull(ll_rtn) END CHOOSE Return ll_rtn end function public function long of_shellrun (string as_filename, string as_shellverb, windowstate a_windowstate);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_ShellRun // // PURPOSE: This function takes the Normal!, Maximized and // Minimized! enumerated values and passes the // corresponding value to the form of the function // that actually does the processing. // // ARGUMENTS: as_exefullpath - Path of program to execute // as_shellverb - Shell action verb (blank for default) // a_windowstate - Show window option // // RETURN: Return code from processing // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- long ll_rtn CHOOSE CASE a_windowstate CASE Normal! ll_rtn = this.of_ShellRun(as_filename, as_shellverb, SW_SHOWNORMAL) CASE Maximized! ll_rtn = this.of_ShellRun(as_filename, as_shellverb, SW_SHOWMAXIMIZED) CASE Minimized! ll_rtn = this.of_ShellRun(as_filename, as_shellverb, SW_SHOWMINIMIZED) END CHOOSE Return ll_rtn end function private function long of_run (string as_exefullpath, long al_showwindow, string as_initialdir);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_Run // // PURPOSE: This function starts the process and waits (or not) for it to // finish. If a timeout period has been set, it // optionally can terminate the process. // // ARGUMENTS: as_exefullpath - Path of program to execute // ai_showwindow - Show window option // as_initialdir - initial directory for run // // RETURN: Return code of the program or: // -1 = Create Process failed // 258 = Process terminated after timeout // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- // 31/01/2008 SeKi If il_millsecs < 0 then don't wait STARTUPINFO lstr_si PROCESS_INFORMATION lstr_pi long ll_null, ll_CreationFlags, ll_msecs ulong ll_ExitCode String ls_null string ls_inidir // initialize arguments SetNull(ll_null) SetNull(ls_null) lstr_si.cb = 72 lstr_si.dwFlags = STARTF_USESHOWWINDOW lstr_si.wShowWindow = al_showwindow ll_CreationFlags = CREATE_NEW_CONSOLE + NORMAL_PRIORITY_CLASS if trim(as_initialdir) <> "" then ls_inidir = as_initialdir else ls_inidir = ls_null end if // create process/thread and execute the passed program If CreateProcess(ls_null, as_exefullpath, ll_null, & ll_null, False, ll_CreationFlags, ll_null, & ls_inidir, lstr_si, lstr_pi) Then // wait for the process to complete If il_millsecs > 0 Then // wait until process ends or timeout period expires ll_ExitCode = WaitForSingleObject(lstr_pi.hProcess, il_millsecs) // terminate process if not finished If ib_terminate And ll_ExitCode = WAIT_TIMEOUT Then TerminateProcess(lstr_pi.hProcess, -1) ll_ExitCode = WAIT_TIMEOUT Else // check for exit code GetExitCodeProcess(lstr_pi.hProcess, ll_ExitCode) End If Elseif il_millsecs = 0 then // wait until process ends WaitForSingleObject(lstr_pi.hProcess, INFINITE) // check for exit code GetExitCodeProcess(lstr_pi.hProcess, ll_ExitCode) else // check for exit code GetExitCodeProcess(lstr_pi.hProcess, ll_ExitCode) End If // close process and thread handles CloseHandle(lstr_pi.hProcess) CloseHandle(lstr_pi.hThread) Else // return failure ll_ExitCode = -1 End If Return ll_ExitCode end function public function long of_run (string as_exefullpath, trigevent a_windowstate, string as_initialdir);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_Run // // PURPOSE: This function takes the Hide! enumerated value and // passes SW_HIDE to the form of the function that // actually does the processing. // // ARGUMENTS: as_exefullpath - Path of program to execute // a_windowstate - Show window option // as_initialdir - initial directory for run // // RETURN: Return code from processing // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- long ll_rtn CHOOSE CASE a_windowstate CASE Hide! // run the passed program ll_rtn = this.of_Run(as_exefullpath, SW_HIDE,as_initialdir) CASE ELSE // valid trigevent but invalid windowstate SetNull(ll_rtn) END CHOOSE Return ll_rtn end function public function long of_run (string as_exefullpath, windowstate a_windowstate, string as_initialdir);// ----------------------------------------------------------------------------- // SCRIPT: n_runandwait.of_Run // // PURPOSE: This function takes the Normal!, Maximized and // Minimized! enumerated values and passes the // corresponding value to the form of the function // that actually does the processing. // // ARGUMENTS: as_exepath - Path of program to execute // a_windowstate - Show window option // as_initialdir - initial directory for run // // RETURN: Return code from processing // // DATE PROG/ID DESCRIPTION OF CHANGE / REASON // ---------- -------- ----------------------------------------------------- // 07/16/2003 RolandS Initial Coding // ----------------------------------------------------------------------------- long ll_rtn CHOOSE CASE a_windowstate CASE Normal! ll_rtn = this.of_Run(as_exefullpath, SW_SHOWNORMAL,as_initialdir) CASE Maximized! ll_rtn = this.of_Run(as_exefullpath, SW_SHOWMAXIMIZED,as_initialdir) CASE Minimized! ll_rtn = this.of_Run(as_exefullpath, SW_SHOWMINIMIZED,as_initialdir) END CHOOSE Return ll_rtn end function public function boolean of_processexists (string as_procname); //Test the existence of a process // ----------------------------------------------------------------------------- // 14/09/2012 SeKi ulong ul_hdl ul_hdl = of_findprocess(as_procname) return ul_hdl <> 0 end function public function unsignedlong of_findprocess (string as_procname);//Returns the handle of a process after searching by its name // ----------------------------------------------------------------------------- // 14/09/2012 SeKi long tailleP=2000 // Size of Process long TailleM=400 // Size of Module long NeededP // returned size of Process long NeededM // returned size of Module long resName // size of returned name of the module long ifx, ii // for looping through processes boolean resultP, resultM // return codes for EnumProcesses and EnumProcessModules string name // Name of the module ulong ul_hfound = 0 //handle of the process resultP=EnumProcesses(i_Process,TailleP,NeededP) if resultP=true then for ifx=1 to integer(NeededP / 4) HandleP[ifx] = OpenProcess(PROCESS_ALL_ACCESS,false,i_Process.lpIdProcess[iFX]) resultM = EnumProcessModules(HandleP[ifx], i_Module, TailleM, NeededM) if NeededM >= 4 then if GetProcessMemoryInfo( HandleP[ifx], pmc, 40 ) then /* ls_message = '' ls_message = "PageFaultCount: " + string(pmc.PageFaultCount) + '~r~n' + & + "PeakWorkingSetSize: " + string(pmc.PeakWorkingSetSize ) + '~r~n' & + "WorkingSetSize: " + string(pmc.WorkingSetSize ) + '~r~n' & + "QuotaPeakPagedPoolUsage: " + string(pmc.QuotaPeakPagedPoolUsage ) + '~r~n' & + "QuotaPagedPoolUsage: " + string(pmc.QuotaPagedPoolUsage ) + '~r~n' & + "QuotaPeakNonPagedPoolUsage: " + string(pmc.QuotaPeakNonPagedPoolUsage ) + '~r~n' & + "QuotaNonPagedPoolUsage: " + string(pmc.QuotaNonPagedPoolUsage) + '~r~n' & + "PagefileUsage: " + string(pmc.PagefileUsage ) + '~r~n' & + "PeakPagefileUsage: " + string(pmc.PeakPagefileUsage ) */ Name=space(254) resName=GetModuleBaseNameW(handleP[ifx], i_Module.lpidmodule[1], name ,254) //MessageBox( "Memory Info for : " + Name,ls_message) ii ++ //mle_1.text += "~r~nMemory Info for : " + Name + ls_un + ls_message + ls_un if name = as_procname then ul_hfound = handleP[ifx] exit //for end if end if end if CloseHandle(HandleP[ifx]) next /* IF ii > 0 THEN mle_1.text = "Retrieved ProcessMemoryInfo for " + string(ii) + " processes~r~n" + mle_1.text END IF else MessageBox ("Memory Info","Fail calling EnumProcesses") */ end if return ul_hfound end function on unvo_process_mgt.create call super::create TriggerEvent( this, "constructor" ) end on on unvo_process_mgt.destroy TriggerEvent( this, "destructor" ) call super::destroy end on
Dernière modification par seki (14-09-2012 09:27:47)
Hors ligne
ok
le kill marche bien, mais quand je fais un simple of_run( exe, normal!, "" ), PB se vautre lamentablement
Hors ligne
erasorz a écrit:
PB se vautre lamentablement
Gni? Tu peux montrer le bout de code ?
Hors ligne
c'est ce que j'ai mis en remplaçant exe par le chemin et nom complet d'un exécutable...
Hors ligne
Bizarre.
Je en reproduis pas de plantage en appelant un exe avec son path complet, ni avec un path incorrect (PB 11.5.1.4843 Win7 64b).
Hors ligne