summaryrefslogtreecommitdiff
path: root/Include/UpgradeDLL.nsh
blob: ba10674c656d6c487fe0f9c2bd7c66a2e706521c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*

NOTE:
-----
This macro is provided for backwards compatibility with NSIS 2.0 scripts.
It's recommended you update your scripts to use the new Library.nsh macros.


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/ME support, this should be on the same volume as 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.

Notes:

* If you want to support Windows 9x/ME, you can only use short filenames (8.3).

* This macro uses the GetDLLVersionLocal command to retrieve the version of local libraries.
  This command is only supported when compiling on a Windows system.

------------------------

Example:

!insertmacro UpgradeDLL "dllname.dll" "$SYSDIR\dllname.dll" "$SYSDIR"

*/

!ifndef UPGRADEDLL_INCLUDED

!define UPGRADEDLL_INCLUDED

!macro __UpgradeDLL_Helper_AddRegToolEntry mode filename tempdir

  Push $R0
  Push $R1
  Push $R2
  Push $R3

  ;------------------------
  ;Copy the parameters

  Push "${filename}"
  Push "${tempdir}"

  Pop $R2 ; temporary directory
  Pop $R1 ; file name to register

  ;------------------------
  ;Advance counter

  StrCpy $R0 0
  ReadRegDWORD $R0 HKLM "Software\NSIS.Library.RegTool.v2\UpgradeDLLSession" "count"
  IntOp $R0 $R0 + 1
  WriteRegDWORD HKLM "Software\NSIS.Library.RegTool.v2\UpgradeDLLSession" "count" "$R0"

  ;------------------------
  ;Setup RegTool

  ReadRegStr $R3 HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" "NSIS.Library.RegTool.v2"
  StrCpy $R3 $R3 -4 1
  IfFileExists $R3 +3

    File /oname=$R2\NSIS.Library.RegTool.v2.$HWNDPARENT.exe "${NSISDIR}\Bin\RegTool.bin"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \
      "NSIS.Library.RegTool.v2" '"$R2\NSIS.Library.RegTool.v2.$HWNDPARENT.exe" /S'

  ;------------------------
  ;Add RegTool entry

  WriteRegStr HKLM "Software\NSIS.Library.RegTool.v2\UpgradeDLLSession" "$R0.file" "$R1"
  WriteRegStr HKLM "Software\NSIS.Library.RegTool.v2\UpgradeDLLSession" "$R0.mode" "${mode}"

  Pop $R3
  Pop $R2
  Pop $R1
  Pop $R0

!macroend

!macro UpgradeDLL LOCALFILE DESTFILE TEMPBASEDIR

  Push $R0
  Push $R1
  Push $R2
  Push $R3
  Push $R4
  Push $R5

  !define UPGRADEDLL_UNIQUE "${__FILE__}${__LINE__}"

  SetOverwrite try

  ;------------------------
  ;Copy the parameters used on run-time to a variable
  ;This allows the usage of variables as paramter

  StrCpy $R4 "${DESTFILE}"
  StrCpy $R5 "${TEMPBASEDIR}"

  ;------------------------
  ;Get version information

  IfFileExists $R4 0 "upgradedll.copy_${UPGRADEDLL_UNIQUE}"

  ClearErrors
    GetDLLVersionLocal "${LOCALFILE}" $R0 $R1
    GetDLLVersion $R4 $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}"

  ;------------------------
  ;Upgrade

  "upgradedll.upgrade_${UPGRADEDLL_UNIQUE}:"
    !ifndef UPGRADEDLL_NOREGISTER
      ;Unregister the DLL
      UnRegDLL $R4
    !endif

  ;------------------------
  ;Copy

  ClearErrors
    StrCpy $R0 $R4
    Call ":upgradedll.file_${UPGRADEDLL_UNIQUE}"
  IfErrors 0 "upgradedll.noreboot_${UPGRADEDLL_UNIQUE}"

  ;------------------------
  ;Copy on reboot

  GetTempFileName $R0 $R5
    Call ":upgradedll.file_${UPGRADEDLL_UNIQUE}"
  Rename /REBOOTOK $R0 $R4

  ;------------------------
  ;Register on reboot

  !insertmacro __UpgradeDLL_Helper_AddRegToolEntry 'D' $R4 $R5

  Goto "upgradedll.done_${UPGRADEDLL_UNIQUE}"

  ;------------------------
  ;DLL does not exist

  "upgradedll.copy_${UPGRADEDLL_UNIQUE}:"
    StrCpy $R0 $R4
    Call ":upgradedll.file_${UPGRADEDLL_UNIQUE}"

  ;------------------------
  ;Register

  "upgradedll.noreboot_${UPGRADEDLL_UNIQUE}:"
    !ifndef UPGRADEDLL_NOREGISTER
      RegDLL $R4
    !endif

  ;------------------------
  ;Done

  "upgradedll.done_${UPGRADEDLL_UNIQUE}:"

  Pop $R5
  Pop $R4
  Pop $R3
  Pop $R2
  Pop $R1
  Pop $R0

  ;------------------------
  ;End

  Goto "upgradedll.end_${UPGRADEDLL_UNIQUE}"

  ;------------------------
  ;Extract

  "upgradedll.file_${UPGRADEDLL_UNIQUE}:"
    File /oname=$R0 "${LOCALFILE}"
    Return

  "upgradedll.end_${UPGRADEDLL_UNIQUE}:"

  SetOverwrite lastused
  
  !undef UPGRADEDLL_UNIQUE

!macroend

!endif