Communication Inter-Processus (IPC) pour Windows avec C
J'ai un vieux programme écrit en C avec Microsoft Visual C++, et j'ai besoin de mettre en œuvre une sorte de "keepalive", je suis donc en mesure de recevoir la pensée de communication interprocessus dans un nouveau programme qui va tuer et re-lancement de la première, si pas de msg a été reçu dans les 5 dernières secondes.
Le problème est que j'ai été à la recherche pour n'importe quel tutoriel ou un exemple de l'IPC pour Windows en langage C, mais presque tout ce que j'ai trouver est pour le C++.
De l'aide ou des ressources?
EDIT: Comme @Adriano suggéré dans les réponses, je suis en train d'utiliser la Mémoire Partagée. Mais le programme de lanceur est terminée par les Fenêtres, en raison d'une sorte d'exception, je ne suis pas être en mesure de les rattraper. Se produit lors de l'appel de CopyMemory.
Le code est le suivant:
#include "stdafx.h"
#include "windows.h"
#include "iostream"
using namespace std;
int launchMyProcess();
void killMyProcess();
bool checkIfMyProcessIsAlive();
STARTUPINFO sInfo;
PROCESS_INFORMATION pInfo;
HANDLE mappedFile;
LPVOID pSharedMemory;
long lastReceivedBeatTimeStamp;
const int MSECONDS_WITHOUT_BEAT = 500;
const LPTSTR lpCommandLine = "MyProcess.exe configuration.txt";
int main(int argc, char* argv[])
{
mappedFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(int), "Global\\ActivityMonitor");
LPVOID pSharedMemory = MapViewOfFile(mappedFile, FILE_MAP_READ, 0, 0, sizeof(int));
if(!launchMyProcess()){
cout<<"Error creating MyProcess.exe"<<endl;
UnmapViewOfFile(pSharedMemory);
CloseHandle(mappedFile);
return -1;
}
while(true){
Sleep(100);
if(!checkIfMyProcessIsAlive()){
cout<<"Relaunching MyProcess...";
killMyProcess();
if(!launchMyProcess()){
cout<<"Error relaunching MyProcess.exe"<<endl;
UnmapViewOfFile(pSharedMemory);
CloseHandle(mappedFile);
return -1;
}
}
}
UnmapViewOfFile(pSharedMemory);
CloseHandle(mappedFile);
return 0;
}
bool checkIfMyProcessIsAlive()
{
static int volatile latestMagicNumber = 0;
int currentMagicNumber = 0;
CopyMemory(¤tMagicNumber, pSharedMemory, sizeof(int));
if(currentMagicNumber != latestMagicNumber){
latestMagicNumber = currentMagicNumber;
return true;
}
return false;
}
int launchMyProcess()
{
ZeroMemory(&sInfo, sizeof(sInfo));
sInfo.cb = sizeof(sInfo);
ZeroMemory(&pInfo, sizeof(pInfo));
return CreateProcess(NULL, lpCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &sInfo, &pInfo);
}
void killMyProcess()
{
TerminateProcess(pInfo.hProcess, 0);
CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread);
Sleep(3000);
}
- Il n'a pas d'importance si les tutoriels sont en C++, ils vont être en utilisant le même C fonctions WIN32.
- Ce n'est pas, mais C tutoriel serait reçu avec joie 🙂
so I am able to receive it thought interprocess communication into a new program
est un peu vague. Comment, exactement, êtes-vous d'obtenir des informations de l'ancien programme? Cela ne ressemble pas à un IPC de problème pour moi. Si votre nouveau programme engendre l'ancienne, via la fonction CreateProcess dire, alors vous pouvez le tuer et re-créer très facilement.- Oui @Skizz la création/fin de processus fonctionne bien. Maintenant, je n'ai pas mis en œuvre de toute forme de communication entre l'ancien et le nouveau (lanceur). J'essaie de trouver quelle est la meilleure approche pour quelque chose d'aussi simple que de emmiting un battement de coeur, comme Mark Wilkins a dit
Vous devez vous connecter pour publier un commentaire.
Si votre vieux C application dispose d'une pompe de message (car il a une INTERFACE utilisateur) peut-être le principe le plus simple moyen pour vérifier si il est vivant ou pas est IsHungAppWindow() fonction et Windows va faire les choses pour vous.
Si ce n'est pas votre cas et que vous avez besoin de la CIB il existe de nombreuses options, cela dépend de quel type de mécanisme IPC vous souhaitez utiliser. Ici je vais énumérer quelques ressources.
Pour une vue d'ensemble de l'IPC techniques: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365574(v=vs. 85).aspx
Quelques exemples:
MODIFIER
Je pense qu'un petit exemple permettra de clarifier beaucoup plus que des tonnes de mots. Dans cet exemple je vais utiliser la mémoire partagée, mais vous pouvez utiliser celui que vous préférez (et vous vous sentez plus à l'aise avec). Il est non testé donc veuillez utiliser comme référence.
Le processus du MONITEUR, doit être lancé en premier.
Le processus SURVEILLÉ, il va signal de son activité pour le processus du Moniteur.
De mémoire partagée est un très léger de ressources et vous pouvez utiliser ce que vous préférez pour votre chronomètres (si le timing n'est pas une exigence stricte, vous pouvez faire une sorte de repos de traitement. Personnellement, j'aime cette cause vous n'aurez pas besoin de verrouiller n'importe quel thread, et probablement que vous avez un délai d'inactivité thread de traitement).
Fonctions de minuterie sont pris en charge à partir de Windows 2000, assurez-vous que _WIN32_WINNT macro est définie avec 0x0500 (ou plus).
Additif
Je n'ai pas mentionné dans la liste, car ils n'existent que dans les plus récentes versions de système d'exploitation, mais vous pouvez même l'utiliser les variables de condition. Windows 8 va prendre en charge un très utile WaitOnAddress fonction, mais c'est quand même l'avenir je pense donc que vous ne pouvez pas l'utiliser.
De l'OP et les différents commentaires, il semble que si l'objectif principal est de déterminer si la demande est suspendu. Un couple des manières assez simples à créer une sorte de "battement de cœur", qui peut être suivi par une autre application serait soit de la mémoire partagée ou un sémaphore nommé.
Vous pouvez utiliser CreateFileMapping et MapViewOfFile dans un processus de création de la mémoire partagée et ensuite utiliser MapViewOfFile dans les autres processus pour obtenir un pointeur vers elle. Si vous avez créé il à la taille d'un entier, une méthode simple de keep-alive serait d'avoir le processus d'incrémenter la valeur dans la mémoire de quelques secondes. L'autre processus peut lire toutes les quelques secondes pour vérifier qu'il est en train de changer.
Avec un nom sémaphore (CreateSemaphore et OpenSemaphore), vous pourriez faire essentiellement la même chose. Ont la surveillés application du signal périodiquement et ont le moniteur attendre sur lui pour s'assurer qu'il a été signalé.
Ce qui semble être un autre cas d'aller sur quelque chose de très long chemin à cause d'un manque de familiarité avec la plate-forme que vous avez affaire.
Si tous vous avez besoin de savoir comme vous le dites dans votre commentaire est de savoir si ou non votre programme est vivant donc vous pouvez le tuer, vous n'avez même pas à distance besoin de la CIB.
Au début du programme que vous souhaitez surveiller:
Dans le "chien de garde" du programme, vous vérifiez si les autres utilitaire est vivant comme ceci:
Il existe une demi-douzaine d'autres solutions qui s'appliquent tout aussi bien (ou mieux). Si votre chien de garde est le seul qui ait jamais crée de l'application qui va être surveillés, vous pouvez attendre sur le
HANDLE
deCreateProcess
(ouShellExecuteEx
).