From: Joseph M. Newcomer on
The version library is not included by default in the link. If you get any kind of linker
error, it is ESSENTIAL that you RTFM, which tells you which library needs to be linked in.
Link in that library.
joe
****
On Tue, 15 Jun 2010 18:14:48 -0500, "JCO" <someone(a)somewhere.com> wrote:

>
>This is another issue that fits in this thread.
>I've been messing with the GetFileVersionInfo() but when it's in my cpp, I
>get link errors. I can't seem to find a header file that might be missing
>so I don't understand it. The code snip is shown below. I have some extra
>code because I'm experimenting a bit but the issue is the
>GetFileVersionInfo() linker Issue.
>*********************************************************
> //get filename, add .exe, then get handle to this filename
****
Start throwing code away here
****
> CString strFileName( _T("") );
> strFileName = AfxGetApp()->m_pszExeName;
> strFileName.Append( _T(".exe") );
> HMODULE hmod = GetModuleHandle( strFileName );
>
> //use GetModuleFileName() to obtain full path of file
> CString strFullPath( _T("") );
> LPTSTR pstr = strFullPath.GetBufferSetLength(MAX_PATH+1);
> DWORD pathLen = ::GetModuleFileName( hmod, pstr, MAX_PATH);
>
> strFullPath.ReleaseBuffer( pathLen ); //Note: ReleaseBuffer doesn't need
>a +1 for the null byte
****
Throw away all the above code. As far as I can tell, it does nothing that can't be done
in the four simple lines below.

CString filename;
LPTSTR p = fliename.GetBuffer(MAX_PATH);
GetModuleFileName(NULL, p, MAX_PATH);
filename.ReleaseBuffer();

It is not at all clear why you have to use GetModuleHandle here at all. The module handle
is not needed for anything. RTFM; using NULL as the module handle gives you the filename
of the running executable!
****
>
> //Use GetFileVersionInfo() to get file information
> TCHAR szExePath[MAX_PATH];
****
This variable is not needed; eliminate it entirely!
*****
> ::GetModuleFileName( NULL, szExePath, MAX_PATH );
****
Why are you repeating the GetModuleFileName, which was already done? Get rid of this
line; it serves no useful purpose because you already have the module filename!
****
>
> DWORD dwDummy;
> DWORD dwFVISize = GetFileVersionInfoSize( szExePath, &dwDummy );
****
Given I used the variable "filename" above, this would simply be
DWORD dwFVISize = ::GetFileVersionInfoSize(filename, &dwDummy);
****
>
> LPBYTE lpVersionInfo = new BYTE[dwFVISize];
****
You would be better served by
CBytArray VersionInfo;
VersionInfo.SetSize(dwFVISize];
*****
> GetFileVersionInfo( szExePath , 0 , dwFVISize , lpVersionInfo );
****
And then coding the above as
::GetFileVersionInfo(filename, 0, dwFVISize, VersionInfo.GetData());
****
>
> if( lpVersionInfo )
> delete lpVersionInfo;
****
Note there is no need to do the delete if you have used the CByteArray.

Note also that you must not delete this data until *after* you have used it!

And why is it that if the value is NULL, you try to call ::GetFileVersionInfo anyway? If
you were testing for an allocation error, you would test BEFORE you tried to use the
pointer. And there is no need to condition delete if it is NULL. And if the call
failed, why are you blindly going on and tryhing to *use* the illegal values?
>
> VS_FIXEDFILEINFO *lpFfi;
****
And where do I see this pointer being initialized? You have an uninitialized pointer and
you blindly use it to access values below!

It should be initialized as
VS_FIXEDFILEINFO * Ffi =(VS_FIXEDFILEINFO *)VersionInfo.GetData();
****
> DWORD dwFileVersionMS = lpFfi->dwFileVersionMS;
> DWORD dwFileVersionLS = lpFfi->dwFileVersionLS;
> DWORD dwLeftMost = HIWORD(dwFileVersionMS);
> DWORD dwSecondLeft = LOWORD(dwFileVersionMS);
> DWORD dwSecondRight = HIWORD(dwFileVersionLS);
> DWORD dwRightMost = LOWORD(dwFileVersionLS);
>
> CString sMsg;
> sMsg.Format( _T("Version: %d.%d.%d.%d") , dwLeftMost,
>dwSecondLeft,dwSecondRight, dwRightMost );
> MessageBox( sMsg );
>
>********************************************************
>
>These are the liker Errors:
>Error 1 error LNK2019: unresolved external symbol _GetFileVersionInfoW(a)16
>referenced in function "public: void __thiscall
>CAppVersionDynamicDlg::OnBnClickedButtonVersion(void)"
>(?OnBnClickedButtonVersion(a)CAppVersionDynamicDlg@@QAEXXZ)AppVersionDynamicDlg.obj AppVersionDynamicError 2 error LNK2019: unresolved external symbol _GetFileVersionInfoSizeW@8
>referenced in function "public: void __thiscall
>CAppVersionDynamicDlg::OnBnClickedButtonVersion(void)"
>(?OnBnClickedButtonVersion(a)CAppVersionDynamicDlg@@QAEXXZ)AppVersionDynamicDlg.obj AppVersionDynamic"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
>news:cc1f16hsn3lejfmtp2b5n0a20093vii1bf(a)4ax.com...
****
RTFM. The documentation CLEARLY states that the API call is found in version.lib, so it
is screamingly obvious that this library is not included in the link. So add it to the
linker list of libraries to search!
joe
****
>> The idea is that the header file is used to create both the string in the
>> About box and
>> the values in the .rc file that describes the VERSIONINFO.
>> joe
>>
>> On Mon, 14 Jun 2010 18:54:46 -0500, "JCO" <someone(a)somewhere.com> wrote:
>>
>>>I think I'm missing something but I'm interested in this topic.
>>>If you have your version defined in a header file, then you can display it
>>>in the dialog, however, if you did a "property" on the exe file, has it
>>>really changed? If so, then I got lost somewhere in this thread.
>>>
>>>Also;
>>>I was under the impression that you can set something in VS that allowed
>>>the
>>>version to change each time you do a build. I don't remember how to do
>>>this
>>>but I always thought this was possible. Now it may only change the Build
>>>number and not anything else, however, this is a good feature. Is this
>>>still possible, if so .... how do you do it?
>>>
>>>Thanks
>>>
>>>
>>>"Giovanni Dicanio" <giovanniDOTdicanio(a)REMOVEMEgmail.com> wrote in message
>>>news:eg3hiCyCLHA.2012(a)TK2MSFTNGP02.phx.gbl...
>>>> On 13/06/2010 15:47, RB wrote:
>>>>
>>>>> void CFileHandlingApp::OnAppAbout()
>>>>> {
>>>>> CAboutDlg aboutDlg;
>>>>> CString s;
>>>>> s.Format( _T(" version %d.%d.%d.%d"), VERMAJ, VERMIN, VERFIX,
>>>>> BUILDNUMBER );
>>>>> aboutDlg.m_CtrlStaticVer.SetWindowText(s); //gets a Debug Assertion
>>>>> Failed
>>>>> aboutDlg.DoModal();
>>>>
>>>> You may want to add a method to your CAboutDlg class like
>>>> SetVersionString(LPCTSTR pszVersion) and a data member of type CString
>>>> (e.g. CString m_strVersion).
>>>> This new method should set the version string, storing it into the
>>>> proper
>>>> data member.
>>>>
>>>> Then, CAboutDlg::OnInitDialog would get this string and .SetWindowText()
>>>> it in the proper static control.
>>>>
>>>> e.g.:
>>>>
>>>> class CAboutDlg
>>>> {
>>>> ...
>>>> public:
>>>> void SetVersionString(LPCTSTR pszVersion)
>>>> {
>>>> m_strVersion = pszVersion;
>>>> }
>>>>
>>>> ...
>>>>
>>>> private:
>>>> CString m_strVersion;
>>>> };
>>>>
>>>> In CAboudDlg::OnInitDialog() do:
>>>>
>>>> m_CtrlStaticVer.SetWindowText(m_strVersion);
>>>>
>>>>
>>>> Giovanni
>> Joseph M. Newcomer [MVP]
>> email: newcomer(a)flounder.com
>> Web: http://www.flounder.com
>> MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
If you add a VERSIONINFO to the RC2 file, you must DELETE the EXISTING ONE from the .rc
file! Otherwise, guess what, you have a duplicate resource of type VERSION, whose name is
1, and whose language is 0x0409.

Error 1 leads directly to error 2.
joe

On Tue, 15 Jun 2010 12:24:05 -0500, "JCO" <someone(a)somewhere.com> wrote:

>When I add this information to the RC2 file, I get these two errors:
>1 CVT1100: duplicate resource, Type:VERSION, name:1, language:0x0409
>2 LNK1123: failure during conversion to COFF: file invalid or corrupt
>
>"RB" <NoMail(a)NoSpam> wrote in message
>news:umG$MhIDLHA.4400(a)TK2MSFTNGP05.phx.gbl...
>> Corrective update, although the paste I gave you does in fact work
>> in my App currently. You may want to reexamine my use of the
>> results of #define _STR(x) #x
>> #define STR(x) _STR(x)
>> since I am still learning this area, and some reading I did last night
>> proves to me that I did not fully understand what this macro was
>> expanding to when I implemented some of the pasted code.
>>
>> I really should not be replying to questions since I am not at that
>> level of competence yet. I only supplied it since I "appeared at the
>> time" to have a working example of what you asked for, which
>> the whole idea was given to me ( if you followed the thread )
>> by David Webber, but the implementation (and any foo bars )
>> are my doing, not Davids.
>> So use what you will but be aware.
>> RB
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
See below...
On Tue, 15 Jun 2010 13:44:23 -0500, "JCO" <someone(a)somewhere.com> wrote:

>
>I understand the items that are added to the .rc2 file, however, are you
>suppose to also edit the .rc file by commenting out everything listed under
>"Version"?
****
I have no idea what you mean by "commenting out everything listed under "Version". What
you need to do is DELETE the version resource from the .rc file. Highlight it in the tree
describing the resources and use the "delete" key, just like you would do in deleting any
other kind of resource.

Commenting something out is not a relevant concept here. Deleting it is what you want to
do!
joe

>
>
>"RB" <NoMail(a)NoSpam> wrote in message
>news:umG$MhIDLHA.4400(a)TK2MSFTNGP05.phx.gbl...
>> Corrective update, although the paste I gave you does in fact work
>> in my App currently. You may want to reexamine my use of the
>> results of #define _STR(x) #x
>> #define STR(x) _STR(x)
>> since I am still learning this area, and some reading I did last night
>> proves to me that I did not fully understand what this macro was
>> expanding to when I implemented some of the pasted code.
>>
>> I really should not be replying to questions since I am not at that
>> level of competence yet. I only supplied it since I "appeared at the
>> time" to have a working example of what you asked for, which
>> the whole idea was given to me ( if you followed the thread )
>> by David Webber, but the implementation (and any foo bars )
>> are my doing, not Davids.
>> So use what you will but be aware.
>> RB
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
See below...
On Tue, 15 Jun 2010 16:15:28 -0500, "JCO" <someone(a)somewhere.com> wrote:

>
>When I delete the VERSION in the .rc, I get the following link errors:
>
>Error 1 error LNK2019: unresolved external symbol _GetFileVersionInfoW(a)16
>referenced in function "public: void __thiscall
****
RTFM. You did not include version.lib in the link! This is trivial to fix. You really,
really need to understand what "undefined symbol" means. It means it can't figure out
what the symbol means, because no library has that symbol defined in it. So figure out
what library DOES have that symbol defined, and add it to the link.

Fortunately, this is trivial, because every API call tells you *exactly* what library it
is found in!
joe
****
>CAppVersionDynamicDlg::OnBnClickedButton1(void)"
>(?OnBnClickedButton1(a)CAppVersionDynamicDlg@@QAEXXZ) AppVersionDynamicDlg.objAppVersionDynamicError 2 fatal error LNK1120: 1 unresolved externals E:\My
>C++\AppVersionDynamic\AppVersionDynamic\Debug\AppVersionDynamic.exeAppVersionDynamicIf I don't remove anything from the .rc file, I get the other two errors I
>posted earlier.
>Sorry this isn't working for me. I'm not that experienced in this stuff
>either.
>Thanks
>
>"RB" <NoMail(a)NoSpam> wrote in message
>news:eI1w22LDLHA.1888(a)TK2MSFTNGP05.phx.gbl...
>>> I understand the items that are added to the .rc2 file, however, are you
>>> suppose to also edit the .rc file by commenting out everything listed
>>> under "Version"?
>>
>> Yes, and sorry I said CAbout Dialog segment earlier. Actually
>> at first I cut and pasted the Dialog segement also and it worked
>> but I lost my ability to see and edit it's other aspects in the resource
>> editor so I pasted it back and it held next time VS rewrote it.
>> But anyhow yes the version segment, but in my VS I cannot comment out rc
>> file segments since the VS writes (and rewrites ) the entire file. So I
>> cut the version segment out totally and pasted it into the rc2 file. See
>> other reply (but ignore dialog segment and
>> use version)
>> If your VS allows you to comment in the rc file then yea you could do
>> that, but unless things changed with the newer VS that file belongs to the
>> VS so I would think that anything you were allowed to comment
>> would be gone next time VS rewrote it
>> RB
>>
>>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Giovanni Dicanio on
On 16/06/2010 05:57, Joseph M. Newcomer wrote:

>> LPBYTE lpVersionInfo = new BYTE[dwFVISize];
> ****
> You would be better served by
> CBytArray VersionInfo;
> VersionInfo.SetSize(dwFVISize];

or STL's vector:

vector<BYTE> VersionInfo(dwFVISize);

>>
>> if( lpVersionInfo )
>> delete lpVersionInfo;
> ****
> Note there is no need to do the delete if you have used the CByteArray.
>
> Note also that you must not delete this data until *after* you have used it!

Note also that if the memory was allocated using new BYTE[...], it
should be deleted using delete[] (note the square brackets).

I agree that with RAII classes like std::vector you just don't need to
spend brain cycles :) to track these kind of memory leaks.

Giovanni