Savoir si un Process NSTask est fini

aranaudaranaud Membre
08:32 modifié dans API AppKit #1
Je voudrai savoir si s'est possible (sûrement) de savoir si un processus lancer avec NSTask est fini. Et comment le savoir.

J'ai essayé avec :
<br />- (void)checkATaskStatus:(NSNotification *)aNotification {<br />&nbsp; &nbsp; int status = [[aNotification object] terminationStatus];<br />&nbsp; &nbsp; if (status == 0) {<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;Task succeeded.&quot;);<br />&nbsp; &nbsp; &nbsp; &nbsp; ...<br />&nbsp; &nbsp; &nbsp; &nbsp; // mon code<br />&nbsp; &nbsp; &nbsp; &nbsp; ...<br />&nbsp; &nbsp; } else {<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;Task failed.&quot;);<br />&nbsp; &nbsp; }<br />}<br />

Mais sa plante (. Est-ce que j'utilise la bonne méthode ou pas ?

Nota : il y a plusieurs NSTask.

Réponses

  • fouffouf Membre
    avril 2006 modifié #2
    Tu peux utiliser NSTaskDidTerminateNotification qui permet de savoir quand un processus se finit. De plus, tu peux connaà®tre la NSTask qui a fini grâce à  l'objet de la notif. Après, tu peux faire un tableau de booléens pour savoir quels sonts les processus ayant quitté ou non ...

    [ouf à  3 minutes près j'était grillé ;) ]
  • BruBru Membre
    08:32 modifié #3
    dans 1144571035:

    Mais sa plante (. Est-ce que j'utilise la bonne méthode ou pas ?


    Merci d'en dire un peu plus la prochaine fois.

    Ce que j'arrive à  deviner dans ma boule de cristal, c'est que tu dois utiliser la notification NSTaskDidTerminateNotification.

    Mais comme ma boule de cristal n'arrive pas à  voir comment tu a écris le code de création/lancement de la NSTask et l'enregistrement auprès du notificationCenter, alors là  s'arrête ma divination.

    .
  • aranaudaranaud Membre
    08:32 modifié #4
    Je vais essayer d'être plus clair.

    dans l'init
    <br />- (id)init<br />{ <br />&nbsp; &nbsp; self = [super init];<br />&nbsp; &nbsp; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkATaskStatus:) name:NSTaskDidTerminateNotification object:nil];<br />&nbsp; &nbsp; return self;<br />}<br />
    


    lancement du process, suite au téléchargement d'une archive sur internet, je la décompresse.
    <br />/* fin du telechergement */<br />- (void)downloadDidFinish:(NSURLDownload *)download<br />{<br />&nbsp; &nbsp; NSLog(@&quot;Telechargement fini&quot;);<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; //&nbsp; décompression de l&#39;archive<br />&nbsp; &nbsp; NSTask *openMiseJours = [[NSTask alloc] init];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  // class pour la command unix<br />&nbsp; &nbsp; [openMiseJours setLaunchPath:@&quot;/usr/bin/unzip&quot;];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  // on execute la commande terminal dans les lignes qui suivent : open<br />&nbsp; &nbsp; [openMiseJours setCurrentDirectoryPath:[[NSString stringWithString:@&quot;~/Library/Application Support/gestion_bugdet_maison&quot;] stringByExpandingTildeInPath]];&nbsp; // endroit de l&#39;execution de la commande<br />&nbsp; &nbsp; [openMiseJours setArguments:[NSArray arrayWithObjects: @&quot;-j&quot;, [[NSString stringWithString:@&quot;~/Library/Application Support/gestion_bugdet_maison/miseJours2.zip&quot;] stringByExpandingTildeInPath], nil]];&nbsp; &nbsp; // argument : option , nom archive, fichier<br />&nbsp; &nbsp; [openMiseJours launch]; <br />}<br />
    


    Traitement une fois décompresse
    <br />- (void)checkATaskStatus:(NSNotification *)aNotification {<br />&nbsp; &nbsp; int status = [[aNotification object] terminationStatus];<br />&nbsp; &nbsp; if (status == 0) {<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;Task succeeded.&quot;);<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; charge et décodage de la mise à  jours<br />&nbsp; &nbsp; &nbsp; &nbsp; unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:[NSData dataWithContentsOfFile:[[NSString stringWithString:@&quot;~/Library/Application Support/gestion_bugdet_maison/miseJours2.plist&quot;] stringByExpandingTildeInPath]]];<br />&nbsp; &nbsp; &nbsp; &nbsp; docInternet = [[NSMutableDictionary alloc] initWithDictionary:[unarchiver decodeObjectForKey:@&quot;lolita&quot;]];<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; if ([versionActuelUtiliser isEqualToString:[[docInternet objectForKey:@&quot;normale&quot;] objectForKey:@&quot;versionAppl&quot;]]) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSBeep();							// bip system<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSRunAlertPanel(NSLocalizedString(@&quot;message1&quot;, nil), NSLocalizedString(@&quot;message1&quot;, nil), @&quot;OK&quot;, nil, nil);<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newVersionOK = NO;<br />&nbsp; &nbsp; &nbsp; &nbsp; } else {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSBeep();							// bip system<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (gestionnaireFenetre == nil) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  // charge et affichage de la fenêtre<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gestionnaireFenetre = [[gestionFenetreUpdate alloc] initWithWindowNibName:@&quot;windowUpdate&quot;];&nbsp; &nbsp; &nbsp; &nbsp;  // charge interface windowUpdate<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [gestionnaireFenetre showWindow:nil];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  // affichage de la fenêtre<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newVersionOK = YES;<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; } else {<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;Task failed.&quot;);<br />&nbsp; &nbsp; }<br />}<br />
    


    Le rapport de blocage

    Thread 0 Crashed:
    0  libobjc.A.dylib                0x90a46100 objc_msgSend + 32
    1  com.apple.Foundation          0x92975ad8 _nsnote_callback + 180
    2  com.apple.CoreFoundation      0x9080b4c4 __CFXNotificationPost + 368
    3  com.apple.CoreFoundation      0x908035a0 _CFXNotificationPostNotification + 684
    4  com.apple.Foundation          0x9295fee0 -[NSNotificationCenter postNotificationName:object:userInfo:] + 92
    5  com.apple.Foundation          0x929775d4 _performTaskSource + 120
    6  com.apple.CoreFoundation      0x907e4a68 __CFRunLoopDoSources0 + 384
    7  com.apple.CoreFoundation      0x907e3f98 __CFRunLoopRun + 452
    8  com.apple.CoreFoundation      0x907e3a18 CFRunLoopRunSpecific + 268
    9  com.apple.HIToolbox            0x9321d980 RunCurrentEventLoopInMode + 264
    10  com.apple.HIToolbox            0x9321d014 ReceiveNextEventCommon + 380
    11  com.apple.HIToolbox            0x9321ce80 BlockUntilNextEventMatchingListInMode + 96
    12  com.apple.AppKit              0x93720104 _DPSNextEvent + 384
  • BruBru Membre
    avril 2006 modifié #5
    Dans ton code init :
    dans 1144573311:
    <br />    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkATaskStatus:) name:NSTaskDidTerminateNotification object:nil];<br />
    


    et plus loin, dans la méthode de fin de NSTask :
    dans 1144573311:
    <br />    int status = [[aNotification object] terminationStatus];<br />
    


    Comment veux tu que [aNotification object] fonctionne, puisque tu y mets nil ?

    Modifie ton code en supprimant ta méthode init, et en mettant :
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkATaskStatus:) name:NSTaskDidTerminateNotification object:openMiseJours];
    

    à  la suite [openMiseJours setCurrentDirectoryPath:] dans la méthode downloadDidFinish.

    Enfin, dans la méthode checkATaskStatus, n'oublie pas de faire un release sur la tâche (ce que tu ne semble pas faire actuellement) et de retirer du NSNotificationCenter ton observateur.

    .
  • aranaudaranaud Membre
    08:32 modifié #6
    OK. Merci Bru.  <3 <br />
    Nota : l'exemple donné par Apple n'est pas très claire.

    -(id)init {
        self = [super init];
        [[NSNotificationCenter defaultCenter] addObserver:self
                selector:@selector(checkATaskStatus:)
                name:NSTaskDidTerminateNotification
                object:nil];
        return self;
    }

    - (void)checkATaskStatus:(NSNotification *)aNotification {
        int status = [[aNotification object] terminationStatus];
        if (status == ATASK_SUCCESS_VALUE)
            NSLog(@Task succeeded.);
        else
            NSLog(@Task failed.);
    }
  • maconnectmaconnect Membre
    08:32 modifié #7
    dans 1144575305:
    Enfin, dans la méthode checkATaskStatus, n'oublie pas de faire un release sur la tâche (ce que tu ne semble pas faire actuellement) et de retirer du NSNotificationCenter ton observateur.
    il a oublié :P
    [[aNotification object] release];<br />[[NSNotificationCenter defaultCenter] removeObserver:self];
    


    @+
Connectez-vous ou Inscrivez-vous pour répondre.