[C++] Versionsinfo auslesen

Lupo

Lt. Junior Grade
Registriert
Feb. 2003
Beiträge
407
hallo,
ich verusche aus einer exe datei die versionsinfo auszulesen. leider gelingt mir das noch nicht so recht. kann mir jemand evtl noch einen tipp geben ?
hier der code soweit:

#include<iostream>
#include<afx.h>
#include<string>

using namespace std;

CString GetFileVersionString(const CString& FileName)
{
// prüfen ob überhaupt Info da sind
DWORD nSize = GetFileVersionInfoSize(FileName, 0);
CString Result = "";

if (nSize)
{
char *pInfo = new char[nSize];

// Versionsinfo auslesen
GetFileVersionInfo(FileName, 0, nSize, pInfo);

VS_FIXEDFILEINFO *FileInfo;
UINT uLen;

// Root-Information auslesen
VerQueryValue(pInfo, "\\", (void**) &FileInfo, (PUINT) &uLen);


// Versionsnummer bilden
Result.Format("%d.%d.%d.%d",
HIWORD(FileInfo->dwProductVersionMS),
LOWORD(FileInfo->dwProductVersionMS),
HIWORD(FileInfo->dwProductVersionLS),
LOWORD(FileInfo->dwProductVersionLS));

// Speicher freigeben (ich bin mir nicht sicher, aber vermutlich zeigt FileInfo auf diesen Datenbereich)
delete [] pInfo;
}

return Result;
}

int main (void)
{

CString FileVersion = "Version: " + GetFileVersionString(":\\Dokumente und Einstellungen\\Hereich\\Desktop.test.exe");

return 0;
}


fehlermeldung:

c:\doku......d\dsyd.cpp(11) : error C2664: 'GetFileVersionInfoSizeA' : Konvertierung des Parameters 1 von 'const class CString' in 'char *' nicht moeglich
Kein benutzerdefinierter Konvertierungsoperator verfuegbar, der diese Konvertierung durchfuehren kann, oder der Operator kann nicht aufgerufen werden
c:\doku....\dsyd.cpp(19) : error C2664: 'GetFileVersionInfoA' : Konvertierung des Parameters 1 von 'const class CString' in 'char *' nicht moeglich
Kein benutzerdefinierter Konvertierungsoperator verfuegbar, der diese Konvertierung durchfuehren kann, oder der Operator kann nicht aufgerufen werden
Fehler beim Ausführen von cl.exe.

dsyd.obj - 2 Fehler, 0 Warnung(en)c:\dokumente und
 
Der Fehler steht doch im Klartext da. GetFileVersionInfo erwartet einen char*. CString hat aber nur eine Konvertierungsfunktion nach const char*. Das const kann der Compiler nicht einfach entfernen (und du solltest das genauso wenig).

Warum allerdings ein veränderbarer String benötigt wird, ist mir unklar.

Also: Leg einen char-Buffer an und kopier den String mit strcpyn oder memcpy da rein und ruf dann die Funktion auf.
 
meinst du so ? ( habe den quelltext etwas abgespeckt)


#include<iostream>
#include<afx.h>
#include<cstring>

using namespace std;

CString GetFileVersionString(const CString FileName)
{
CString Result = "";

GetFileVersionInfo(FileName,0,0,0);

VS_FIXEDFILEINFO *FileInfo;
UINT uLen;


VerQueryValue(0, "\\", (void**) &FileInfo, (PUINT) &uLen);


Result.Format("%d.%d.%d.%d",
HIWORD(FileInfo->dwProductVersionMS),
LOWORD(FileInfo->dwProductVersionMS),
HIWORD(FileInfo->dwProductVersionLS),
LOWORD(FileInfo->dwProductVersionLS));

cout << Result;

return Result;
}

int main (void)
{
char namefile[100];

string name(":\\Dokumente und Einstellungen\\Hereich\\Desktop.test.exe");

strcpy(namefile,name.c_str());

CString FileVersion = "Version: " + GetFileVersionString(namefile);


return 0;
}


leider tritt der gleiche fehler weiterhin auf .
 
Hallo Lupo,

Du verwendest drei verschiedene stringtypen. Das ist ziemlich oversized.
Verwende doch einfach char* für die Übergabe und wenn Dir CString gefällt, dann lass den als Rückgabetyp.

Code:
CString GetFileVersionString(char* apFileName)
{
CString lResult;

  ...

return lResult;
}

int main (void)
{
  CString FileVersion = GetFileVersionString("C:\\Dokumente und Einstellungen\\Hereich\\Desktop\\test.exe");

  return 0;
}

MfG

Arnd
 
hab es jetzt hinbekommen. wenn evtl jemand noch den code braucht hier ist er:


#include<iostream>
#include<afx.h>
#include<string>


using namespace std;


CString GetFileVersionString(const CString &FileName)
{

char* fname_1 = new char [FileName.Length +1];
strcpy(fname_1,FileName);

// prüfen ob überhaupt Info da sind
DWORD nSize = GetFileVersionInfoSize(fname_1, 0);
CString Result = "";

if (nSize)
{
char *pInfo = new char[nSize];

// Versionsinfo auslesen
GetFileVersionInfo(fname_1, 0, nSize, pInfo);

VS_FIXEDFILEINFO *FileInfo;
UINT uLen;

// Root-Information auslesen
VerQueryValue(pInfo, "\\", (void**) &FileInfo, (PUINT) &uLen);


// Versionsnummer bilden
Result.Format("%d.%d.%d.%d",
HIWORD(FileInfo->dwProductVersionMS),
LOWORD(FileInfo->dwProductVersionMS),
HIWORD(FileInfo->dwProductVersionLS),
LOWORD(FileInfo->dwProductVersionLS));

// Speicher freigeben (ich bin mir nicht sicher, aber vermutlich zeigt FileInfo auf diesen Datenbereich)
delete [] pInfo;
}

return Result;
}

int main (void)
{

CString FileVersion = "Version: " + GetFileVersionString(":\\Dokumente und Einstellungen\\Hereich\\Desktop.test.exe");

return 0;

}
 
Hilfe ein Speicherfresser :-).

fname_1 wird nicht wieder freigegeben.

Code:
char* fname_1 = new char [FileName.Length +1];
strcpy(fname_1,FileName);

// prüfen ob überhaupt Info da sind
DWORD nSize = GetFileVersionInfoSize(fname_1, 0);

das sollte doch auch gehen:

Code:
// prüfen ob überhaupt Info da sind
DWORD nSize = GetFileVersionInfoSize(FileName.GetBuffer(1),0);


MfG

Arnd
 
du hast recht mit dem speicher leck ist das noch ein problem aber ich habe es noch nicht lösen können. so wie du es vorgeschlagen hast klingt es gut , geht jedoch nicht weil er mit konvertierungen probleme bekommet. deswegen schreibe ich alles vorher in --- fname_1 --- rein damit er das richtig verarbeiten kann
(

error C2662: 'GetBuffer' : this-Zeiger kann nicht von 'const class CString' in 'class CString &' konvertiert werden

)

. sonst streikt er.

unf fname_1.getbuffer will er nicht nehmen.


hast du noch einen tipp ?
 
Mach einfach das const weg. Das brauchst Du nicht mehr wenn Du mit dem GetBuffer arbeitest. GetBuffer() gibt einen char* zurück.
Sicherheitshalber solltest Du am Ende der Methode noch FileName.ReleaseBuffer() aufrufen.

Lies Dir einfach mal die Doku zu den Methoden durch. CString hat auch noch mehr Methoden :-).

Und das f_name1.getbuffer nicht geht, braucht Dich nicht zu wundern. f_name ist kein Objekt einer Klasse, sondern ein einfacher Datentyp. Wie soll das gehen?

Und wo ist das Problem den Speicher wieder freizugeben? Einfach ein delete[] f_name1 am Schluss.

MfG

Arnd
 
Zuletzt bearbeitet:
Zurück
Oben