2010-01-06 12 views
2

Je travaille sur un programme d'installation de NSIS et j'essaie de vérifier si une certaine application est en cours d'exécution avant de la désinstaller. Donc, j'utilise kernel32::CreateMutexA appel. Voici le morceau:Détecter si une instance est en cours d'exécution avec kernel32 :: CreateMutexA

System::Call 'kernel32::CreateMutexA(i 0, i 0, t "cmd.exe") i .r1 ?e' 
Pop $R0 
StrCmp $R0 0 +3 
    MessageBox MB_USERICON "The application is already running." 
Abort 

je l'ai mis en un.onInit. Le problème est, le processus (cmd.exe ici) n'est jamais détecté.

Ai-je raté quelque chose?

Tx.

+0

Un nombre quelconque d'instances de cmd.exe peut s'exécuter sur un système pour plusieurs raisons – Anders

+0

En fait, 'cmd.exe' était juste un exemple. – Anonymous

Répondre

2

J'ai trouvé une solution simple; en utilisant FindProcDLL plugin.

Alors:

FindProcDLL::FindProc "cmd.exe" 
Pop $R0 
StrCmp $R0 0 +3 
MessageBox MB_USERICON "The application is already running." IDOK 
Abort 

post-scriptumFindProcDLL.dll doit être copié dans /Plugins.

+0

Cela ne fonctionne pas avec NSIS 2.46, comme cela est également documenté sur la page. – Rex

1

Tout ce que vous faites est de créer un mutex avec le nom global "cmd.exe". De l'MSDN article pour CreateMutex:

Si lpName correspond au nom d'un événement existant, sémaphores, waitable timer, travail, ou d'un objet de mappage de fichier, la fonction échoue et la fonction retourne GetLastError ERROR_INVALID_HANDLE. Cela se produit car ces objets partagent le même espace de noms.

Donc, à moins cmd.exe crée une poignée à l'un de ces types d'objets avec le nom "cmd.exe", cet appel sera simplement créer un nouveau mutex avec ce nom et vous renvoyer le (non erronous) manipuler.

1

Vous utilisez probablement la mauvaise fonction API Win32. Votre CreateMutex essaie de créer un mutex nommé "something.exe". S'il n'y en a pas un, il réussira, donc à moins que le processus que vous essayez de vérifier crée un mutex avec ce nom, vous n'obtiendrez pas le résultat que vous recherchez.

Ce que vous voulez est probablement d'énumérer tous les processus en cours et de voir si celui que vous cherchez est là. Vous pouvez le faire avec ToolHelp32 à partir de Win32 API - voir sample here. Je ne sais pas à quel point il sera facile de le convertir en NSIS «pur», donc vous pourriez vouloir écrire un plugin DLL, ou vérifier s'il y a une solution existante flottant autour de la communauté NSIS.

+0

Tx Idan. C'est étrange. Lorsque j'essaie avec le programme d'installation lui-même (par exemple 'my_setup.exe'), cela fonctionne! Mais pas avec un autre processus. – Anonymous

+0

qu'est-ce qui fonctionne? à partir de votre exemple de code, la boîte de message apparaîtra si CreateMutexA a réussi - c'est-à-dire qu'il n'y a pas de mutex nommé avec le nom que vous avez fourni. indépendamment du comportement que vous obtenez, c'est la mauvaise solution au problème que vous essayez de résoudre. –

+0

'CreateMutexA()' réussit avec le programme d'installation lui-même. Donc, c'est en fait la bonne solution pour détecter s'il y a une instance en cours d'exécution du programme d'installation. Mais comme vous l'avez dit, pas le bon pour un autre processus. – Anonymous

0

Pour ce genre de chose, je l'ai utilisé, l'KillProcess ou FIND-Close-Terminate plugins pour NSIS - voir here

La documentation est assez simple, nous espérons que cela fait ce que vous avez besoin - avec un surcoût assez minime .