1 |
|
---|
2 |
|
---|
3 | ; Macro - Upgrade DLL File
|
---|
4 | ; Written by Joost Verburg
|
---|
5 | ; ------------------------
|
---|
6 | ;
|
---|
7 | ; Parameters:
|
---|
8 | ; LOCALFILE - Location of the new DLL file (on the compiler system)
|
---|
9 | ; DESTFILE - Location of the DLL file that should be upgraded
|
---|
10 | ; (on the user's system)
|
---|
11 | ; TEMPBASEDIR - Directory on the user's system to store a temporary file
|
---|
12 | ; when the system has to be rebooted.
|
---|
13 | ; For Win9x support, this should be on the same volume as the
|
---|
14 | ; DESTFILE!
|
---|
15 | ; The Windows temp directory could be located on any volume,
|
---|
16 | ; so you cannot use this directory.
|
---|
17 | ;
|
---|
18 | ; Define REPLACEDLL_NOREGISTER if you want to upgrade a DLL that does not
|
---|
19 | ; have to be registered.
|
---|
20 | ;
|
---|
21 | ; Note: If you want to support Win9x, you can only use
|
---|
22 | ; short filenames (8.3).
|
---|
23 | ;
|
---|
24 | ; Example of usage:
|
---|
25 | ; !insertmacro ReplaceDLL "dllname.dll" "$SYSDIR\dllname.dll" "$SYSDIR"
|
---|
26 | ;
|
---|
27 |
|
---|
28 | !macro ReplaceDLL LOCALFILE DESTFILE TEMPBASEDIR
|
---|
29 |
|
---|
30 | Push $R0
|
---|
31 | Push $R1
|
---|
32 | Push $R2
|
---|
33 | Push $R3
|
---|
34 | Push $R4
|
---|
35 | Push $R5
|
---|
36 |
|
---|
37 | ;------------------------
|
---|
38 | ;Unique number for labels
|
---|
39 |
|
---|
40 | !define REPLACEDLL_UNIQUE ${__LINE__}
|
---|
41 |
|
---|
42 | ;------------------------
|
---|
43 | ;Copy the parameters used on run-time to a variable
|
---|
44 | ;This allows the usage of variables as parameter
|
---|
45 |
|
---|
46 | StrCpy $R4 "${DESTFILE}"
|
---|
47 | StrCpy $R5 "${TEMPBASEDIR}"
|
---|
48 |
|
---|
49 | ;------------------------
|
---|
50 | ;Check file and version
|
---|
51 | ;
|
---|
52 | IfFileExists $R4 0 replacedll.copy_${REPLACEDLL_UNIQUE}
|
---|
53 |
|
---|
54 | ;ClearErrors
|
---|
55 | ; GetDLLVersionLocal "${LOCALFILE}" $R0 $R1
|
---|
56 | ; GetDLLVersion $R4 $R2 $R3
|
---|
57 | ;IfErrors replacedll.upgrade_${REPLACEDLL_UNIQUE}
|
---|
58 | ;
|
---|
59 | ;IntCmpU $R0 $R2 0 replacedll.done_${REPLACEDLL_UNIQUE}
|
---|
60 | ; replacedll.upgrade_${REPLACEDLL_UNIQUE}
|
---|
61 | ;IntCmpU $R1 $R3 replacedll.done_${REPLACEDLL_UNIQUE}
|
---|
62 | ; replacedll.done_${REPLACEDLL_UNIQUE}
|
---|
63 | ; replacedll.upgrade_${REPLACEDLL_UNIQUE}
|
---|
64 |
|
---|
65 | ;------------------------
|
---|
66 | ;Let's replace the DLL!
|
---|
67 |
|
---|
68 | SetOverwrite try
|
---|
69 |
|
---|
70 | ;replacedll.upgrade_${REPLACEDLL_UNIQUE}:
|
---|
71 | !ifndef REPLACEDLL_NOREGISTER
|
---|
72 | ;Unregister the DLL
|
---|
73 | UnRegDLL $R4
|
---|
74 | !endif
|
---|
75 |
|
---|
76 | ;------------------------
|
---|
77 | ;Try to copy the DLL directly
|
---|
78 |
|
---|
79 | ClearErrors
|
---|
80 | StrCpy $R0 $R4
|
---|
81 | Call :replacedll.file_${REPLACEDLL_UNIQUE}
|
---|
82 | IfErrors 0 replacedll.noreboot_${REPLACEDLL_UNIQUE}
|
---|
83 |
|
---|
84 | ;------------------------
|
---|
85 | ;DLL is in use. Copy it to a temp file and Rename it on reboot.
|
---|
86 |
|
---|
87 | GetTempFileName $R0 $R5
|
---|
88 | Call :replacedll.file_${REPLACEDLL_UNIQUE}
|
---|
89 | Rename /REBOOTOK $R0 $R4
|
---|
90 |
|
---|
91 | ;------------------------
|
---|
92 | ;Register the DLL on reboot
|
---|
93 |
|
---|
94 | !ifndef REPLACEDLL_NOREGISTER
|
---|
95 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \
|
---|
96 | "Register $R4" 'rundll32.exe "$R4",DllRegisterServer'
|
---|
97 | !endif
|
---|
98 |
|
---|
99 | Goto replacedll.done_${REPLACEDLL_UNIQUE}
|
---|
100 |
|
---|
101 | ;------------------------
|
---|
102 | ;DLL does not exist - just extract
|
---|
103 |
|
---|
104 | replacedll.copy_${REPLACEDLL_UNIQUE}:
|
---|
105 | StrCpy $R0 $R4
|
---|
106 | Call :replacedll.file_${REPLACEDLL_UNIQUE}
|
---|
107 |
|
---|
108 | ;------------------------
|
---|
109 | ;Register the DLL
|
---|
110 |
|
---|
111 | replacedll.noreboot_${REPLACEDLL_UNIQUE}:
|
---|
112 | !ifndef REPLACEDLL_NOREGISTER
|
---|
113 | RegDLL $R4
|
---|
114 | !endif
|
---|
115 |
|
---|
116 | ;------------------------
|
---|
117 | ;Done
|
---|
118 |
|
---|
119 | replacedll.done_${REPLACEDLL_UNIQUE}:
|
---|
120 |
|
---|
121 | Pop $R5
|
---|
122 | Pop $R4
|
---|
123 | Pop $R3
|
---|
124 | Pop $R2
|
---|
125 | Pop $R1
|
---|
126 | Pop $R0
|
---|
127 |
|
---|
128 | ;------------------------
|
---|
129 | ;End
|
---|
130 |
|
---|
131 | Goto replacedll.end_${REPLACEDLL_UNIQUE}
|
---|
132 |
|
---|
133 | ;------------------------
|
---|
134 | ;Called to extract the DLL
|
---|
135 |
|
---|
136 | replacedll.file_${REPLACEDLL_UNIQUE}:
|
---|
137 | File /oname=$R0 "${LOCALFILE}"
|
---|
138 | Return
|
---|
139 |
|
---|
140 | replacedll.end_${REPLACEDLL_UNIQUE}:
|
---|
141 |
|
---|
142 | ;------------------------
|
---|
143 | ;Restore settings
|
---|
144 |
|
---|
145 | SetOverwrite lastused
|
---|
146 |
|
---|
147 | !undef REPLACEDLL_UNIQUE
|
---|
148 |
|
---|
149 | !macroend
|
---|