Mam zasobu wersji w moich zasobach w projekcie C++, który zawiera numer wersji, prawa autorskie i szczegóły kompilacji. Czy istnieje prosty sposób, aby uzyskać dostęp do tego w czasie wykonywania, aby wypełnić moje okno dialogowe help/about, ponieważ obecnie utrzymuję oddzielne wartości stałych tych informacji. Idealnie, rozwiązanie powinno działać dla Windows/CE mobile i wcześniejszych wersji Visual C++ (6.0 w górę).Jak odczytać z zasobu wersji w Visual C++
Odpowiedz
Jest to edytowany wersja mojego oryginalnego odpowiedź.
bool GetProductAndVersion(CStringA & strProductName, CStringA & strProductVersion)
{
// get the filename of the executable containing the version resource
TCHAR szFilename[MAX_PATH + 1] = {0};
if (GetModuleFileName(NULL, szFilename, MAX_PATH) == 0)
{
TRACE("GetModuleFileName failed with error %d\n", GetLastError());
return false;
}
// allocate a block of memory for the version info
DWORD dummy;
DWORD dwSize = GetFileVersionInfoSize(szFilename, &dummy);
if (dwSize == 0)
{
TRACE("GetFileVersionInfoSize failed with error %d\n", GetLastError());
return false;
}
std::vector<BYTE> data(dwSize);
// load the version info
if (!GetFileVersionInfo(szFilename, NULL, dwSize, &data[0]))
{
TRACE("GetFileVersionInfo failed with error %d\n", GetLastError());
return false;
}
// get the name and version strings
LPVOID pvProductName = NULL;
unsigned int iProductNameLen = 0;
LPVOID pvProductVersion = NULL;
unsigned int iProductVersionLen = 0;
// replace "040904e4" with the language ID of your resources
if (!VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductName"), &pvProductName, &iProductNameLen) ||
!VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductVersion"), &pvProductVersion, &iProductVersionLen))
{
TRACE("Can't obtain ProductName and ProductVersion from resources\n");
return false;
}
strProductName.SetString((LPCSTR)pvProductName, iProductNameLen);
strProductVersion.SetString((LPCSTR)pvProductVersion, iProductVersionLen);
return true;
}
Gdzie znajduje się identyfikator języka? –
@JeffB Zacznę od strony MSDN [Stałe identyfikatora języka i ciągi znaków] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693 (v = vs.85) .aspx) . –
Obie twoje ostatnie dwie linie dają mi '' void ATL :: CSimpleStringT
Coś takiego daje surowy dostęp do danych zasobów i możesz zacząć:
HRSRC res = ::FindResource(NULL, MAKEINTRESOURCE(MY_VERSION_ID), RT_VERSION);
DWORD size = ::SizeofResource(NULL, res);
HGLOBAL mem = ::LoadResource(NULL, res);
LPVOID raw_data = ::LockResource(mem);
...
::FreeResource(mem);
Ok, nieco bardziej googleing znalazł following na CodeGuru. Zasadniczo to podejście używa obiektu , aby uzyskać dostęp do dowolnego pliku. Warto sprawdzić, czy działa na aktualnie uruchomionym pliku .EXE i Windows CE.
Coś może Ci zacząć, może:
TCHAR moduleName[MAX_PATH+1];
(void)GetModuleFileName(AfxGetInstanceHandle(), moduleName, MAX_PATH);
DWORD dummyZero;
DWORD versionSize = GetFileVersionInfoSize(moduleName, &dummyZero);
if(versionSize == 0)
{
return NULL;
}
void* pVersion = malloc(versionSize);
if(pVersion == NULL)
{
return NULL;
}
if(!GetFileVersionInfo(moduleName, NULL, versionSize, pVersion))
{
free(pVersion);
return NULL;
}
UINT length;
VS_FIXEDFILEINFO* pFixInfo;
VERIFY(VerQueryValue(pVersionInfo, const_cast<LPTSTR>("\\"), (LPVOID*)&pFixInfo, &length));
Uwaga! Korzystanie z FindResource..LockResource nie jest poprawne. Czasami będzie działać (tak jak w moim małym programie demonstracyjnym), a czasami powoduje naruszenia zasad dostępu (np. Kod produkcyjny, dla którego robiłem demo).
Dokumentacja VerQueryValue() stwierdza, że należy wywołać metody GetFileVersionInfoSize i GetFileVersionInfo. Raymond Chen wyjaśnia, zobacz http://blogs.msdn.com/oldnewthing/archive/2006/12/26/1365215.aspx
Aby uzyskać język niezależny wynik zmian odpowiedź Marka:
// replace "040904e4" with the language ID of your resources
!VerQueryValue(&data[0], _T("\\StringFileInfo\\040904e4\\ProductVersion"), &pvProductVersion, &iProductVersionLen))
{
TRACE("Can't obtain ProductName and ProductVersion from resources\n");
return false;
}
Aby
UINT uiVerLen = 0;
VS_FIXEDFILEINFO* pFixedInfo = 0; // pointer to fixed file info structure
// get the fixed file info (language-independent)
if(VerQueryValue(&data[0], TEXT("\\"), (void**)&pFixedInfo, (UINT *)&uiVerLen) == 0)
{
return false;
}
strProductVersion.Format("%u.%u.%u.%u",
HIWORD (pFixedInfo->dwProductVersionMS),
LOWORD (pFixedInfo->dwProductVersionMS),
HIWORD (pFixedInfo->dwProductVersionLS),
LOWORD (pFixedInfo->dwProductVersionLS));
dzięki, to jest bardzo interesujące, świetne rozwiązanie! – ghiboz
Otrzymuje różne informacje od odpowiedzi Marka Ransoma. Pobrane wartości to cztery liczby całkowite z wiersza najwyższego poziomu PRODUCTVERSION w pliku zasobów; jednak odpowiedź Marks pobiera łańcuch "ProductVersion" spod bloku "StringFileInfo". –
Czasami otrzymać dostęp naruszenie gdy użycie VerQueryValueA
. Ale nigdy nie dostałem tego błędu podczas używania VerQueryValueW
. Myślę, że coś nie tak z VerQueryValueA
w wersji.dll. Dlatego używam VerQueryValueW
zamiast VerQueryValueA
nawet w projektach Wielobajtowe kodowanie znaków. Here is my code of ReadVersion
function
- 1. Jak odczytać plik zasobu z pliku JAR Java?
- 2. Jak odczytać migawkę pamięci w Visual Studio
- 3. Jak odczytać tablicę bajtów z DataRow w C#?
- 4. Wykrywanie wersji Visual Studio wewnątrz
- 5. Jak zbudować libevent w wersji 2.0.10 z Visual Studio 2008
- 6. Jak zmienić nazwę zasobu w programie Visual Studio?
- 7. odczytać ciąg z pliku .resx w C#
- 8. Jak odczytać CSV na iskry w wersji 1.4?
- 9. Jak odczytać plik maty w wersji 7.3 przez h5py?
- 10. Jak przejść z wersji z Visual Studio 2012 na Visual Studio 2008
- 11. Jak odczytać plik programu Excel w wersji go?
- 12. Załaduj zespół z osadzonego zasobu
- 13. Jak odczytać rosnący plik tekstowy w C++?
- 14. Jak mogę odczytać bazę danych/plik Pythona z C?
- 15. Jak odczytać plik do wektora w C++?
- 16. Jak odczytać właściwości MSI w C#
- 17. Jak odczytać nieograniczoną liczbę znaków w C
- 18. Jak odczytać niestandardowe właściwości pliku w C#
- 19. Jak odczytać tabelę katalogu importowania w C
- 20. Jak odczytać plik XML w języku C#?
- 21. Uzyskiwanie FILEVERSION z pliku zasobów Visual C++
- 22. Jak odczytać/zapisać wartości typu z pamięci "surowej" w C?
- 23. Jak odczytać wartość atrybutu z XmlNode w C#?
- 24. Jak odczytać klucz prywatny z pliku Pvk w języku C#?
- 25. odczytać dane z pliku do końca wiersza w C/C++
- 26. Jak odczytać wartość klucza rejestru C#
- 27. c odczytać uprawnienia pliku
- 28. Jak załadować ikonę z zasobu w Javie?
- 29. Używanie biblioteki DLL języka Visual C++ w starej wersji Borland C?
- 30. Typ wersji w języku C#
Należy zauważyć, że użycie '_get_pgmptr()' lub '_get_wpgmptr()' jest lepsze niż 'GetModuleFileName (NULL, szFilename, MAX_PATH)'; ratuje cię od niepotrzebnej alokacji i wyjaśnia twoją intencję. – q12