c++ libmmd - Comment puis-je obtenir par programme la version d'un fichier DLL ou EXE?




manuellement msvcp140 (7)

J'ai besoin d'obtenir la version du produit et la version du fichier pour un fichier DLL ou EXE en utilisant les API natives Win32 en C ou C ++. Je ne cherche pas la version de Windows, mais les numéros de version que vous voyez en cliquant-droit sur un fichier DLL, en sélectionnant "Propriétés", puis en regardant l'onglet "Détails". Ceci est généralement un numéro de version en pointillés en quatre parties xxxx


Answers

Vous obtenez cette information en utilisant les API d'informations de version . Voici un exemple:

void PrintFileVersion( TCHAR *pszFilePath )
{
    DWORD               dwSize              = 0;
    BYTE                *pbVersionInfo      = NULL;
    VS_FIXEDFILEINFO    *pFileInfo          = NULL;
    UINT                puLenFileInfo       = 0;

    // Get the version information for the file requested
    dwSize = GetFileVersionInfoSize( pszFilePath, NULL );
    if ( dwSize == 0 )
    {
        printf( "Error in GetFileVersionInfoSize: %d\n", GetLastError() );
        return;
    }

    pbVersionInfo = new BYTE[ dwSize ];

    if ( !GetFileVersionInfo( pszFilePath, 0, dwSize, pbVersionInfo ) )
    {
        printf( "Error in GetFileVersionInfo: %d\n", GetLastError() );
        delete[] pbVersionInfo;
        return;
    }

    if ( !VerQueryValue( pbVersionInfo, TEXT("\\"), (LPVOID*) &pFileInfo, &puLenFileInfo ) )
    {
        printf( "Error in VerQueryValue: %d\n", GetLastError() );
        delete[] pbVersionInfo;
        return;
    }

    // pFileInfo->dwFileVersionMS is usually zero. However, you should check
    // this if your version numbers seem to be wrong

    printf( "File Version: %d.%d.%d.%d\n",
        ( pFileInfo->dwFileVersionLS >> 24 ) & 0xff,
        ( pFileInfo->dwFileVersionLS >> 16 ) & 0xff,
        ( pFileInfo->dwFileVersionLS >>  8 ) & 0xff,
        ( pFileInfo->dwFileVersionLS >>  0 ) & 0xff
        );

    // pFileInfo->dwProductVersionMS is usually zero. However, you should check
    // this if your version numbers seem to be wrong.

    printf( "Product Version: %d.%d.%d.%d\n",
        ( pFileInfo->dwProductVersionLS >> 24 ) & 0xff,
        ( pFileInfo->dwProductVersionLS >> 16 ) & 0xff,
        ( pFileInfo->dwProductVersionLS >>  8 ) & 0xff,
        ( pFileInfo->dwProductVersionLS >>  0 ) & 0xff
        );
}

Toutes ces solutions ne fonctionnaient pas correctement (avec mon système). J'ai découvert que chacune des quatre parties du numéro de version sont enregistrées en tant que valeur de 16 bits.

Les deux premiers nombres sont enregistrés dans DWORD dwFileVersionMS 32 bits et les deux autres dans dwFileVersionLS. J'ai donc édité votre code dans la section de sortie comme ceci:

    TRACE( "File Version: %d.%d.%d.%d\n",
        ( pFileInfo->dwFileVersionMS >> 16 ) & 0xffff,
        ( pFileInfo->dwFileVersionMS >>  0 ) & 0xffff,
        ( pFileInfo->dwFileVersionLS >> 16 ) & 0xffff,
        ( pFileInfo->dwFileVersionLS >>  0 ) & 0xffff
        );

Et ça fonctionne parfaitement. La sortie est formatée comme sur mon système:

major.minor.build.revision



Ce code affiche correctement les numéros de version du fichier.

( pFileInfo->dwFileVersionMS >> 16 ) & 0xff,
( pFileInfo->dwFileVersionMS >> 0 ) & 0xff,
( pFileInfo->dwFileVersionLS >>  16 ) & 0xff,
( pFileInfo->dwFileVersionLS >>  0 ) & 0xff);


Comme aucune des réponses ne le mentionne ... J'ai découvert que vous devez faire des calculs différents selon que vous utilisez des systèmes 32 ou 64 bits . C'est pourquoi vous trouvez que certaines réponses dans cette question fonctionnent pour vous, et d'autres pas.

Voici un exemple de mise en œuvre que j'utilise:

if(IsWow64())
{
        // 64 bit build
        major =     (verInfo->dwProductVersionMS >> 16) & 0xffff;
        minor =     (verInfo->dwProductVersionMS >>  0) & 0xffff;
        revision =  (verInfo->dwProductVersionLS >> 16) & 0xffff;
        build =     (verInfo->dwProductVersionLS >>  0) & 0xffff;
} 
else
{
        // 32 bit build
        major =     HIWORD(verInfo->dwProductVersionMS);
        minor =     LOWORD(verInfo->dwProductVersionMS);
        revision =  HIWORD(verInfo->dwProductVersionLS);
        build =     LOWORD(verInfo->dwProductVersionLS);
}

Et l'implémentation de IsWow64 (pas la mienne):

typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process;

BOOL IsWow64()
{
    BOOL bIsWow64 = FALSE;

    //IsWow64Process is not available on all supported versions of Windows.
    //Use GetModuleHandle to get a handle to the DLL that contains the function
    //and GetProcAddress to get a pointer to the function if available.

    fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
        GetModuleHandle(TEXT("kernel32")),"IsWow64Process");

    if(NULL != fnIsWow64Process)
    {
        if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
        {
            // Handle error...
        }
    }
    return bIsWow64;
}

J'aime vraiment les réponses de Darren Cook et stacker à ce problème. J'étais en train de jeter un coup d'œil sur mes pensées, mais je crois que mon approche est trop en forme pour ne pas partir d'ici.

En bref, vous avez identifié un algorithme pour déterminer qu'un logo Coca-Cola est présent à un endroit particulier dans l'espace. Vous essayez maintenant de déterminer, pour des orientations arbitraires et des facteurs d'échelle arbitraires, une heuristique appropriée pour distinguer les canettes de Coca-Cola des autres objets, y compris: bouteilles , panneaux d'affichage , publicités et accessoires Coca-Cola associés à ce logo iconique. Vous n'avez pas appelé beaucoup de ces cas supplémentaires dans votre énoncé de problème, mais je pense qu'ils sont essentiels au succès de votre algorithme.

Le secret ici est de déterminer quelles caractéristiques visuelles un can contient, ou, à travers l'espace négatif, quelles caractéristiques sont présentes pour les autres produits de Coke qui ne sont pas présents pour les canettes. À cette fin, la première réponse actuelle esquisse une approche de base pour sélectionner «peut» si et seulement si «bouteille» n'est pas identifié, soit par la présence d'un bouchon de bouteille, liquide, ou d'autres heuristiques visuelles similaires.

Le problème est que cela tombe en panne. Une bouteille peut, par exemple, être vide et ne pas présenter de bouchon, ce qui conduit à un faux positif. Ou, ce pourrait être une bouteille partielle avec des fonctionnalités supplémentaires mutilées, conduisant à nouveau à une fausse détection. Inutile de dire que ce n'est pas élégant, ni efficace pour nos besoins.

À cette fin, les critères de sélection les plus corrects pour les canettes semblent être les suivants:

  • La forme de la silhouette de l'objet, telle que vous l'avez esquissée dans votre question , est-elle correcte? Si oui, +1.
  • Si nous supposons la présence de lumière naturelle ou artificielle, détecte-t-on un contour de chrome à la bouteille qui indique si elle est faite d'aluminium? Si oui, +1.
  • Déterminons-nous que les propriétés spéculaires de l'objet sont correctes, par rapport à nos sources lumineuses ( lien vidéo illustratif sur la détection de la source lumineuse )? Si oui, +1.
  • Pouvons-nous déterminer d'autres propriétés de l'objet qui l'identifient comme une boîte, y compris, mais sans s'y limiter, l'inclinaison de l'image topologique du logo, l'orientation de l'objet, la juxtaposition de l'objet (par exemple, sur une surface plane comme une table ou dans le contexte d'autres boîtes), et la présence d'une tirette? Si oui, pour chacun, +1.

Votre classification pourrait alors ressembler à ceci:

  • Pour chaque correspondance candidate, si la présence d'un logo Coca Cola a été détectée, tracez une bordure grise.
  • Pour chaque match sur +2, tracez une bordure rouge.

Ceci met visuellement en évidence chez l'utilisateur ce qui a été détecté, en mettant l'accent sur les positifs faibles qui peuvent, correctement, être détectés comme des boîtes mutilées.

La détection de chaque propriété comporte une complexité temporelle et spatiale très différente, et pour chaque approche, un passage rapide sur http://dsp.stackexchange.com est plus que raisonnable pour déterminer l'algorithme le plus correct et le plus efficace pour vos besoins. Mon intention ici est, purement et simplement, de souligner que détecter si quelque chose est un peut invalider une petite partie de l'espace de détection candidat n'est pas la solution la plus robuste ou efficace à ce problème, et idéalement, vous devriez prendre les mesures appropriées en conséquence.

Et bon, félicitations pour l'article de Hacker News! Dans l'ensemble, c'est une très bonne question digne de la publicité qu'elle a reçue. :)





c++ winapi dll version exe