UpgradeDLL include file, VB6 runtime installation

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3130 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
joostverburg 2003-11-12 12:55:13 +00:00
parent 6622a27977
commit 352f409053
3 changed files with 187 additions and 17 deletions

View file

@ -443,6 +443,8 @@
\H{upgradedll} Upgrade a DLL (macro)
There is also a copy of this macro in the Include folder, so you only have to include UpgradeDLL.nsh to use it.
\c ; Macro - Upgrade DLL File
\c ; Written by Joost Verburg
\c ; ------------------------

View file

@ -80,11 +80,11 @@ If both NoModify and NoRepair are set to 1, the button displays "Remove" instead
\H{usefulvb6_runtime} How to install the VB6 runtimes
The best way to install the VB6 runtimes is to use the \R{upgradedll}{UpgradeDLL macro} to upgrade the DLL files, and the \R{addshareddll}{AddSharedDLL macro} when installing the software for the first time to increase the shared DLL count. Define UPGRADEDLL_NOREGISTER before upgrading Stdole2.tlb (and undefine it before upgrading other files).
The best way to install the VB6 runtimes is to use the \R{upgradedll}{UpgradeDLL macro} to upgrade the DLL files and the \R{addshareddll}{AddSharedDLL function} to increment the shared DLL count.
Use the Modern UI with a Finish page to ask for a reboot if required or use \R{IfRebootFlag}{IfRebootFlag} and make your own page or messagebox.
You can extract the files from vbrun60sp5.exe using any archiver that supports CAB compression, or if you have installed the latest version on your system, copy the following files from your system directory:
To get the VB6 runtime files, you can extract the files from vbrun60sp5.exe using any archiver that supports CAB compression or, if you have installed the latest version, copy the the files from the System folder. You need the following files:
Asycfilt.dll \\<br\\>
Comcat.dll \\<br\\>
@ -93,27 +93,29 @@ Oleaut32.dll \\<br\\>
Olepro32.dll \\<br\\>
Stdole2.tlb \\<br\\>
During the uninstallation, use \R{unremovesharedll}{un.RemoveSharedDLL} to decrement the shared DLL count, but remove the Delete /REBOOTOK $R1 line, because the shared DLL registration is not reliable enough for such important system files.
During the uninstallation, use the un.DecrementSharedDLL function below to decrement the shared DLL count (never remove the files, because the shared DLL count is not reliable enough for such imporant files).
\c # Don't forget to copy the macro's!
\c !include "UpgradeDLL.nsh"
\c
\c !define VBFILESDIR C:\Windows\System
\c # or
\c #!define VBFILESDIR C:\Path\to\where\vbrun60sp5.exe\extracted
\c !define VBFILESDIR "C:\Windows\System" ;Location of VB6 runtime files
\c
\c Section "Install VB DLLs"
\c
\c !insertmacro UpgradeDLL ${VBFILESDIR}\Comcat.dll $SYSDIR\Comcat.dll $SYSDIR
\c !insertmacro UpgradeDLL ${VBFILESDIR}\Msvbvm60.dll $SYSDIR\Msvbvm60.dll $SYSDIR
\c !insertmacro UpgradeDLL ${VBFILESDIR}\Oleaut32.dll $SYSDIR\Oleaut32.dll $SYSDIR
\c !insertmacro UpgradeDLL ${VBFILESDIR}\Olepro32.dll $SYSDIR\Olepro32.dll $SYSDIR
\c
\c !define UPGRADEDLL_NOREGISTER
\c !insertmacro UpgradeDLL ${VBFILESDIR}\Asycfilt.dll $SYSDIR\Asycfilt.dll $SYSDIR
\c !insertmacro UpgradeDLL ${VBFILESDIR}\Stdole2.tlb $SYSDIR\Stdole2.tlb $SYSDIR
\c !undef UPGRADEDLL_NOREGISTER
\c # skip shared count increasing if already done once for this application
\c IfFileExists $INSTDIR\myprog.exe skipAddShared
\c
\c ;Only iease DLL count on new installation
\c ;Replace myprog.exe or use another detection method
\c IfFileExists $INSTDIR\myprog.exe skipAddSharedDLL
\c Push $SYSDIR\Asycfilt.dll
\c Call AddSharedDLL
\c Call AncrddSharedDLL
\c Push $SYSDIR\Comcat.dll
\c Call AddSharedDLL
\c Push $SYSDIR\Msvbvm60.dll
@ -124,23 +126,53 @@ During the uninstallation, use \R{unremovesharedll}{un.RemoveSharedDLL} to decre
\c Call AddSharedDLL
\c Push $SYSDIR\Stdole2.tlb
\c Call AddSharedDLL
\c skipAddShared:
\c skipAddSharedDLL:
\c
\c SectionEnd
\c
\c Section "Uninstall"
\c
\c Push $SYSDIR\Asycfilt.dll
\c Call un.RemoveSharedDLL
\c Call un.DecrementSharedDLL
\c Push $SYSDIR\Comcat.dll
\c Call un.RemoveSharedDLL
\c Call un.DecrementSharedDLL
\c Push $SYSDIR\Msvbvm60.dll
\c Call un.RemoveSharedDLL
\c Call un.DecrementSharedDLL
\c Push $SYSDIR\Oleaut32.dll
\c Call un.RemoveSharedDLL
\c Call un.DecrementSharedDLL
\c Push $SYSDIR\Olepro32.dll
\c Call un.RemoveSharedDLL
\c Call un.DecrementSharedDLL
\c Push $SYSDIR\Stdole2.tlb
\c Call un.RemoveSharedDLL
\c Call un.DecrementSharedDLL
\c
\c SectionEnd
\c
\c Function AddSharedDLL
\c Exch $R1
\c Push $R0
\c ReadRegDword $R0 HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1
\c IntOp $R0 $R0 + 1
\c WriteRegDWORD HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 $R0
\c Pop $R0
\c Pop $R1
\c FunctionEnd
\c
\c Function un.DecrementSharedDLL
\c Exch $R1
\c Push $R0
\c ReadRegDword $R0 HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1
\c StrCmp $R0 "" done
\c IntOp $R0 $R0 - 1
\c IntCmp $R0 0 rk rk uk
\c rk:
\c DeleteRegValue HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1
\c Goto done
\c uk:
\c WriteRegDWORD HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 $R0
\c done:
\c Pop $R0
\c Pop $R1
\c FunctionEnd
\H{useful_system_plugin} Calling an external DLL using the System.dll plugin

136
Include/UpgradeDLL.nsh Normal file
View file

@ -0,0 +1,136 @@
!ifndef UPGRADEDLL_INCLUDED
!define UPGRADEDLL_INCLUDED
; Macro - Upgrade DLL File
; Written by Joost Verburg
; ------------------------
;
; Parameters:
; LOCALFILE - Location of the new DLL file (on the compiler system)
; DESTFILE - Location of the DLL file that should be upgraded (on the user's system)
; TEMPBASEDIR - Directory on the user's system to store a temporary file when the system has
; to be rebooted.
; For Win9x support, this should be on the same volume as the DESTFILE!
; The Windows temp directory could be located on any volume, so you cannot use
; this directory.
;
; Define UPGRADEDLL_NOREGISTER if you want to upgrade a DLL that does not have to be registered.
;
; Note: If you want to support Win9x, you can only use short filenames (8.3).
;
; Example of usage:
; !insertmacro UpgradeDLL "dllname.dll" "$SYSDIR\dllname.dll" "$SYSDIR"
;
!macro UpgradeDLL LOCALFILE DESTFILE TEMPBASEDIR
Push $R0
Push $R1
Push $R2
Push $R3
;------------------------
;Unique number for labels
!define UPGRADEDLL_UNIQUE ${__LINE__}
;------------------------
;Check file and version
IfFileExists "${DESTFILE}" 0 upgradedll.copy_${UPGRADEDLL_UNIQUE}
ClearErrors
GetDLLVersionLocal "${LOCALFILE}" $R0 $R1
GetDLLVersion "${DESTFILE}" $R2 $R3
IfErrors upgradedll.upgrade_${UPGRADEDLL_UNIQUE}
IntCmpU $R0 $R2 0 upgradedll.done_${UPGRADEDLL_UNIQUE} upgradedll.upgrade_${UPGRADEDLL_UNIQUE}
IntCmpU $R1 $R3 upgradedll.done_${UPGRADEDLL_UNIQUE} upgradedll.done_${UPGRADEDLL_UNIQUE} \
upgradedll.upgrade_${UPGRADEDLL_UNIQUE}
;------------------------
;Let's upgrade the DLL!
SetOverwrite try
upgradedll.upgrade_${UPGRADEDLL_UNIQUE}:
!ifndef UPGRADEDLL_NOREGISTER
;Unregister the DLL
UnRegDLL "${DESTFILE}"
!endif
;------------------------
;Try to copy the DLL directly
ClearErrors
StrCpy $R0 "${DESTFILE}"
Call :upgradedll.file_${UPGRADEDLL_UNIQUE}
IfErrors 0 upgradedll.noreboot_${UPGRADEDLL_UNIQUE}
;------------------------
;DLL is in use. Copy it to a temp file and Rename it on reboot.
GetTempFileName $R0 "${TEMPBASEDIR}"
Call :upgradedll.file_${UPGRADEDLL_UNIQUE}
Rename /REBOOTOK $R0 "${DESTFILE}"
;------------------------
;Register the DLL on reboot
!ifndef UPGRADEDLL_NOREGISTER
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \
"Register ${DESTFILE}" '"$SYSDIR\rundll32.exe" "${DESTFILE}",DllRegisterServer'
!endif
Goto upgradedll.done_${UPGRADEDLL_UNIQUE}
;------------------------
;DLL does not exist - just extract
upgradedll.copy_${UPGRADEDLL_UNIQUE}:
StrCpy $R0 "${DESTFILE}"
Call :upgradedll.file_${UPGRADEDLL_UNIQUE}
;------------------------
;Register the DLL
upgradedll.noreboot_${UPGRADEDLL_UNIQUE}:
!ifndef UPGRADEDLL_NOREGISTER
RegDLL "${DESTFILE}"
!endif
;------------------------
;Done
upgradedll.done_${UPGRADEDLL_UNIQUE}:
Pop $R3
Pop $R2
Pop $R1
Pop $R0
;------------------------
;End
Goto upgradedll.end_${UPGRADEDLL_UNIQUE}
;------------------------
;Called to extract the DLL
upgradedll.file_${UPGRADEDLL_UNIQUE}:
File /oname=$R0 "${LOCALFILE}"
Return
upgradedll.end_${UPGRADEDLL_UNIQUE}:
;------------------------
;Restore settings
SetOverwrite lastused
!undef UPGRADEDLL_UNIQUE
!macroend
!endif