none
How do I get my own file version inside my own file in C langauge? RRS feed

  • Question

  • This is a simple (silly) question. Whenever I release a new version of my program I manually edit the *.rc file. I would like to get access to the info in the *.rc file in my *.c program when running it. For example I would like read the following field programmatically inside my C:

    Fileversion

    LegalCopyright

    InternalName 

     

    I dont want to use GetFileVersion() for my own file version. So how do I do that? I am using VS2010, C program not MFC, plain old C.

    thanks

    ananda

     

    Monday, March 28, 2011 3:36 PM

Answers

  • On 3/28/2011 11:36 AM, ananda vardhana wrote:

    This is a simple (silly) question. Whenever I release a new version
    of my program I manually edit the *.rc file. I would like to get
    access to the info in the *.rc file in my *.c program when running
    it.

    I dont want to use GetFileVersion() for my own file version.

    Why not? That's the documented supported method. See also

    http://blogs.msdn.com/b/oldnewthing/archive/2006/12/26/1365215.aspx

    You can use GetModuleFileName(NULL) to obtain the path of your own executable.


    Igor Tandetnik

    Monday, March 28, 2011 3:50 PM
  • Thanks to both. I felt *.rc file is like *.h part of the product. If I can get access to what ever in *.h directly without having to make any calls,

    No, rc file is like .c file. The .h files are .h files, for both .c and .rc parts. You have to call something to get any resources (such as message strings, icons etc.) anyway.

    Note that version resource is special: its string part can be split to localized resource DLLs, as explained here.

    "in Windows Server 2008 and in Windows Vista, GetFileVersionInfo queries the fixed part of the file-version information from the multilanguage file (an .exe file or a .dll file) and queries the nonfixed part of the file-version information from the .mui file. Then, GetFileVersionInfo merges the fixed and nonfixed parts of the file-version information and returns the result to the user. If a particular binary file does not have a corresponding .mui file, file-version information retrieval reverts to the behavior of the earlier operating system. "

    -- pa


    Monday, March 28, 2011 4:46 PM
  • >I felt *.rc file is like *.h part of the product.
    >If I can get access to what ever in *.h directly
    >without having to make any calls, I thought there
    > should be direct internal path to get the info
    >inside my own *.rc file.

    The .rc file may not even be available at run time.
    Even if it were, there would be no guarantee that
    it was the same version that was used when the .exe
    was built.

    When you build your program, the .rc script file is
    compiled by the Resource Compiler. The compiled
    resource file (.res) is then added to your .exe
    by the linker. To get the version info for the
    .exe reliably you have to retrieve that resource
    data from the .exe itself.

    - Wayne
    Monday, March 28, 2011 5:14 PM

All replies

  • On 3/28/2011 11:36 AM, ananda vardhana wrote:

    This is a simple (silly) question. Whenever I release a new version
    of my program I manually edit the *.rc file. I would like to get
    access to the info in the *.rc file in my *.c program when running
    it.

    I dont want to use GetFileVersion() for my own file version.

    Why not? That's the documented supported method. See also

    http://blogs.msdn.com/b/oldnewthing/archive/2006/12/26/1365215.aspx

    You can use GetModuleFileName(NULL) to obtain the path of your own executable.


    Igor Tandetnik

    Monday, March 28, 2011 3:50 PM
  • Well, I tend to call GetFileVersion myself.  Another alternative I have done one time was:

    Create a version.c file that contained the version information.  I then used a custom build step to parse the version.c file and emit a VS_VERSION_INFO block into a file that I included from my .rc file.  This worked pretty well.  I suspect I could have refined the process even more and somehow used the C preprocessor and some fancy macro definitions to do all the work for me.

    Monday, March 28, 2011 3:52 PM
  • If you follow the approach outlined by http://support.microsoft.com/kb/237870, you can include the header file generated by the VBScript in your .c file to get the version information for your project.

    There is nothing wrong with calling GetFileVersion on your own executable, however.

    Monday, March 28, 2011 4:04 PM
  • Thanks to both. I felt *.rc file is like *.h part of the product. If I can get access to what ever in *.h directly without having to make any calls, I thought there should be direct internal path to get the info inside my own *.rc file. Might be it is not as easy as getting it from a header file but logically I feel there is a method to do it. Using GetFileVersion() is a round about method I feel, that would be like opening your own *.h file and programatically reading the value you have defined there. Might be I am wrong in my logical thinking :-)...
    Monday, March 28, 2011 4:08 PM
  • Thanks for the clarification Pavel and all. I was wrong in my thinking so shall use GetFileVersion() as directed by all. Thanks again and this case  might be closed. 
    Monday, March 28, 2011 4:49 PM
  • >I felt *.rc file is like *.h part of the product.
    >If I can get access to what ever in *.h directly
    >without having to make any calls, I thought there
    > should be direct internal path to get the info
    >inside my own *.rc file.

    The .rc file may not even be available at run time.
    Even if it were, there would be no guarantee that
    it was the same version that was used when the .exe
    was built.

    When you build your program, the .rc script file is
    compiled by the Resource Compiler. The compiled
    resource file (.res) is then added to your .exe
    by the linker. To get the version info for the
    .exe reliably you have to retrieve that resource
    data from the .exe itself.

    - Wayne
    Monday, March 28, 2011 5:14 PM
  • Wow! Thanks for the info Wayne and clarification. I shall revisit my program and check it out
    Sunday, June 5, 2011 8:54 PM
  • Just to complete this. I finally ended up writing this code and it works. I know it is bit round about but it does the work :-)

    This is how you call it:

        ULONG           majVer = 0, minVer = 0;

        GetMyFileInfo("MyProgram.exe", &majVer, &minVer);

     

    This is the actual function:

    ULONG

    GetMyFileInfo(

        CHAR *FileName,

        PULONG MajVer,

        PULONG MinVer

        )

        /*++

        Gets file versions of the *FileName files

        Filename can be a path or the current binary name

        like MyProgram.exe

        --*/

    {

     

        ULONG dwHandle, dwLen;

        ULONG BufLen;

        LPTSTR lpData;

        VS_FIXEDFILEINFO *pFixedFileInfo;

        errno_t err;

     

        dwLen = GetFileVersionInfoSize( FileName, &dwHandle );

        if (!dwLen) {

            err = GetLastError();

            return err;

        }

     

        lpData = (LPTSTR) malloc (dwLen);

        if (!lpData) {

            return 0;

        }

     

        if( !GetFileVersionInfo( FileName, dwHandle, dwLen, lpData ) )

        {

            err = GetLastError();

            free (lpData);

            return err;

        }

        if( VerQueryValue( lpData, "\\", (LPVOID *) &pFixedFileInfo, (PUINT)&BufLen

    ) )

        {

            *MajVer = HIWORD(pFixedFileInfo->dwFileVersionMS);

            *MinVer = LOWORD(pFixedFileInfo->dwFileVersionMS);

        } else {

            err = GetLastError();

            return err;

        }

        return 1;

    } // GetMyFileInfo

    Friday, August 19, 2011 6:07 PM