1

I am new in the forum but I have already found a lot of help for my other projects. I am using Visual Studio 2019 and I have created a .rc file which contains the file version and a few other things. These information are displayed in the Properties window of the my dll correctly.

I have created a function

void PrintVersion(TCHAR* pszFilePath, void (*printFunc)(const char*, ...));

which receives the file path and a pointer to my logger function. Inside that function I want to read the file version and print it to the logger. But my logger returns Error in GetFileVersionInfoSize: The system cannot find the file specified.

My function call does look like this:

TCHAR* filename = L"mydll.dll";
PrintVersion(filename, gPrintFunc);

And the function is implemented as follows:

// Read the version of the dll and write it to the logger
void PrintVersion(TCHAR* pszFilePath, void (*printFunc)(const char*, ...))
{
    DWORD               dwSize = 0;
    DWORD               verHandle = 0;
    BYTE*               pbVersionInfo = NULL;
    VS_FIXEDFILEINFO*   pFileInfo = NULL;
    UINT                puLenFileInfo = 0;

    // Get the size of the version information. This is done to check if the file is avaialbe
    // If the size is zero then a error occured
    dwSize = GetFileVersionInfoSize(pszFilePath, &verHandle);
    if (dwSize == 0)
    {
        gPrintFunc("Error in GetFileVersionInfoSize: ");
        PrintLastErrorString(gPrintFunc);
        return;
    }

    // Create some memory for the file version info
    pbVersionInfo = malloc(dwSize);

    // Store the information into pbVersionInfo
    #pragma warning(suppress : 6387)
    if (!GetFileVersionInfo(pszFilePath, verHandle, dwSize, pbVersionInfo))
    {
        gPrintFunc("Error in GetFileVersionInfo: ");
        PrintLastErrorString(gPrintFunc);
        free(pbVersionInfo);
        return;
    }

    // Make the information easier accessable in pFileInfo
    #pragma warning(suppress : 6387)
    if (!VerQueryValue(pbVersionInfo, TEXT("\\"), (LPVOID*)&pFileInfo, &puLenFileInfo))
    {
        gPrintFunc("Error in VerQueryValue: ");
        PrintLastErrorString(gPrintFunc);
        free(pbVersionInfo);
        return;
    }

    // pFileInfo->dwFileVersionMS and pFileInfo->dwFileVersionLS contain the software version
    // Major2B.Minor2B.Revision2B.Build2B
    gPrintFunc("File Version of %s: %d.%d.%d.%d\n",
        pszFilePath,
        (pFileInfo->dwFileVersionMS >> 16) & 0xffff,
        (pFileInfo->dwFileVersionMS >> 0) & 0xffff,
        (pFileInfo->dwFileVersionLS >> 16) & 0xffff,
        (pFileInfo->dwFileVersionLS >> 0) & 0xffff
    );

    // Free up the reserved memory
    free(pbVersionInfo);
}
// Used for receiving the last WIN32 error and write it to the logger
void PrintLastErrorString(void (*printFunc)(const char*, ...))
{
    // Get the error id of the last error
    DWORD iLastError;
    iLastError = GetLastError();

    //Ask Win32 to give us the string version of that message ID.
    //The parameters we pass in, tell Win32 to create the buffer that holds the message for us (because we don't yet know how long the message string will be).
    LPSTR messageBuffer = NULL;
    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, iLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

    gPrintFunc("%s\n", messageBuffer);
    return;
}

I created that function by combining a few different C++ and C# examples from this forum. I am not familiar with the TCHAR* datatype. I assume that the problem has maybe something to do with the filename string. Further I am not able to print the filename to the logger with the %s format placeholder. In this case only the first letter of the filename is displayed.

One further info. Before I copied that code to the dll. I created a small console application. And in this case it was possible to read the file version of the exe. I also tried to specify the complete path of the dll. The dll and the exe, which uses the dll are in the same directory.

Maybe someone can help me :)

BR

जलजनक
  • 3,072
  • 2
  • 24
  • 30
  • 2
    Please don't spam unrelated tags. Only tag the language the code is actually written in. – Some programmer dude Apr 12 '22 at 06:42
  • 1
    As for your problem, do you know about the concept of [*working directory*](https://en.wikipedia.org/wiki/Working_directory)? Every process have a *working directory* (also called current working directory). All relative paths (like for example `mydll.dll`) are relative to the working directory. What happens if you use the full and absolute path to the DLL? Does it work then? – Some programmer dude Apr 12 '22 at 06:45
  • On another note, your functions have a `printFunc` argument, but they don't use it? Why not? – Some programmer dude Apr 12 '22 at 06:45
  • 4
    Concerning _I am not familiar with the TCHAR* datatype._: [TCHAR](https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/tchar), [Generic-Text Mappings in tchar.h](https://learn.microsoft.com/en-us/cpp/text/generic-text-mappings-in-tchar-h?view=msvc-170), [SO: Is TCHAR still relevant?](https://stackoverflow.com/questions/234365/is-tchar-still-relevant) and google is your friend: [google "windows TCHAR"](https://www.google.com/search?q=windows+TCHAR) – Scheff's Cat Apr 12 '22 at 06:48

1 Answers1

0

Thank you for your answers. I changed now the character set to: Use Unicode Character Set and now it works as expected.