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.
Is it possible to locate a file from version information property?
16 posts
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
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
MD5 plugin usedName "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
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.
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
-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:
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 🙂
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 uselessSorry, 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
-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
If not, please ask again and I'll whip up some sample code.
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
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 🙂md5dll::GetMD5File "$R9"
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.
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.
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:
The NSIS script:
The InstallOptions INI:!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
[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