IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Récupérer le répertoire de stockage de l'executable


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 53
    Points : 37
    Points
    37
    Par défaut Récupérer le répertoire de stockage de l'executable
    Bonsoir,

    désolé si le sujet a déjà été abordé, mais je ne trouve pas de moyen propre de récupérer le dossier de stockage de l'exécutable de mon programme. Mon problème est d'ouvrir le fichier "config.ini" se trouvant a coté de mon exécutable, même si l'utilisateur le lance depuis ailleurs :

    Soit le code C++ suivant, le programme étant stocké dans /home/user/code/exemple/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::ifstream fichier("config.ini");
    Je veux que ce code ouvre toujours le fichier /home/user/code/exemple/config.ini, même si user tape depuis son home ./code/exemple/exec

    J'utilise boost dans mon développement, et j'aimerai quelque-chose de portable si possible.


    Merci d'avance

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Salut, je crois (à vérifier) que la fonction

    pourra résoudre ton problème

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 53
    Points : 37
    Points
    37
    Par défaut
    Citation Envoyé par salseropom Voir le message
    Salut, je crois (à vérifier) que la fonction

    pourra résoudre ton problème
    ça retourne le répertoire courant, c'est justement ce que je ne veux pas.

    Par contre il faut que je tente de concaténer le dit répertoire courant avec argv[0] privé de ce qui se trouve après le dernier /

    J'aimerai bien une méthode plus propre, si possible. des idées ?

  4. #4
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Le répertoire courant n'est pas le répertoire d'installation de l'exécutable.

    Pour commencer, l'idée de chercher un fichier de configuration dans un chemin relatif à l'exécutable ne correspond pas tellement à la pratique unix (on cherche plutôt à une série d'endroits bien connus: ~/.exerc, /opt/etc/exerc, /usr/local/etc/exerc, /etc/exerc).

    Un problème est qu'en présence de liens hards, l'idée qu'un seul répertoire contient un fichier est fausse. Et j'ai vu utiliser des liens hards pour rassembler des exécutables de différentes sources dans un même répertoire qui lui seul est placé dans le path. Face à ça, la seule solution est de retrouver l'information ailleurs:
    - un endroit bien connu comme suggéré ci-dessus,
    - un endroit hardcodé dans l'exe à la compilation (ça marche bien avec les programmes libres qui sont souvent compilés dans le contexte d'utilisation)
    - un endroit donné par un argument ou une variable d'environnement

    Même si tu ne veux pas supporter les liens hards comme ça, les liens symboliques sont courant dans le même objectif.

    En prime, dès que tu utilises des bibliothèques dynamiques, tu as le problème avant le lancement de l'exécutable -- si tu ne peux pas supposer que ton fichier de config n'est pas à un endroit bien connu mais que les libs sont correctement gérées par l'OS, ok il y a $ORIGIN ou qqch dans le RPATH, mais j'ai jamais vu utilisé en pratique. Donc on lance via script pour mettre le LD_LIBRARY_PATH ou équivalent et qui peut passer l'info du lieu d'installation à l'exe; en prime, il a l'avantage sur l'exe que arg0 est à coup sur le chemin d'accès au script.

    Sinon,
    - argv[0] est le nom de l'exécutable, souvent soit un chemin relatif par rapport au répertoire courant (getcwd() de salseropom), soit un nom à trouver dans le PATH. Mais c'est facile d'induire en erreur, et il y a des contextes où la convention est d'induire en erreur (un shell par exemple).
    - différents moyens dépendant de l'OS -- et de la manière dont il a été configuré:
    * Solaris a /proc/<pid>/paths/a.out qui est un lien symbolique donnant le chemin utilisé pour lancer l'exe
    * Linux a /proc/self/exe qui donne la même chose
    * Linux a dladdr() qui peut servir à trouver l'info
    * Windows a qqch du genre de dladdr()

    Si le résultat est un lien symbolique, il faut ensuite le résoudre. Si tu veux être robuste, partiellement, parce que conserver la structure d'installation mais avec des liens symboliques pour les répertoires est assez courant chez certains sysadmin (du moins ça l'était quand je me suis retrouvé confronté au problème). Faire la résolution partielle en shell est un exercice amusant.

    La lib libiberty de GNU (utilisée et fournie par gcc par exemple) contient une fonction qui tente de traiter le problème: make_relative_prefix_ignore_links

  5. #5
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    * Windows a qqch du genre de dladdr()
    GetModuleFileName() fait ce travail aussi (mais adieu la portabilité)

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 53
    Points : 37
    Points
    37
    Par défaut
    Merci pour vos réponse.

    Pour le portabilité, je préfèrerai la conserver, mais si je dois l'abandonner ça sera au profit de linux (normalement la plateforme de destination de mon programme).

    Pour situer mon programme, il serrait bien qu'il soit portable : on le met sur une clé usb avec son fichier de config et on peu l'exécuter partout (à condition d'avoir installé les libs boost bien-sur).

    Du coup je vais voir pour passer le chemin du fichier de config en paramètre du programme, avec une valeur par défaut à "$HOME/.monprogramme.conf" (ça existe un equivalent de getenv($HOME) en portable ?)

    Si je veux éviter ça, la seule solution restante est le "/proc/self/exe" si je comprends bien. Dans ce cas, la classe Path de boost Filesystem devrait m'aider pour la résolution des liens symboliques (je suppose, je n'ai jamais utilisé).

    Merci pour toutes ces explications !

  7. #7
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    GetModuleFileName() fait ce travail aussi (mais adieu la portabilité)
    La simple notion de repertoire n'etant pas presente dans la norme, tout ce qui peut en avoir n'est pas strictement conforme. Comme toujours dans ce cas la, il faut encapsuler et laisser le systeme de build choisir la bonne version (je verrai bien le choix entre deux fichiers, un pour Windows, un pour ce qui se reclame de POSIX et dans ce dernier des #ifdef pour utiliser si possible les /proc/self/exe ou equivalent).

Discussions similaires

  1. Commande ftp pour récupérer un répertoire entier
    Par SuperCed dans le forum Développement
    Réponses: 3
    Dernier message: 09/01/2008, 09h06
  2. Comment récupérer le répertoire parent d'un répertoire?
    Par Jayceblaster dans le forum Delphi
    Réponses: 14
    Dernier message: 23/05/2006, 18h38
  3. VB6: récupérer le répertoire d'installation de l'application
    Par getea85 dans le forum Installation, Déploiement et Sécurité
    Réponses: 2
    Dernier message: 28/12/2005, 15h12
  4. [JSP] Récupérer le répertoire courant
    Par dafly dans le forum Servlets/JSP
    Réponses: 4
    Dernier message: 10/06/2004, 11h01
  5. [API win32] Récupérer le répertoire d'un profile
    Par sbeu dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 27/09/2002, 12h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo