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 :

Connaitre le répertoire de l'application ?


Sujet :

C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 54
    Points : 37
    Points
    37
    Par défaut Connaitre le répertoire de l'application ?
    Bonjour,
    Je lance mon application par ligne de commande et j'aimerais connaitre le chemin de l'executable pour sauvegarder mes fichiers.
    Car j'utilise le répertoire courant mais il n'est pas forcement le même que celui de l'exécutable.
    Existe t'il une fonction?

    merci

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Plusieurs moyens:

    En C standard, tu peux avoir la ligne de commande avec les paramètres de main() : argv[0] correspond à la commande du programme.

    Malheureusement, les fonctions d'exécution de programme permettent de choisir les paramètres, le programme risque donc d'avoir été lancé avec un argv[0] erroné ou incomplet...

    Sous Windows, tu as la fonction GetModuleFileName() qui marche très bien (passe-lui NULL comme paramètre HMODULE et elle te renverra le chemin de l'exécutable)

    Sous Unixoïde, aucune idée: Il peut y avoir une fonction spécifique, mais dans ce cas, j'ignore laquelle...

  3. #3
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Médinoc
    Plusieurs moyens:

    En C standard, tu peux avoir la ligne de commande avec les paramètres de main() : argv[0] correspond à la commande du programme.
    La norme dit que argv[0] peut contenir soit
    • "" (une chaine vide)
    • le nom du programme
    • le nom du programme avec le chemin complet

    Ce n'est donc pas une méthode fiable.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Euh... Je ne le trouve pratiquement nulle part.
    ("no manual entry for getpwd" sur deux serveurs unix (HP_UX et FreeBSD), rien sur MSDN, et google qui me conseille getcwd())

    Il y a bien getcwd(), mais...
    Car j'utilise le répertoire courant mais il n'est pas forcement le même que celui de l'exécutable.

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Médinoc
    Euh... Je ne le trouve pratiquement nulle part.
    ("no manual entry for getpwd" sur deux serveurs unix (HP_UX et FreeBSD), rien sur MSDN, et google qui me conseille getcwd())

    Il y a bien getcwd(), mais...
    Car j'utilise le répertoire courant mais il n'est pas forcement le même que celui de l'exécutable.
    Oups c'est ce que je voulais dire (GET Current Working Directory), mais effectivement, ça ne répond pas à la question.

    J'efface.

  6. #6
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut Re: Connaitre le répertoire de l'application ?
    Citation Envoyé par LeBigornot
    ...j'aimerais connaitre le chemin de l'executable pour sauvegarder mes fichiers.
    Car j'utilise le répertoire courant mais il n'est pas forcement le même que celui de l'exécutable.
    Pour acceder au repertoire courant, toujours POSIX par contre, une des trois pourraient faire l'affaire

    getcwd
    getwd (BSD)
    get_current_working_dir_name (extension GNU)

    Si ca peut aider

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    ben non, ça peut pas aider: On cherche le répertoire du programme, pas le répertoire courant...

  8. #8
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Points : 1 067
    Points
    1 067
    Par défaut
    Sous linux, c'est moins évident :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Si argv[0] est vide alors
        afficher "je ne sais pas faire"
        Quitter
    Sinon si argv[0] commence par '/'
        cheminAbsolu <- argv[0]
    Sinon si argv[0] contient un '/'
        cheminAbsolu <- getcwd() (+'/') + argv[0]
    Sinon
        nomExe <- argv[0]
        trouve <- FAUX
        Pour chaque nom de répertoire présent dans la variable PATH
            cheminAbsolu <- repertoireDePATH (+'/') + nomExe
            Si cheminAbsolu correspond à un fichier exécutable
                trouve <- VRAI
                Sortir de la boucle
            Fin si
        Fin pour
        Si pas trouve
            afficher "pas trouve"
            Quitter
        Fin si
    Fin si
    vraiCheminAbsolu <- cheminCanonique(cheminAbsolu)
    Pour obtenir le chemin canonique, la fonction realpath() fait déjà le travail.
    Si vous avez plus simple, je prends.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 54
    Points : 37
    Points
    37
    Par défaut
    Merci de vos réponses mais je n'y trouve malheureusement pas moj bonheur
    Donc je vais vous expliquer plus en détail mon problème peut être que vous m'y apporterer une autre solution:
    C'est un programme C sous Linux devant s'executer si possible sur toutes les plateformes Unix.
    Pour le lancer automatiquement j'utilise la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    su - toto-c "/apps/program/monprog/monprog -b"
    Dans mon prog j'écris des fichiers et j'aimerais les écrire dans le repertoire "monrpog" et pas à la racine.

    Merci

  10. #10
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par Médinoc
    ben non, ça peut pas aider: On cherche le répertoire du programme, pas le répertoire courant...
    Bin à ce que j'ai pu lire, getcwd récupère le répertoire courant du processus en cours d'execution, ce qui devrait faire l'affaire dans ce cas précis ... je suppose ! Sinon je ne vois pas ce qu'il cherche !

  11. #11
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par LeBigornot
    Pour le lancer automatiquement j'utilise la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    su - toto-c "/apps/program/monprog/monprog -b"
    Dans mon prog j'écris des fichiers et j'aimerais les écrire dans le repertoire "monrpog" et pas à la racine.
    Hé, dans ce cas bien précis, utiliser un chemin relatif suffirait amplement, je ne vois pas en quoi vous vous compliquez la vie, tu donnes juste le nom du fichier quand tu veut en créer un puis il se met automatiquement dans le répertoire .../monprog/ !

  12. #12
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par LeBigornot
    Merci de vos réponses mais je n'y trouve malheureusement pas moj bonheur
    Donc je vais vous expliquer plus en détail mon problème peut être que vous m'y apporterer une autre solution
    Pour ma part, je pense avoir bien compris le problème. Inutile de l'exposer de nouveau.
    Qu'est-ce qui ne vous plait pas dans ma solution ? Est-ce qu'elle ne fonctionne pas ? L'avez-vous essayée ?
    Si vous trouvez une fonction toute faite (et portable) qui permet de se passer de ma solution : n'hésitez pas à m'en faire part, cela me permettra de simplifier certains de mes programmes.

  13. #13
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par David.Schris
    Si vous trouvez une fonction toute faite (et portable) qui permet de se passer de ma solution : n'hésitez pas à m'en faire part, cela me permettra de simplifier certains de mes programmes.
    Le probleme de LeBigornot n'est pas simple a resoudre de facon portable. De toute facon, devoir resoudre un tel probleme est symptomatique d'une conception mal pensee.
    J'imagine que s'il a besoin de connaitre le chemin complet vers son executable, c'est qu'il souhaite trouver un fichier de configuration, d'initialisation, ou de donnees. Il est beaucoup plus robuste d'utiliser une variable d'environnement dans ces conditions (en environnement multi-utilisateur, par exemple, le fichier de configuration va varier d'un utilisateur a l'autre, et le repertoire contenant l'executable n'est certainement pas disponible en ecriture a tous les utilisateurs).

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 54
    Points : 37
    Points
    37
    Par défaut
    Citation Envoyé par DaZumba
    Le probleme de LeBigornot n'est pas simple a resoudre de facon portable. De toute facon, devoir resoudre un tel probleme est symptomatique d'une conception mal pensee.
    J'imagine que s'il a besoin de connaitre le chemin complet vers son executable, c'est qu'il souhaite trouver un fichier de configuration, d'initialisation, ou de donnees. Il est beaucoup plus robuste d'utiliser une variable d'environnement dans ces conditions (en environnement multi-utilisateur, par exemple, le fichier de configuration va varier d'un utilisateur a l'autre, et le repertoire contenant l'executable n'est certainement pas disponible en ecriture a tous les utilisateurs).
    j'aime bien ce concept de conception mal pensée.
    En gros tu penses qu'aller lire une variable d'environement dans laquel l'utilisateur aura rentré le chemin d'acces (ou a l'installation) est suffisant ? C'est vrai que cela simplifierait problème...

    Même si mon problème n'est pas clair je ne suis pas issu du monde Unix et je ne connais pas la façon "standard" de faire cela.

    Quitte a lire une variable d'environement pourquoi pas stocker le répertoire d'install dans mon fichier de configuration (passé en paramètre a l'application) alors ?


    Citation Envoyé par David.Schris
    Pour ma part, je pense avoir bien compris le problème. Inutile de l'exposer de nouveau.
    Qu'est-ce qui ne vous plait pas dans ma solution ? Est-ce qu'elle ne fonctionne pas ? L'avez-vous essayée ?
    Si vous trouvez une fonction toute faite (et portable) qui permet de se passer de ma solution : n'hésitez pas à m'en faire part, cela me permettra de simplifier certains de mes programmes.
    Exact ta solution est celle que j'utilise en y ayant rajouter le cas ou argv[0] commence par './'.
    Cela marche très bien sur mon Linux de dev mais j'ai peur du résultat une fois mon application lancée sur d'autres systèmes (AIX en particuier).

    Merci

  15. #15
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par LeBigornot
    En gros tu penses qu'aller lire une variable d'environement dans laquel l'utilisateur aura rentré le chemin d'acces (ou a l'installation) est suffisant ? C'est vrai que cela simplifierait problème...

    Même si mon problème n'est pas clair je ne suis pas issu du monde Unix et je ne connais pas la façon "standard" de faire cela.

    Quitte a lire une variable d'environement pourquoi pas stocker le répertoire d'install dans mon fichier de configuration (passé en paramètre a l'application) alors ?
    Il y a en effet quelques solutions typiques dans le monde Unix:
    - un fichier de configuration a un endroit connu. C'est le principe utilise par les shells, par exemple, qui font lire des "runcom" files dans le home directory (.kshrc par exemple) ou dans un autre repertoire connu et fixe.
    - une variable d'environnement qui donne la valeur du repertoire. Cette variable peut etre ajoutee a l'installation, ou l'application est "emballee" dans un script qui place cette variable.

    Faire comme cela a plusieurs avantages:
    - c'est simple
    - cela donne une certaine liberte a l'utilisateur
    - cela assure que le repertoire est accessible en ecriture (si ton application est installee dans /usr/bin ou /usr/local/bin, tu ne peux pas mettre a jour tes configurations)
    - c'est conforme a la philosophie Unix.

  16. #16
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 54
    Points : 37
    Points
    37
    Par défaut
    Citation Envoyé par DaZumba
    Il y a en effet quelques solutions typiques dans le monde Unix:
    - un fichier de configuration a un endroit connu. C'est le principe utilise par les shells, par exemple, qui font lire des "runcom" files dans le home directory (.kshrc par exemple) ou dans un autre repertoire connu et fixe.
    - une variable d'environnement qui donne la valeur du repertoire. Cette variable peut etre ajoutee a l'installation, ou l'application est "emballee" dans un script qui place cette variable.

    Faire comme cela a plusieurs avantages:
    - c'est simple
    - cela donne une certaine liberte a l'utilisateur
    - cela assure que le repertoire est accessible en ecriture (si ton application est installee dans /usr/bin ou /usr/local/bin, tu ne peux pas mettre a jour tes configurations)
    - c'est conforme a la philosophie Unix.
    Cette solution me plait beaucoup merci
    Voila comment rester conforme et ne pas faire de chose inutile alors
    Merci encore

  17. #17
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par LeBigornot
    Exact ta solution est celle que j'utilise en y ayant rajouter le cas ou argv[0] commence par './'.
    Un ajout inutile à mon sens [1] car quand argv[0] commence par './' il entre dans la catégorie, déjà traitée, des argv[0] contenant un '/'.
    Tu me diras peut-être : "oui, mais quand on colle le répertoire courant devant on obtient un truc comme '/repertoire/courant/./nomAppli' et ce n'est pas beau". Mais ce cas aussi est déjà traité par l'algo. que j'ai donné puisqu'il se termine par "vraiCheminAbsolu <- cheminCanonique(cheminAbsolu)"...
    D'après ce que j'ai compris, tu peux donc (légèrement) simplifier ton algo.

    Citation Envoyé par LeBigornot
    Cela marche très bien sur mon Linux de dev mais j'ai peur du résultat une fois mon application lancée sur d'autres systèmes (AIX en particuier).
    Là, tu as peut-être raison d'avoir peur.
    Dans ton "stdlib.h" (sous linux) tu devrais pouvoir lire quelque-chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #ifdef  __USE_GNU
    /* Return a malloc'd string containing the canonical absolute name of the
       named file.  The last file name component need not exist, and may be a
       symlink to a nonexistent file.  */
    extern char *canonicalize_file_name (__const char *__name) __THROW;
    #endif
     
    #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
    /* Return the canonical absolute name of file NAME.  The last file name
       component need not exist, and may be a symlink to a nonexistent file.
       If RESOLVED is null, the result is malloc'd; otherwise, if the canonical
       name is PATH_MAX chars or more, returns null with `errno' set to
       ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, returns the
       name in RESOLVED.  */
    extern char *realpath (__const char *__restrict __name,
                           char *__restrict __resolved) __THROW;
    #endif
    Donc, cela s'annonce a priori plutôt bien pour realpath() sous AIX.
    Une petite recherche dans la doc. d'AIX permet de vérifier que cette fonction est bien disponible (http://publib.boulder.ibm.com/infoce...2/realpath.htm).
    Mais en poussant un peu plus loin, on tombe sur des choses du style :
    Citation Envoyé par http://www.flamingspork.com/portawiki/index.php/Realpath
    realpath(3) is known to be broken on at least some versions of the following platforms:
    • AIX
    • NeXTStep
    You cannot reliably detect this at configure time unless you have root privs.
    On trouve aussi des discussions concernant le problème de l'implémentation de realpath() sous AIX :
    Citation Envoyé par http://lists.gnu.org/archive/html/bug-make/2005-07/msg00003.html
    I've built make-3.81beta3 with the IBM C compiler v7 and GCC 3.4.3.
    All tests pass except functions/realpath
    Mais rien de grave en fait : c'est une fonction simple à implémenter.
    D'ailleurs, utiliser une version personnelle de realpath() semble être la solution utilisée dans certains cas :
    Citation Envoyé par http://lists.gnu.org/archive/html/bug-make/2005-07/msg00005.html
    > Does GNU make use libc's realpath or its own on AIX? (Check the test for
    > realpath in config.log.) I am pretty sure it's AIX's realpath since I
    > just tested GNU make's own fallback implementation and it work fine.
    > So this is really a bug in AIX, not GNU make.

    Yep, that's it. Thanks.
    Cela peut sembler lourd d'inclure une version "de secours" d'une fonction, mais c'est parfois (souvent?) le prix à payer pour avoir une application portable.
    Il m'est par exemple arrivé d'inclure des implémentations de strlcat() et strlcpy() dans des projets pour qu'ils puissent être compilés sous de relativement anciennes versions de linux...mais cela fonctionne (le script de configuration a son importance dans ces cas).

    Pour le reste, je ne pense pas qu'il y ait de réels problèmes. Merci de nous tenir au courant si il y en a, c'est toujours bon à savoir.

    Citation Envoyé par LeBigornot
    Merci
    A bientôt

    [1] : et pas seulement à mon sens d'ailleurs : j'ai vu cette solution utilisée ailleurs...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 27/04/2011, 21h01
  2. Connaitre le repertoire de l'application
    Par dr23fr dans le forum Général Java
    Réponses: 3
    Dernier message: 01/06/2006, 19h15
  3. [VB.NET] Répertoire courant mon application
    Par Sytchev3 dans le forum Windows Forms
    Réponses: 4
    Dernier message: 30/05/2006, 09h08
  4. Connaitre le répertoire courant
    Par SheikYerbouti dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 22/03/2006, 13h50
  5. [Débutant] Connaitre le répertoire courant
    Par The Wretched dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 16/06/2005, 12h51

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