Comment crypter le dossier "Ressources"
Quelqu'un qui a testé mon utilitaire m'a signalé qq chose qui peut se révéler gênant. Lorsqu'on fait 'Ouvrir le paquet' de l'exécutable, on aboutit à un dossier 'Ressources'.
Le problème est qu'à l'intérieur il y a tous mes scripts et qu'on peut facilement les modifier car ils sont en .txt. Il y a le double de chaque script en version .scpt et qui est binaire lui.
Le problème est que pour s'exécuter depuis Xcode, il faut des fichiers de script en .txt mais j'en suis pas totalement sûr.
Je voudrais savoir s'il y a une possibilité de crypter ces fichiers texte de scripts pour les rendre non copiables ni modifiables. Opaques quoi.
Merci d'avance
P.S. Les 3 instructions dont je me sers (merci Mr Tablier!) pour appeler le script sont:
leFormat = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:@Ouvrir_READ_ME ofType:@txt]
usedEncoding:&enc error:NULL];
monScript = [[NSAppleScript alloc] initWithSource:leFormat] ; // Création du script
descripteur = [monScript executeAndReturnError:&infoErreur] ;
J'ai pas essayé mais est-ce qu'on peut lancer un applescript par le fichier .scpt donc binaire en remplaçant la 1ère instruction du groupe par:
leFormat = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:@Ouvrir_READ_ME ofType:@scpt]
usedEncoding:&enc error:NULL];
Réponses
Il faut utiliser la méthode initWithContentsOfURL de NSAppleScript pour lire un fichier Script compilé.
Merci beaucoup je vais essayer cela. Mais ce n'est pas pour charger des ressources sur un site en lui donnant un URL ? Ou alors on peut mettre une URL locale commençant par 127.0.0.1 ? ? Je vais regarder cela...
En tout cas dans les exemples donnés sur le Net il semble qu'on introduit un URL en amont avant de lancer cette méthode. Désolé suis un peu débutant et pas encore très à l'aie avec toutes ces méthodes.
http://stackoverflow.com/questions/15282658/nsstring-initwithcontentsofurl-problems
J'imagine qu'on met une instruction comme:
NSURL *url = [[NSURL alloc] initWithString:@"http://127.0.0.1/directory/script.scpt"];
et sans doute après on lance le script compilé par:
NSError *error;
NSStringEncoding *encoding = nil;
NSString *tryString = [[NSString alloc] initWithContentsOfURL:url
usedEncoding:encoding
error:&error];
NSLog(@string:%@", tryString);
Non, il existe des file URL. (d'ailleurs elles commencent par file://)
Exact , erreur ou oubli de ma part.
NSURL *url = [[NSURL alloc] initWithString:@"file://127.0.0.1/dir...ry_de_Appli/Ressources/script.scpt"];
Comme ça on charge le script compilé qui se trouve dans le dossier Ressources, enfin j'imagine.
Mais en gros la syntaxe c'est ça non ?
Merci beaucoup. Si mes scripts compilés se trouvent sous Contents/Resources de mon exécutable, j'imagine qu'il faut mettre en tête une ligne:
NSURL *pathForResource = [[NSURL alloc] initWithStringOfURL@"/Contents/Resources/script.scpt"];
ensuite:
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@script ofType:@scpt];
NSURL *scriptFileURL = [NSURL fileURLWithPath:scriptPath];
et à la fin:
descripteur = [scriptFileURL executeAndReturnError:&infoErreur] ;
​C'est à peu près cela ? Ou alors descripteur = [scriptFileURL CompileAndReturnError:&infoErreur] ? Plutôt le dernier non ?
Oui on peut effectivement faire inutilement compliqué aussi.
Mais la solution de Ceroce est largement suffisante.
Et bien sûr ce n'est pas utile de compiler un Script binaire, qui par définition est déjà compilé.
exact suis-je bête. Donc ces 2 instructions suffisent. Je vais essayer ça.
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@"/Contents/Resources/script" ofType:@scpt];
NSURL *scriptFileURL = [NSURL fileURLWithPath:scriptPath];
Normalement ça devrait marcher d'après vous ? Merci en tout cas.
La méthode "pathForResource:ofType:" de NSBundle fait tout le travail pour toi. Regarde dans la doc de NSBundle, et dans les diverses doc qui expliquent l'organisation des ressources dans ton bundle d'application.
En gros NSBundle gère tout pour toi, sait que les ressources sont dans /Contents/Ressources sous OSX et à la racine sous iOS, va chercher la ressource dans la bonne langue si elle est localisée, etc.
Il n'est surtout pas nécessaire de préciser le "Contents/Resources" dans ton chemin. Pire encore, ça ne marchera pas (ça risque d'essayer d'aller chercher dans "TonApp.app/Contents/Resources/Contents/Resources/script.scpt" qui évidemment n'existe pas à cet emplacement).
Relis la doc de NSBundle des de cette méthode, c'est plutôt bien expliqué en général.
Re-merci. Je suis assez débutant et il faut que je me plonge dans la doc. Compliqué car le coe“ur de la programmation de mon utilitaire est en Applescript et l'interface en Xcode.
Mais je vais y arriver et m'en sortir.
Re-Merci
P.S. Par curiosité et intérêt, si on compile avec non pas Build mais Build and Release, on voit toujours les extraits source des scripts en .txt ? En fait il semble que oui et je me demandais juste s'il n'y avait pas une astuce pour faire qu'ils n'apparaissent pas dans les Ressources au moment de la création du standalone. On peut aussi les retirer à la main, le programme n'en a pas besoin pour s'exécuter mais j'ai peur qu'en les soumettent à AppStore via Archive, on envoie tout d'un bloc et que les fichiers .txt continuent de figurer dans les Ressources. Et du coup c'est la porte ouverte au copiage et pire, au piratage.
Bon ceci dit l'appel de méthodes d'instances d'Applescript via NSBundle et les variables pathForResource et fileURLWithPath semble bien être la meilleure solution effectivement.
Petit problème pour compiler:
NSAppleEventDescriptor *descripteur;
NSURL *scriptFileURL;
NSString *scriptPath;
NSDictionary *infoErreur;
scriptPath = [[NSBundle mainBundle] pathForResource:@Ouvrir_READ_ME ofType:@scpt];
scriptFileURL = [NSURL fileURLWithPath:scriptPath];
descripteur = [scriptFileURL executeAndReturnError:&infoErreur];
Il me met "No visible Interface for NSURL declares the selector executeAndReturnError"
executeAndReturnError semble être une méthode associée à NSAppleScript et pas NSURL d'où confusion
===============
Si je remplace par:
NSAppleScript *scriptFileURL;
NSString *scriptPath;
NSDictionary *infoErreur;
NSAppleEventDescriptor *descripteur;
scriptPath = [[NSBundle mainBundle] pathForResource:@Ouvrir_READ_ME ofType:@scpt];
//scriptFileURL = [NSURL fileURLWithPath:scriptPath];
scriptFileURL = [[NSAppleScript alloc] initWithSource:scriptPath] ; // Création du script
descripteur = [scriptFileURL executeAndReturnError:&infoErreur];
Il s'exécute car comprend la méthode executeAndReturnError mais il plante ou boucle en me mettant un breakpoint dans la fenêtre Navigator sur cette dernière instruction.