Archive: Is it possible to locate a file from version information property?


Is it possible to locate a file from version information property?
well, here is the scenario. I want to check a target machine if "myapp.dll" is installed and update it if needed with new one. Some strange user for some strange reason has renamed "myapp.dll" in "another.dll". As far as I know by any documented way, there is not way to search and locate the file. My question is, could be possible to search all files in a dir looking at version information property tab? For example in description or in comments or in original file name? Is it possible for someone to grab such info?
Note that the file is not shared or self registered etc so there are not any info in registry.

P.S. OK, someone would say that the above is useless in real world. It is just a study affair.


Have you looked into http://nsis.sourceforge.net/wiki/MD5_plugin ?


That there ^^ is your best solution.
Iterate through the files with FindFirst, FindNext, FindClose and compare each found files' MD5 checksum with a hardcoded checksum in a !define of the particular dll file that you are after. Obviously though if there are a lot of dll files in the folder it could take a while. If this is the case you could get a count of the files in the directory first and show a progress banner with the Banner plugin.

-Stu


Name "Output"
OutFile "Output.exe"

!include "FileFunc.nsh"
!insertmacro Locate

!define DLL_PATH "C:\ftp"
!define DLL_SIZE_BYTES "158720"
!define DLL_MD5 "be65a68caf476e39ff62af6813d0198f"

Section
StrCpy $R0 ''

${Locate} "${DLL_PATH}" "/L=F /M=*.dll /S=0B" "LocateCallback"

IfErrors 0 +2
MessageBox MB_OK "Error" IDOK +2
MessageBox MB_OK "$$R0={$R0}"
SectionEnd

Function LocateCallback
StrCmp $R6 ${DLL_SIZE_BYTES} 0 end

md5dll::GetMD5File "$R9"
Pop $0

StrCmp $0 ${DLL_MD5} 0 end
StrCpy $R0 $R9
StrCpy $0 StopLocate

end:
Push $0
FunctionEnd
MD5 plugin used

Thank you all!
i would say that the best reason why one should use NSIS is the instant and detailed feedback from the community.
As I am examining the above by instructor I am able to find any file that I am looking for.
Therefore, I understand that the conclusion is that it is not possible to grab details from the version information property tab.


It probably is possible, but using an MD5 would be a better solution as an MD5 checksum is unique to every non-identical file.

-Stu


I guess the only problem is that that's probably the least scaleable solution possible :)


Therefore, I understand that the conclusion is that it is not possible to grab details from the version information property tab.
There is a plugin which can be used to extract this information. It handles the standard Version Information fields and can also extract user defined entries:

http://nsis.sourceforge.net/MoreInfo_plug-in

well, MoreInfo plug-in is not the case since it requires a specific file name in the filename parameter, thereby it is useless on the above scenario.


Red Wine,

please see the example code from Instructor, the same method can be used with the MoreInfo plugin, just iterate through all the files matching your search filter. So it's not useless :)


please see the example code from Instructor, the same method can be used with the MoreInfo plugin, just iterate through all the files matching your search filter. So it's not useless
Sorry, I stuck here, I can't figure it out...
Could you please set up an example just like the way Instructor did?

Thanks in advance

$R9 is the dll path and name.

-Stu


Red Wine:

See Instructors code above, do you see the LocateCallback function? That is where all the work takes place. This function gets called for each file that matches the search pattern. Now, instead of

md5dll::GetMD5File "$R9"

just use any suitable function from the MoreInfo plugin. $R9 contains the full path and filename of the file found. I am too lazy to make up some sample code now, as I am still chewing on strange skinning effects, but I am sure you can figure it out now :)
If not, please ask again and I'll whip up some sample code.

I think I'll figure it out now, thanks.
BTW examining some of the above I made a kind of auto creation for MD5 checksums. Please take a look.


It took me a while, though, I figured out how it works.
With the compination of Locate and MoreInfo plug-in is possible to find any file in a target without the need to provide the file name nor the exact file size. All it needs is the file extension and the info from a supported by MoreInfo plug-in field.

Name "locate with moreinfo"
OutFile "locate_moreinfo.exe"
ShowInstDetails show

!include "FileFunc.nsh"
!insertmacro Locate
!insertmacro GetRoot

!define DLL_PATH "$1"
!define DLL_ProductName "My App® for Windows"

Function .onInit
${GetRoot} "$PROGRAMFILES" "$1"
FunctionEnd

Section
StrCpy $R0 ''

${Locate} "${DLL_PATH}" "/L=F /M=*.dll /S=0B" "LocateCallback"

IfErrors 0 +2
MessageBox MB_OK "Error" IDOK +2
MessageBox MB_OK "$$R0={$R0}"
DetailPrint "$$R0={$R0}"
SectionEnd

Function LocateCallback
MoreInfo::GetProductName "$R9"
Pop $0

StrCmp '$0' '${DLL_ProductName}' 0 end
StrCpy "$R0" "$R9"
StrCpy "$0" StopLocate

end:
Push "$0"
FunctionEnd

According to my quest for the given above scenario I had to navigate through the maze of several NSIS plugins and headers. The benefit is that I got my self a little deeper inside NSIS scripting and being able to make a fancy gui frontend for the md5dll. As far as I'm testing it on my XP-SP2 system I can't find any noteworthy bug. I'd like to kindly request the community to examine it and drop me a note if there is any.

The NSIS script:

!include 'TextFunc.nsh'
!include 'FileFunc.nsh'
!include 'WinMessages.nsh'
!include 'LogicLib.nsh'
!include 'StrFunc.nsh'

${StrIOToNSIS}

!define TEMP1 $R0
!define LOG "$EXEDIR\MD5_Builder.Log"

!insertmacro FileJoin
!insertmacro GetTime
!insertmacro GetFileName

var md5_result
var FILE_NAME
var file
var day
var month
var year
var weekday
var hour
var min
var sec
var ctlcolor

Name "MD5 CheckSum Builder"
Caption "MD5 CheckSum Builder"
OutFile "Builder.exe"
BrandingText " "
XPstyle on

ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
ReserveFile "builder.ini"

Page custom SetCustom ValidateCustom ": Select a file"
PageEx instfiles
Caption ": Building MD5 CheckSum"
PageCallbacks "" "" InstFilesLeave
PageExEnd


Section "builder"
HideWindow

ReadINIStr '${TEMP1}' "$PLUGINSDIR\builder.ini" "Field 2" "State"
StrCpy '$FILE_NAME' '${TEMP1}'

${If} ${FileExists} "$FILE_NAME"
ReadINIStr ${TEMP1} "$PLUGINSDIR\builder.ini" "Field 5" "State"
${Unless} ${TEMP1} == "1"
${GetFileName} "$FILE_NAME" $file
Call Get_Time
ReadINIStr ${TEMP1} "$PLUGINSDIR\builder.ini" "Field 4" "State"
ClearErrors
Call Build_md5
IfErrors _errors
${Select} "${TEMP1}"
${case} ""
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 4" "State" \
"MD5 checksum created at $weekday $day-$month-$year $hour:$min:$sec \
\r\n------------------------------------------------------------------------\r\nMD5 \
checksum for $file is: \r\n$md5_result"
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 3" "Flags" ""
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 5" "Flags" ""
StrCpy $ctlcolor "1"
${caseElse}
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 4" "State" \
"${TEMP1} \r\n\r\nMD5 checksum for $file is: \r\n$md5_result"
StrCpy $ctlcolor "1"
${EndSelect}
${EndUnless}
${EndIf}

ReadINIStr ${TEMP1} "$PLUGINSDIR\builder.ini" "Field 5" "State"

${If} ${TEMP1} == '1'
${AndIf} ${FileExists} "${LOG}"
ClearErrors
GetTempFileName $R7 $PLUGINSDIR
FileOpen $R8 $R7 a
ReadIniStr "${TEMP1}" "$PLUGINSDIR\builder.ini" "Field 4" "State"
${StrIOToNSIS} $R0 "${TEMP1}"
FileWrite $R8 "$R0 $\r$\n$\r$\n$\r$\n"
FileClose $R8
IfErrors _errors
${FileJoin} "${LOG}" "$R7" ""
IfErrors _errors
Exec '"notepad.exe" "${LOG}"'
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 3" "Flags" "DISABLED"
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 5" "Flags" "DISABLED"
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 4" "State" ""

${ElseIf} ${TEMP1} == '1'
ClearErrors
GetTempFileName $R7 $PLUGINSDIR
FileOpen $R8 $R7 a
ReadIniStr "${TEMP1}" "$PLUGINSDIR\builder.ini" "Field 4" "State"
${StrIOToNSIS} $R0 "${TEMP1}"
FileWrite $R8 "$R0 $\r$\n$\r$\n$\r$\n"
FileClose $R8
IfErrors _errors
Rename $R7 "${LOG}"
Exec '"notepad.exe" "${LOG}"'
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 3" "Flags" "DISABLED"
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 5" "Flags" "DISABLED"
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 4" "State" ""
${EndIf}


${If} ${Errors}
_errors:
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 4" "State" \
"MD5 checksum created at $weekday $day-$month-$year $hour:$min:$sec \
\r\n------------------------------------------------------------------------\r\nError \
creating MD5 checksum for $file"
MessageBox MB_OK|MB_ICONSTOP 'Error creating MD5 checksum for $file'
${EndIf}

WriteIniStr "$PLUGINSDIR\builder.ini" "Field 2" "State" ""
WriteIniStr "$PLUGINSDIR\builder.ini" "Field 5" "State" ""
SectionEnd


Function .onInit
InitPluginsDir
File /oname=$PLUGINSDIR\builder.ini "_builder.ini"
FunctionEnd


Function Get_Time
${GetTime} "" "L" $day $month $year $weekday $hour $min $sec
FunctionEnd


Function Build_md5
md5dll::GetMD5File "$FILE_NAME"
Pop $0
StrCpy "$md5_result" "$0"
Push $0
FunctionEnd


Function SetCustom
${If} $ctlcolor == "1"
Push ${TEMP1}
Push $6
InstallOptions::initDialog /NOUNLOAD "$PLUGINSDIR\builder.ini"
Pop ${TEMP1}
ReadINIStr $6 "$PLUGINSDIR\builder.ini" "Field 3" "HWND"
SetCtlColors $6 0x3E55B0 transparent
ReadINIStr $6 "$PLUGINSDIR\builder.ini" "Field 4" "HWND"
SetCtlColors $6 0x000000 0xFFFFFF
InstallOptions::show
Pop ${TEMP1}
Pop $6
${Else}
Push ${TEMP1}
InstallOptions::dialog "$PLUGINSDIR\builder.ini"
Pop ${TEMP1}
Pop ${TEMP1}
${EndIf}
FunctionEnd


Function ValidateCustom
ReadINIStr '${TEMP1}' "$PLUGINSDIR\builder.ini" "Field 5" "State"
${If} ${TEMP1} <> "1"
ReadINIStr '${TEMP1}' "$PLUGINSDIR\builder.ini" "Field 2" "State"
${EndIf}
${If} ${TEMP1} == ""
MessageBox MB_ICONEXCLAMATION|MB_OK "You must select a valid file!"
Abort
${EndIf}
StrCpy $ctlcolor ""
FunctionEnd

Function InstFilesLeave
Bringtofront
SendMessage $HWNDPARENT "0x408" "-1" "0"
Abort
FunctionEnd


The InstallOptions INI:
[Settings]
NumFields=5
NextButtonText=Build
CancelButtonText=Close

[Field 1]
Type=GroupBox
Left=0
Right=-1
Top=0
Bottom=-1
Text=" Browse for the file to create the MD5 checksum... "

[Field 2]
Type=FileRequest
Left=11
Right=-11
Top=25
Bottom=38
Filter=Program Files|*.exe|DLL Files|*.dll|All files|*.*
Flags=FILE_MUST_EXIST|FILE_EXPLORER

[Field 3]
Type=Label
Left=14
Right=-120
Top=45
Bottom=55
Text="MD5 Checksum Builder Log"
Flags=DISABLED

[Field 4]
Type=Text
Flags=VSCROLL|MULTILINE|READONLY
State=
Left=11
Right=-12
Top=56
Bottom=112

[Field 5]
Type=radiobutton
Text=" Dump Log Window to file"
Left=12
Right=-120
Top=116
Bottom=124
State=
Flags=DISABLED