Microsoft n'expose pas de méthode permettant de détecter, par
programmation, la présence d'une patch, tel que celles offertes dans les Service Packs d'Office.
Une solution de contourner cette lacune est de lire la version actuelle incluse dans les exécutables-mêmes. La table qui suit liste les numéros trouvés en exécutant le code qui suit, tant sur mon système que sur celui de Doug Ware.
|
Exe Name |
|
Pre Office
2000 SR1 |
|
Post Office
2000 SR1 |
|
|
MsAccess.exe |
|
9.0.0.2719 |
|
9.0.0.3822 |
|
WinWord.exe |
|
9.0.0.2717 |
|
9.0.0.3822 |
|
Excel.Exe |
|
9.0.0.2719 |
|
9.0.0.3822 |
|
FrontPage.exe |
|
4.0.2.2717 |
|
4.0.2.3821 |
|
Outlook.exe |
|
9.0.0.2416 |
|
9.0.0.2416 |
|
PowerPnt.exe |
|
9.0.0.2716 |
|
9.0.0.3821 |
|
WinProj.exe |
|
8.0.98.407 |
|
Build not available |
Private Type VS_FIXEDFILEINFO
dwSignature As Long
dwStrucVersion As Long
dwFileVersionMS As Long
dwFileVersionLS As Long
dwProductVersionLS As Long
dwFileFlagsMask As Long
dwProductVersionMS As Long
dwFileFlags As Long
dwFileOS As Long
dwFileType As Long
dwFileSubtype As Long
dwFileDateMS As Long
dwFileDateLS As Long
End Type
Private Declare Function apiGetFileVersionInfoSize _
Lib "version.dll" Alias "GetFileVersionInfoSizeA" _
(ByVal lptstrFilename As String, _
lpdwHandle As Long) _
As Long
Private Declare Function apiGetFileVersionInfo Lib _
"version.dll" Alias "GetFileVersionInfoA" _
(ByVal lptstrFilename As String, _
ByVal dwHandle As Long, _
ByVal dwLen As Long, _
lpData As Any) _
As Long
Private Declare Function apiVerQueryValue Lib _
"version.dll" Alias "VerQueryValueA" _
(pBlock As Any, _
ByVal lpSubBlock As String, _
lplpBuffer As Long, _
puLen As Long) _
As Long
Private Declare Sub sapiCopyMem _
Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)
Function fGetProductVersion(strExeFullPath As String) As String
On Error GoTo ErrHandler
Dim lngSize As Long
Dim lngRet As Long
Dim pBlock() As Byte
Dim lpfi As VS_FIXEDFILEINFO
Dim lppBlock As Long
lngSize = apiGetFileVersionInfoSize( _
strExeFullPath, _
lngRet)
If lngSize Then
ReDim pBlock(lngSize)
lngRet = apiGetFileVersionInfo(strExeFullPath, 0, _
lngSize, pBlock(0))
If Not lngRet = 0 Then
lngRet = apiVerQueryValue(pBlock(0), _
"\", lppBlock, lngSize)
Call sapiCopyMem(lpfi, ByVal lppBlock, lngSize)
With lpfi
fGetProductVersion = HIWord(.dwFileVersionMS) & "." & _
LOWord(.dwFileVersionMS) & "." & _
HIWord(.dwFileVersionLS) & "." & _
LOWord(.dwFileVersionLS)
End With
End If
End If
ExitHere:
Erase pBlock
Exit Function
ErrHandler:
Resume ExitHere
End Function
Private Function LOWord(dw As Long) As Integer
If dw And &H8000& Then
LOWord = dw Or &HFFFF0000
Else
LOWord = dw And &HFFFF&
End If
End Function
Private Function HIWord(dw As Long) As Integer
HIWord = (dw And &HFFFF0000) \ &H10000
End Function