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

Windows Discussion :

Problème de link bizarre LNK2019 dans une application c++/API Windows


Sujet :

Windows

  1. #1
    Membre du Club Avatar de masterx_goldman
    Inscrit en
    Mai 2008
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 164
    Points : 51
    Points
    51
    Par défaut Problème de link bizarre LNK2019 dans une application c++/API Windows
    Bonjour à tous,
    Je développe un programme en C++/API Windows, ce programme va traiter le lancement de process, communication interprocess(bref c'est pas très important ce détail).
    J'ai téléchargé une classe qui peut m'aider à faire ce que je veux dans ce contexte, le lien vers code project est le suivant:
    http://www.codeproject.com/KB/vista-...#_Toc230522882

    1) j'ai crée une application win32 sous Visual Studio 2008
    (y'a rien encore dans le main de cette application ), le voilà le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include "monprog.h"
    #include "ProcessStarter.h"
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	return 0;
    }
    code de la classe :

    "ProcessStarter.h"
    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
    #ifndef _PROCESS_STARTER_H_
    #define _PROCESS_STARTER_H_
    
    #include "windows.h"
    #include "winbase.h"
    
    
    #include <string>
    
    class ProcessStarter
    {
    public:
        ProcessStarter(const std::string& processPath, const std::string& arguments = "");
        PHANDLE GetCurrentUserToken();
        BOOL Run();
        
    private:
        std::string processPath_;
        std::string arguments_;
    };
    
    #endif //_PROCESS_STARTER_H_
    "ProcessStarter.cpp"
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    #include "ProcessStarter.h"
    
    #include "userenv.h"
    #include "wtsapi32.h"
    #include "winnt.h"
    
    ProcessStarter::ProcessStarter(const std::string& processPath, const std::string& arguments)
    : processPath_(processPath), arguments_(arguments)
    {
    
    }
    
    PHANDLE ProcessStarter::GetCurrentUserToken()
    {
        PHANDLE currentToken = 0;
        PHANDLE primaryToken = 0;
    
        int dwSessionId = 0;
        PHANDLE hUserToken = 0;
        PHANDLE hTokenDup = 0;
    
        PWTS_SESSION_INFO pSessionInfo = 0;
        DWORD dwCount = 0;
    
        WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);
    
        int dataSize = sizeof(WTS_SESSION_INFO);
    
        for (DWORD i = 0; i < dwCount; ++i)
        {
            WTS_SESSION_INFO si = pSessionInfo[i];
            if (WTSActive == si.State)
            {
                dwSessionId = si.SessionId;
                break;
            }
        }
    
        WTSFreeMemory(pSessionInfo);
    
        BOOL bRet = WTSQueryUserToken(dwSessionId, currentToken);
        int errorcode = GetLastError();
        if (bRet == false)
        {
            return 0;
        }
    
        bRet = DuplicateTokenEx(currentToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, primaryToken);
        errorcode = GetLastError();
        if (bRet == false)
        {
            return 0;
        }
    
        return primaryToken;
    }
    
    BOOL ProcessStarter::Run()
    {
        PHANDLE primaryToken = GetCurrentUserToken();
        if (primaryToken == 0)
        {
            return FALSE;
        }
        STARTUPINFO StartupInfo;
        PROCESS_INFORMATION processInfo;
        StartupInfo.cb = sizeof(STARTUPINFO);
    
        SECURITY_ATTRIBUTES Security1;
        SECURITY_ATTRIBUTES Security2;
    
        std::string command = "\"" + processPath_ + "\"";
        if (arguments_.length() != 0)
        {
            command += " " + arguments_;
        }
    
        void* lpEnvironment = NULL;
        BOOL resultEnv = CreateEnvironmentBlock(&lpEnvironment, primaryToken, FALSE);
        if (resultEnv == 0)
        {                                
            long nError = GetLastError();                                
        }
    
        BOOL result = CreateProcessAsUser(primaryToken, 0, (LPSTR)(command.c_str()), &Security1, &Security2, FALSE, CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, lpEnvironment, 0, &StartupInfo, &processInfo);
    
        DestroyEnvironmentBlock(lpEnvironment);
        CloseHandle(primaryToken);
        return result;
    }
    alors quand je fais le build de mon application:
    1) Quand je compile en MultiByte(Utiliser le jeu de caractères multioctet (MBCS)), je reçois 6 erreurs de link qui sont les suivantes

    Erreur 1 error LNK2019: symbole externe non résolu _WTSQueryUserToken@8 référencé dans la fonction "public: void * * __thiscall ProcessStarter::GetCurrentUserToken(void)" (?GetCurrentUserToken@ProcessStarter@@QAEPAPAXXZ) ProcessStarter.obj monprog

    Erreur 2 error LNK2019: symbole externe non résolu _WTSFreeMemory@4 référencé dans la fonction "public: void * * __thiscall ProcessStarter::GetCurrentUserToken(void)" (?GetCurrentUserToken@ProcessStarter@@QAEPAPAXXZ) ProcessStarter.obj monprog

    Erreur 3 error LNK2019: symbole externe non résolu _WTSEnumerateSessionsA@20 référencé dans la fonction "public: void * * __thiscall ProcessStarter::GetCurrentUserToken(void)" (?GetCurrentUserToken@ProcessStarter@@QAEPAPAXXZ) ProcessStarter.obj monprog
    Erreur 4 error LNK2019: symbole externe non résolu __imp__DestroyEnvironmentBlock@4 référencé dans la fonction "public: int __thiscall ProcessStarter::Run(void)" (?Run@ProcessStarter@@QAEHXZ) ProcessStarter.obj monprog

    Erreur 5 error LNK2019: symbole externe non résolu __imp__CreateEnvironmentBlock@12 référencé dans la fonction "public: int __thiscall ProcessStarter::Run(void)" (?Run@ProcessStarter@@QAEHXZ) ProcessStarter.obj monprog

    Erreur 6 fatal error LNK1120: 5 externes non résolus E:\Programmes\monprog\Debug\monprog.exe monprog
    2) Quand je compile en Unicode(Utiliser le jeu de caractères Unicode), je reçois une seule erreur qui est la suivante:
    Erreur 1 error C2664: 'CreateProcessAsUserW'*: impossible de convertir le paramètre 3 de 'LPSTR' en 'LPWSTR' e:\programmes\monprog\monprog\processstarter.cpp 86 monprog
    ça me paraît bizarre ces erreurs car je peux trouver les headers des fonctions qui semblent causer problème ici quand j'utilise l'utilitaire de Visual Studio "Atteindre la définition"

    J'attends vos réponses et merci pour tout type d'aide

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Quand tu compiles en Unicode, tu n'as pas d'erreurs de link parce que tu ne vas pas jusqu'au link.

    Tu dois utiliser des #defines (ou des fonctions surchargées) pour obtenir une chaîne unicode à partir de command.

    De plus, utilise explicitement const_cast<> au lieu d'un cast C-style en LPSTR, s'il te plait, merci.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Tu as ajouté la librairie "Wtsapi32.lib" dans les dépendances de ton projet ?
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  4. #4
    Membre du Club Avatar de masterx_goldman
    Inscrit en
    Mai 2008
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 164
    Points : 51
    Points
    51
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Tu as ajouté la librairie "Wtsapi32.lib" dans les dépendances de ton projet ?
    J'allais l'écrire aujourd'hui
    En faite, Quand j'ai ajouté les lib nécessaires, le, problème a été résolu , en faite, les headers ont été référencées mais pas les lib, donc je suis allé regarder sur msdn les lib nécessaires pour chacune des fonctions qui semblait causer problème et hop le tour a été joué

  5. #5
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par masterx_goldman Voir le message
    J'allais l'écrire aujourd'hui
    En faite, Quand j'ai ajouté les lib nécessaires, le, problème a été résolu , en faite, les headers ont été référencées mais pas les lib, donc je suis allé regarder sur msdn les lib nécessaires pour chacune des fonctions qui semblait causer problème et hop le tour a été joué
    J'ai tendance à résoudre ce problème à la source pour mes propres librairies, en rajoutant ce genre de code en tête du header principal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #ifdef _MSC_VER // Seulement sous Visual.
    	#ifndef _DEBUG
    		#pragma comment(lib,"monnomdelibrelease")
    	#else
    		#pragma comment(lib,"monnomdelibdebug")
    	#endif
    #endif
    Zéro configuration dans le projet utilisateur, link automatique de la version Debug ou Release en fonction du besoin, pépère...
    Microsoft l'utilise dans quelques entêtes, mais hélas, pas tous, c'est dommage.

    De même, quand j'ai des dépendances statiques (c'est à dire une librairie statique A requérant une autre librairie statique B, donc édition de liens non résolue à la compilation de A mais seulement lorsque l'on fait un EXE ou une DLL utilisant A), j'inclus les #pragma adéquats pour les dépendances afin d'avoir, au maximum possible, des librairies demandant zéro configuration au niveau du projet pour être utilisées dans Visual Studio.
    Pour les DLL, je mets dans l'entête principal (celui définissant les macros d'exportation) le link automatique de la librairie d'importation, et dans un entête privé les dépendances statiques.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  6. #6
    Membre du Club Avatar de masterx_goldman
    Inscrit en
    Mai 2008
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 164
    Points : 51
    Points
    51
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    J'ai tendance à résoudre ce problème à la source pour mes propres librairies, en rajoutant ce genre de code en tête du header principal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #ifdef _MSC_VER // Seulement sous Visual.
    	#ifndef _DEBUG
    		#pragma comment(lib,"monnomdelibrelease")
    	#else
    		#pragma comment(lib,"monnomdelibdebug")
    	#endif
    #endif
    Zéro configuration dans le projet utilisateur, link automatique de la version Debug ou Release en fonction du besoin, pépère...
    Microsoft l'utilise dans quelques entêtes, mais hélas, pas tous, c'est dommage.

    De même, quand j'ai des dépendances statiques (c'est à dire une librairie statique A requérant une autre librairie statique B, donc édition de liens non résolue à la compilation de A mais seulement lorsque l'on fait un EXE ou une DLL utilisant A), j'inclus les #pragma adéquats pour les dépendances afin d'avoir, au maximum possible, des librairies demandant zéro configuration au niveau du projet pour être utilisées dans Visual Studio.
    Pour les DLL, je mets dans l'entête principal (celui définissant les macros d'exportation) le link automatique de la librairie d'importation, et dans un entête privé les dépendances statiques.
    pour les réponses
    Quand tu sera dispo, merci de nous rejoindre sur mon post suivant http://www.developpez.net/forums/d80...p/#post4630418

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

Discussions similaires

  1. Problème arrêt de certains thread dans une application
    Par adteulade dans le forum Android
    Réponses: 7
    Dernier message: 24/04/2012, 10h22
  2. Problème de link dans une application c++/CLI
    Par moooona dans le forum C++/CLI
    Réponses: 3
    Dernier message: 09/01/2012, 10h01
  3. Problème de gestion de suppression dans une application web dynamic data
    Par mo5andes dans le forum Développement Web avec .NET
    Réponses: 4
    Dernier message: 21/06/2010, 10h35
  4. Problème d'envoi de mail dans une application web
    Par BNacer dans le forum API standards et tierces
    Réponses: 7
    Dernier message: 11/12/2009, 22h22
  5. [Forum] Login dans une Application PHP
    Par ChrisColumbus dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 3
    Dernier message: 19/11/2006, 02h49

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