Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Access version resource from code

Brian_Triplett
2,257 Views
I'm trying to access version information about my fortran program in code (for output printing and so forth). Presently that information is stored in a resource file (Version.rc) in my Visual Studio project file (*.vfproj).

Is it possible to access the information in the resource file from code? If so, are there any example of doing this?
0 Kudos
1 Solution
netphilou31
New Contributor III
2,257 Views
Hi,
Please find enclosed a piece of code I use for retrieving the version number of a dll. I guess that you can adapt it to your needs.
Best regards,
[fxfortran]      subroutine GetVersionInfoString(EXE_Name, VERSION_INFO)
      use DFWIN
      implicit none
C
      character(len=*), intent(in) ::  EXE_Name
      character(len=*), intent(out) :: VERSION_INFO
C
C     Reading the version number of an executable (or dll)
C
      integer(4)         Hndl
      integer(4)         nBytes
      integer(4)         rc
      character(len=256) StringInfo
      character(len=8)   CharSet
C
      integer(4)         uVersionLen, uTranslationLen
      integer(4)         lpstrVffInfo, lpstrVffInfo1
      integer(4)         hMem
      integer(4)         i
      character(len=256) lpversion
      integer(1)         lpTranslation(256)
      integer(4)         pTranslation
C
      nBytes = GetFileVersionInfoSize(EXE_Name, LOC(Hndl))
C
      if (nBytes /= 0) then
          hMem = GlobalAlloc(GMEM_MOVEABLE, int(nBytes))
          lpstrVffInfo = GlobalLock(hMem)
          rc = GetFileVersionInfo(EXE_Name, Hndl, nBytes, lpstrVffInfo)
          StringInfo = "\VarFileInfo\Translation"C
          rc = VersionQueryValue(lpstrVffInfo, loc(StringInfo), loc(lpTranslation), loc(uTranslationLen))
          write(CharSet,'(4z2.2)') lpTranslation(2),lpTranslation(1),lpTranslation(4),lpTranslation(3)
          StringInfo = "\StringFileInfo\"//CharSet//"\FileVersion\"C
          rc = VersionQueryValue(lpstrVffInfo, loc(StringInfo), loc(lpVersion), loc(uVersionLen))
          if (rc /= 0) then
              rc = lstrcpy(VERSION_INFO, lpVersion)
              uVersionLen = min(uVersionLen,index(VERSION_INFO,char(0)))
              do i=uVersionLen,LEN(VERSION_INFO)
                 VERSION_INFO(i:i) = ' '
              end do
          else
              VERSION_INFO = 'n.c'
	  end if
          rc = GlobalUnlock(hMem)
          rc = GlobalFree(hMem)
      else
          VERSION_INFO = 'n.c'
      end if
C
      return
      end
[/fxfortran]

View solution in original post

0 Kudos
7 Replies
Steven_L_Intel1
Employee
2,257 Views
Yes. First you call GetModuleHandle with a NULL argument to get a handle to the running EXE. Then you call GetFileVersionInfoEx to retrieve the version information. See the MSDN documentation on these routines for details. One of the things you have to do is get the "size" of the version info first, allocate a block of the desired size, and then get the actual data. I have done this in Fortran but don't think I have the code I used handy.
0 Kudos
netphilou31
New Contributor III
2,258 Views
Hi,
Please find enclosed a piece of code I use for retrieving the version number of a dll. I guess that you can adapt it to your needs.
Best regards,
[fxfortran]      subroutine GetVersionInfoString(EXE_Name, VERSION_INFO)
      use DFWIN
      implicit none
C
      character(len=*), intent(in) ::  EXE_Name
      character(len=*), intent(out) :: VERSION_INFO
C
C     Reading the version number of an executable (or dll)
C
      integer(4)         Hndl
      integer(4)         nBytes
      integer(4)         rc
      character(len=256) StringInfo
      character(len=8)   CharSet
C
      integer(4)         uVersionLen, uTranslationLen
      integer(4)         lpstrVffInfo, lpstrVffInfo1
      integer(4)         hMem
      integer(4)         i
      character(len=256) lpversion
      integer(1)         lpTranslation(256)
      integer(4)         pTranslation
C
      nBytes = GetFileVersionInfoSize(EXE_Name, LOC(Hndl))
C
      if (nBytes /= 0) then
          hMem = GlobalAlloc(GMEM_MOVEABLE, int(nBytes))
          lpstrVffInfo = GlobalLock(hMem)
          rc = GetFileVersionInfo(EXE_Name, Hndl, nBytes, lpstrVffInfo)
          StringInfo = "\VarFileInfo\Translation"C
          rc = VersionQueryValue(lpstrVffInfo, loc(StringInfo), loc(lpTranslation), loc(uTranslationLen))
          write(CharSet,'(4z2.2)') lpTranslation(2),lpTranslation(1),lpTranslation(4),lpTranslation(3)
          StringInfo = "\StringFileInfo\"//CharSet//"\FileVersion\"C
          rc = VersionQueryValue(lpstrVffInfo, loc(StringInfo), loc(lpVersion), loc(uVersionLen))
          if (rc /= 0) then
              rc = lstrcpy(VERSION_INFO, lpVersion)
              uVersionLen = min(uVersionLen,index(VERSION_INFO,char(0)))
              do i=uVersionLen,LEN(VERSION_INFO)
                 VERSION_INFO(i:i) = ' '
              end do
          else
              VERSION_INFO = 'n.c'
	  end if
          rc = GlobalUnlock(hMem)
          rc = GlobalFree(hMem)
      else
          VERSION_INFO = 'n.c'
      end if
C
      return
      end
[/fxfortran]
0 Kudos
bmchenry
New Contributor II
2,257 Views

been messsing with this code and ran into a couple of things:
1) This uses DFWIN. Also works with IFWIN. Is there anydifference between DFWIN v IFWIN?
2) VersionInfoQuery now VerInfoQuery, changing doesn't seem to make any difference
3) on line rc = VerQueryValue(lpstrVffInfo, loc(StringInfo), loc(lpVersion), loc(uVersionLen))
it always returns 0

Anyone look at code and see a problem/issue?

Thanks!
b

0 Kudos
netphilou31
New Contributor III
2,257 Views

Hi,

I developed this portion of code with CVF (COMPAQ Visual Fortran). At that time the module name was DFWIN, but now with Intel Visual Fortran, it has been renamed IFWIN, although a compatibility module is still available. For the other issues I did not test the code using IVF.

0 Kudos
bmchenry
New Contributor II
2,257 Views
aha! therein lies the issue!
i thought it was something that worked on IVF.
OK, that gives me a clue why it wasn't working as expected!

also foundat

http://software.intel.com/en-us/forums/showthread.php?t=78525&o=a&s=lr

from Steve:
The handles (hMem, etc.) should be declared INTEGER(HANDLE). The "lp" variables should be INTEGER(LPVOID).

Guess i'll try that!

thanks!


0 Kudos
Michiel_Tukker
Beginner
2,257 Views

Sorry to kick the topic, but I encountered the same issue where the above code wouldn't work. After some tinkering and combining several posts on the internet, I got it working. Here's my code (works in IVF 11)

 

#define MAX_PATH 260+1      

subroutine GetVersionInfoStrings(FILEVERSION)
	use IFWIN
	implicit none

	character(len=*), intent(out) :: FILEVERSION

	integer(4)         Hndl
	integer(4)         nBytes
	integer(4)         rc
	character(len=256) StringInfo

	integer(4)         uVersionLen
	integer(4)         lpstrVffInfo
	character(100)     lpVersion
	integer(4)         hMem
	integer(4)         i

	character(MAX_PATH) szFilename

	pointer(lplpVersion, lpversion)


	rc = GetModuleFileName(NULL, szFilename, MAX_PATH)
	nBytes = GetFileVersionInfoSize(szFilename, LOC(Hndl))

	if (nBytes /= 0) then
		hMem = GlobalAlloc(GMEM_MOVEABLE, int(nBytes))
		lpstrVffInfo = GlobalLock(hMem)
		rc = GetFileVersionInfo(szFilename, Hndl, nBytes, lpstrVffInfo )

		StringInfo = "\\StringFileInfo\\040904b0\\FileVersion"C  !hex 040904b0 is the code page set in the resource file
		rc = VerQueryValue(lpstrVffInfo, loc(StringInfo), lplpVersion, loc(uVersionLen))
		if (rc /= 0) then
			rc = lstrcpy(FILEVERSION, lpVersion)
			uVersionLen = min(uVersionLen,index(FILEVERSION,char(0)))
			do i=uVersionLen,len(FILEVERSION)
				FILEVERSION(i:i) = ' '
			end do
		else
			FILEVERSION = 'n.c'
		end if
 
		rc = GlobalUnlock(hMem)
		rc = GlobalFree(hMem)
	else
		FILEVERSION = 'n.c'
	end if
end

 

0 Kudos
Steven_L_Intel1
Employee
2,257 Views

Your code won't work in a 64-bit application. See bmchenry's post above yours.

0 Kudos
Reply