Plantage d'appli NSTask, Sierra - Obj-C NSTask |
Bienvenue invité ( Connexion | Inscription )
Plantage d'appli NSTask, Sierra - Obj-C NSTask |
20 Aug 2017, 11:03
Message
#1
|
|
Macbidouilleur d'argent ! Groupe : Membres Messages : 710 Inscrit : 16 Oct 2004 Membre no 25 318 |
Bonjour,
Voilà maintenant quelques années que je n'ai pas touché à Xcode ou bien pour de minimes retouches sur des projets perso. Et venant d'installer Sierra sur mon ordi, j'ai pu constaté que l'appel à un exécutable unix depuis une application via NSTask, faisait planter immédiatement l'app. J'ai donc réécrit une classe dans mon application pour me passer de cet exécutable. Mais j'en ai un autre pour lequel je n'ai pas la moindre idée de la façon dont il procède et je ne peux donc pas m'en passer. Comment faire pour intégrer un exécutable unix dans un projet Xcode sous Mac OS 10.12 pour pouvoir l'appeler depuis l'application avec NSTask ? Y-aurait-il un système de signature ou bien de niveau d'autorisation nécessaire pour l'application pour exécuter d'autres programmes ? Merci PS : l'exécutable appelé depuis le Terminal avec exactement les mêmes arguments... fonctionne très bien. Ce message a été modifié par Nono95400 - 20 Aug 2017, 11:04. -------------------- MacBook Pro 13" M1 2020 - 16Go de RAM - SSD 256Go
Mac Pro early '09 Quad-Core Intel Xeon 2,93 GHz - 8Go de RAM - ATI HD5870 1Go - SSD Vortex 2 128Go - HD 1To, 2To, 3To. MacBook Air 13" i7 1,8Ghz - 4Go de RAM - SSD 256Go |
|
|
24 Aug 2017, 22:24
Message
#2
|
|
Macbidouilleur de vermeil ! Groupe : Membres Messages : 879 Inscrit : 4 Apr 2004 Lieu : Lorraine - 54 Membre no 17 184 |
Bonsoir Nono
Tu ne précises pas grand chose sur ton code et un extrait pourrait être utile pour t'aider davantage. Ou as tu placé ton script ? comment l'appelles tu ? es tu certain des droits d'exécution de ton script (la version qui est exécutée) ? Je viens de faire un essai avec Xcode sous Sierra et l'appel à NSTask fonctionne parfaitement (sous réserve d'avoir bien donné les droits d'execution à ton script). Par ailleurs, en utilisant un bloc try comme ci-dessous, ton application ne devrait pas planter et pourra te donner la raison du blocage. Code @try { NSTask *t = [[NSTask alloc] init]; ... } @catch (NSException *e) { NSLog(@"Expection occurred %@", [e reason]); } De grandes chances que si le chemin n'est pas correct ou si les droits d'exécution ne sont pas attribués tu trouves le défaut : launch path not accessible. Ce message a été modifié par teddy7545 - 24 Aug 2017, 23:51. -------------------- MP Intel Dual Xéon 3 GHz - MacOSX 10.10.3 - ATI Radeon HD 5770 - ATTO UL5D - Apple Cinema HD Display 23 pouces MBP 15' 2017 - MBP 13' mid 2009 - iMac 24' 8,1 2,8GHz - MP G4 MDD Bi 1,25 GHz - MP G4 Quicksylver 933MHz |
|
|
25 Aug 2017, 06:22
Message
#3
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 486 Inscrit : 29 Aug 2002 Membre no 3 340 |
Est-ce l'occasion de jeter un œil à Swift
un "gist" donne un exemple: https://gist.github.com/Seasons7/836d3676884a40c8c98a Code import Foundation let filePath = "/usr/local" // Création de la tâche en Swift 3.x let task = Process() // Configuration de la tâche task.launchPath = "/bin/ls" task.arguments = ["-laF@" , filePath] // Tuyau de sortie let pipe = Pipe() task.standardOutput = pipe // Exécution de la tâche task.launch() // Récupération du résultat let data = pipe.fileHandleForReading.readDataToEndOfFile() let output = String(data: data, encoding: String.Encoding.utf8) print(output!) Et on peut l' essayer sans compiler dans un playground. J-P Ce message a été modifié par Jaypee - 25 Aug 2017, 06:28. |
|
|
26 Aug 2017, 16:32
Message
#4
|
|
Macbidouilleur de vermeil ! Groupe : Membres Messages : 879 Inscrit : 4 Apr 2004 Lieu : Lorraine - 54 Membre no 17 184 |
Bonjour
Merci Jaypee pour le petit test en Swift ... c'est en effet une bonne occasion de tester un peu plus Swift (surtout maintenant que je viens de passer à Sierra avec Xcode 8) Evidemment ça fonctionne très bien ... mais même en Swift il faut que le script possède les droits d'exécution .... et à défaut ça fait évidemment planter de la même façon qu'en ObjectiveC.... Dans ton exemple, tu utilises un exécutable du système (qui est évidemment exécutable) mais je pense que Nono95400 souhaitais utiliser un script perso encaqué dans son bundle auquel il doit affecter les droits au bon fichier (celui qui est ajouté dans le répertoire source) De fait, pour avoir un message d'erreur en clair plutôt qu'un plantage il faudrait également utiliser en Swift un équivalent du bloc try que j'avais moi même mis en place avec ObjectiveC pour comprendre le problème que rencontrait Nono95400. J'ai trouvé quelques exemples de code Swift qui mettent en oeuvre ce mécanisme et je vais essayer de l'implémenter dans cet exemple avec NSTask. Ce message a été modifié par teddy7545 - 26 Aug 2017, 16:37. -------------------- MP Intel Dual Xéon 3 GHz - MacOSX 10.10.3 - ATI Radeon HD 5770 - ATTO UL5D - Apple Cinema HD Display 23 pouces MBP 15' 2017 - MBP 13' mid 2009 - iMac 24' 8,1 2,8GHz - MP G4 MDD Bi 1,25 GHz - MP G4 Quicksylver 933MHz |
|
|
27 Aug 2017, 08:40
Message
#5
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 486 Inscrit : 29 Aug 2002 Membre no 3 340 |
Dans le cas où la commande shell se conforme au standard avec la convention:
status == 0 => success status != 0 => erreur on peut récupérer la valeur dans task.terminationStatus un Int32 !!! Attention: ne pas essayer le code suivant avec des privilèges: il tente de supprimer le log du système !!!! Code // import Cocoa // pas certain que ce soit utile import Foundation let filePath = "/var/log/system.log" "" // Création de la tâche en Swift 3.x let task = Process() // Configuration de la tâche task.launchPath = "/bin/rm" task.arguments = ["-f" , filePath] // Tuyau de sortie let pipe = Pipe() task.standardOutput = pipe // Exécution de la tâche task.launch() task.waitUntilExit() // Récupération du résultat let data = pipe.fileHandleForReading.readDataToEndOfFile() let output = String(data: data, encoding: String.Encoding.utf8) print ("Termination status: \(task.terminationStatus)") print("Output: \(output!)") On voit que le statut est 1 donc en erreur. Le shell ne lève pas d'exception donc pas de try catch possible. On voit aussi que output est vide. J-P Ce message a été modifié par Jaypee - 27 Aug 2017, 10:20. |
|
|
1 Sep 2017, 18:54
Message
#6
|
|
Macbidouilleur d'argent ! Groupe : Membres Messages : 710 Inscrit : 16 Oct 2004 Membre no 25 318 |
Bonjour,
Merci pour votre aide. Je suis un peu perdu avec Swift, en ce moment pour le boulot j'apprend C#, VBA et ST. Donc pas trop le temps pour apprendre un langage supplémentaire à titre perso. Je suis tout aussi perdu avec les nouvelles règles de sécurité de Mac OS Sierra, si je comprend bien un exécutable peut ne pas être autorisé à être appelé par une application et en même temps, il peut être lancé sans soucis depuis le Terminal ? L'exécutable est situé dans le dossier "Resources" de l'application, il y est copié par Xcode lors de la compilation de l'application. Comment puis-je l'autorisé à être exécuté par mon application ? -------------------- MacBook Pro 13" M1 2020 - 16Go de RAM - SSD 256Go
Mac Pro early '09 Quad-Core Intel Xeon 2,93 GHz - 8Go de RAM - ATI HD5870 1Go - SSD Vortex 2 128Go - HD 1To, 2To, 3To. MacBook Air 13" i7 1,8Ghz - 4Go de RAM - SSD 256Go |
|
|
2 Sep 2017, 18:58
Message
#7
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 486 Inscrit : 29 Aug 2002 Membre no 3 340 |
Salut Nono95400,
Si on vérifie les basiques, les permissions elles sont correctes? il doit y avoir r et x au minimum partout, 755 ou rwxr-xr-x sur la commande que tu embarques dans l'appli J-P Ce message a été modifié par Jaypee - 2 Sep 2017, 19:10. |
|
|
5 Sep 2017, 19:20
Message
#8
|
|
Macbidouilleur d'argent ! Groupe : Membres Messages : 710 Inscrit : 16 Oct 2004 Membre no 25 318 |
Bonjour,
Voici les droits de l'exécutable qui est copié dans l'appli lors de la compilation par Xcode : -rwxr-xr-x -------------------- MacBook Pro 13" M1 2020 - 16Go de RAM - SSD 256Go
Mac Pro early '09 Quad-Core Intel Xeon 2,93 GHz - 8Go de RAM - ATI HD5870 1Go - SSD Vortex 2 128Go - HD 1To, 2To, 3To. MacBook Air 13" i7 1,8Ghz - 4Go de RAM - SSD 256Go |
|
|
8 Sep 2017, 20:44
Message
#9
|
|
Macbidouilleur de vermeil ! Groupe : Membres Messages : 879 Inscrit : 4 Apr 2004 Lieu : Lorraine - 54 Membre no 17 184 |
Bonsoir,
Ton problème est curieux car les droits que tu mentionne sont bien adaptés. J'ai fais les tests avec Xcode en ObjectiveC comme en Swift (avec la proposition de Jaypee) et tout fonctionne sans problème. Citation PS : l'exécutable appelé depuis le Terminal avec exactement les mêmes arguments... fonctionne très bien. Es tu certain que c'est le même exécutable que tu lances avec Xcode ou avec le terminal (je veux dire pas sa copie située à un autre endroit)Citation Voici les droits de l'exécutable qui est copié dans l'appli lors de la compilation par Xcode : -rwxr-xr-x Es tu certain que Xcode utilise bien cet exécutable ? comment l'appelles tu dans ton code ?Peux tu montrer le code que tu utilises pour appeler ton exécutable (ou au moins un extrait) ? Peux tu montrer le défaut que tu obtient ? -------------------- MP Intel Dual Xéon 3 GHz - MacOSX 10.10.3 - ATI Radeon HD 5770 - ATTO UL5D - Apple Cinema HD Display 23 pouces MBP 15' 2017 - MBP 13' mid 2009 - iMac 24' 8,1 2,8GHz - MP G4 MDD Bi 1,25 GHz - MP G4 Quicksylver 933MHz |
|
|
9 Sep 2017, 09:23
Message
#10
|
|
Macbidouilleur d'argent ! Groupe : Membres Messages : 710 Inscrit : 16 Oct 2004 Membre no 25 318 |
Bonjour,
Sans rien avoir changé à mon projet ou au code, voilà que l'appli ne plante plus lors de l'appel à l'exécutable Pour info, le bout de code réalisant l'appel : Code + (NSString *)executeGetMonitor:(NSArray*)arguments { NSString * strResult=nil; NSPipe * thePipe=[[NSPipe alloc] init]; NSTask * theTask=[[NSTask alloc] init]; NSString * path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"highmonitor"]; [theTask setLaunchPath: path]; [theTask setArguments: arguments]; [theTask setStandardOutput: thePipe]; [theTask launch]; [theTask waitUntilExit]; if ([theTask terminationStatus] == 0) { strResult = [[NSString alloc] initWithData:[[thePipe fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding]; } else { strResult = [[NSString alloc] initWithFormat:@"Erreur (%d)", [theTask terminationStatus]]; } [theTask release]; [thePipe release]; return strResult; } Lors de l'exécution, je me rend compte que contrairement à avant (mon passage à Sierra), cela prend plusieurs longues secondes. Je vais peut-être faire un "delegate" pour récupérer le résultat, une fois qu'il est disponible et éviter de bloquer l'appli. -------------------- MacBook Pro 13" M1 2020 - 16Go de RAM - SSD 256Go
Mac Pro early '09 Quad-Core Intel Xeon 2,93 GHz - 8Go de RAM - ATI HD5870 1Go - SSD Vortex 2 128Go - HD 1To, 2To, 3To. MacBook Air 13" i7 1,8Ghz - 4Go de RAM - SSD 256Go |
|
|
Nous sommes le : 29th March 2024 - 23:44 |