forked from VOICEVOX/voicevox
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfuncs.nsh
377 lines (337 loc) · 11.9 KB
/
funcs.nsh
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
!ifndef VOICEVOX_FUNCS_INCLUDED
!define VOICEVOX_FUNCS_INCLUDED
; このファイルには独自に定義した定数や変数には依存しない処理だけをまとめておく
!include "LogicLib.nsh"
!include "FileFunc.nsh"
; ${myQuitError} ExitCode
; インストーラーをエラー終了する
; エラーコード一覧は以下
; https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
; @param ExitCode 終了コード、空を渡すと新しく設定しない
!define myQuitError "!insertmacro myQuitError"
!macro myQuitError ExitCode
; ここで終了するのでレジスターの内容を退避/復帰させなくてもいい
StrCpy $0 "${ExitCode}"
${If} $0 != ""
SetErrorLevel $0
${EndIf}
Quit
!macroend
; ${myQuit}
; 後処理をしてインストーラーを終了する
; 終了コードは既に設定されているものを使用する
!define myQuit `!insertmacro myQuitError ""`
; ${myQuitSuccess}
; 後処理をしてインストーラーを正常終了する
!define myQuitSuccess "!insertmacro myQuitError 0"
; ${getArchiveNameAndHash} ResultPath ResultHash
; 結合済みのファイルについての情報を取得する
; @return ResultPath 結合済みファイルで使うべきファイル名
; @return ResultHash 結合済みファイルで期待される SHA2-512 でのハッシュ値(16進数大文字)
!define getArchiveNameAndHash "!insertmacro getArchiveNameAndHash"
!macro getArchiveNameAndHash ResultPath ResultHash
Push $0 ; Stack $0
Push $1 ; $1 $0
; electron-builder のスクリプトに基づいたハッシュ値と対象ファイル名の取得
; https://github.com/electron-userland/electron-builder/blob/28cb86bdcb6dd0b10e75a69ccd34ece6cca1d204/packages/app-builder-lib/templates/nsis/include/installer.nsh#L17-L70
!ifdef APP_64_NAME
!ifdef APP_32_NAME
!ifdef APP_ARM64_NAME
${if} ${IsNativeARM64}
StrCpy $0 "${APP_ARM64_NAME}"
StrCpy $1 "${APP_ARM64_HASH}"
${elseif} ${IsNativeAMD64}
StrCpy $0 "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
${else}
StrCpy $0 "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
${endif}
!else
${if} ${RunningX64}
StrCpy $0 "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
${else}
StrCpy $0 "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
${endif}
!endif
!else
StrCpy $0 "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
!endif
!else
StrCpy $0 "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
!endif
; Stack $1 $0
Exch $1 ; <ResultHash> $0
Exch ; $0 <ResultHash>
Exch $0 ; <ResultPath> <ResultHash>
Pop "${ResultPath}" ; <ResultHash>
Pop "${ResultHash}" ; -empty-
!macroend
; ${getFileSize} Result Path
; ファイルサイズを取得する
; ファイルへのアクセスに失敗した場合はエラーフラグが立つ
; @param Path ファイルへのパス
; @return Result ファイルサイズ(バイト)
!define getFileSize "!insertmacro getFileSize"
!macro getFileSize Result Path
Push "${Path}" ; Stack <Path>
Exch $0 ; $0
Push $1 ; $1 $0
ClearErrors
FileOpen $1 $0 "r"
${IfNot} ${Errors}
FileSeek $1 0 "END" $0
FileClose $1
${Else}
StrCpy $0 0
${EndIf}
; Stack $1 $0
Pop $1 ; $0
Exch $0 ; <Result>
Pop "${Result}" ; -empty-
!macroend
; ${bytesToHumanReadable} Result Input
; バイト単位のサイズを人間が読みやすい表現に変換する
; @param Input バイト単位での容量
; @return Result "1.63 GB" などの人間が読みやすい表記での容量
!define bytesToHumanReadable "!insertmacro bytesToHumanReadable"
!macro bytesToHumanReadable Result Input
Push "${Input}" ; Stack <Input>
Exch $0 ; $0
Push $1 ; $1 $0
Push $2 ; $2 $1 $0
Push $3 ; $3 $2 $1 $0
StrCpy $3 0
${Do}
StrLen $2 $0
${If} $2 > 3 ; 1000 以上あるか?
; 次の単位へ
StrCpy $1 $0 ; 割る前の値も控えておく
System::Int64Op $0 / 1024
Pop $0
IntOp $3 $3 + 1
${Else}
${ExitDo}
${EndIf}
${Loop}
; 小数点以下の部分を作る
; 1.63 や 16.3 や 163 など値の大きさに合わせて桁数を変える
IntOp $1 $1 * 100
IntOp $1 $1 / 1024
IntOp $1 $1 % 100
${If} $2 == 1
StrCpy $0 "$0.$1"
${ElseIf} $2 == 2
IntOp $1 $1 / 10
StrCpy $0 "$0.$1"
${EndIf}
${If} $3 == 0
StrCpy $0 $1
StrCpy $1 "バイト"
${ElseIf} $3 == 1
StrCpy $1 "KB"
${ElseIf} $3 == 2
StrCpy $1 "MB"
${ElseIf} $3 == 3
StrCpy $1 "GB"
${ElseIf} $3 == 4
StrCpy $1 "TB"
${ElseIf} $3 == 5
StrCpy $1 "PB"
${ElseIf} $3 == 6
StrCpy $1 "EB" ; 符号付き 64bit 整数の限界
${EndIf}
StrCpy $0 "$0 $1"
; Stack $3 $2 $1 $0
Pop $3 ; $2 $1 $0
Pop $2 ; $1 $0
Pop $1 ; $0
Exch $0 ; <Result>
Pop "${Result}" ; -empty-
!macroend
; ${getDiskSpace} Result Dir
; Dir に指定されたディレクトリーがあるドライブの空き容量をバイト単位で取得する
; Windows 標準機能でドライブをフォルダーへマウントしたりすると
; C:\somedir の空き容量が C:\ と一致するとは限らないため、調べたいディレクトリーを渡す必要がある
; @param Dir 空き容量を調べたいディレクトリー
; @return Result インストール先の空き容量(バイト単位)、失敗時は ""
!define getDiskSpace "!insertmacro getDiskSpace"
!macro getDiskSpace Result Dir
Push "${Dir}" ; Stack <Dir>
Exch $0 ; $0
Push $1 ; $1 $0
; 存在しないディレクトリーだと失敗するので親を辿る
getDiskSpace_loop:
${IfNot} ${FileExists} "$0\*.*"
${GetParent} $0 $0
Goto getDiskSpace_loop
${EndIf}
; Input
; $0 = 空き容量を調べたいディレクトリー
; Output
; $0 = 取得した空き容量
; $1 = 成功したかどうか
System::Call 'kernel32::GetDiskFreeSpaceEx(t r0, *l .r0, l 0, l 0) i .r1'
${If} $1 == '0'
StrCpy $0 ""
${EndIf}
Pop $1 ; $0
Exch $0 ; <Result>
Pop "${Result}" ; -empty-
!macroend
; ${verifyFile} Result FilePath HashAlgo Hash
; ファイルのハッシュ値を求めて検証する
; 使用可能なハッシュアルゴリズム名は以下を参照
; http://muldersoft.com/docs/stdutils_readme.html#e1f7e07b
; @param FilePath ファイルへのパス
; @param HashAlgo ハッシュアルゴリズム名
; @param Hash ハッシュ値(大文字16進数)
; @return Result "OK", "Failed" のどれか
!define verifyFile "!insertmacro verifyFile"
!macro verifyFile Result FilePath HashAlgo Hash
Push "${Hash}"
Push "${HashAlgo}"
Push "${FilePath}" ; Stack <FilePath> <HashAlgo> <Hash>
Exch $0 ; $0 <HashAlgo> <Hash>
Exch ; <HashAlgo> $0 <Hash>
Exch $1 ; $1 $0 <Hash>
Exch ; $0 $1 <Hash>
Exch 2 ; <Hash> $1 $0
Exch $2 ; $2 $1 $0
${StdUtils.HashFile} $0 "$1" "$0"
${If} $0 == $2
StrCpy $0 "OK"
${Else}
StrCpy $0 "Failed"
${EndIf}
; Stack $2 $1 $0
Pop $2 ; $1 $0
Pop $1 ; $0
Exch $0 ; <Result>
Pop "${Result}" ; -empty-
!macroend
; ${concatenateFile} Result DestPath BasePath NumFiles
; BasePath の末尾に ".0" のような 0 始まりの通し番号をつけたファイルを
; NumFiles 個連結して DestPath へ保存する
; @param DestPath 保存先へのパス
; @param BasePath 連結したいファイル
; @param NumFiles 連結する個数
; @return Result "OK", "Failed" のどれか
!define concatenateFile "!insertmacro concatenateFile"
!macro concatenateFile Result DestPath BasePath NumFiles
Push "${NumFiles}" ; Stack <NumFiles>
Push "${BasePath}" ; <BasePath> <NumFiles>
Push "${DestPath}" ; <DestPath> <BasePath> <NumFiles>
Exch $0 ; $0 <BasePath> <NumFiles>
Exch ; <BasePath> $0 <NumFiles>
Exch $1 ; $1 $0 <NumFiles>
Exch ; $0 $1 <NumFiles>
Exch 2 ; <NumFiles> $1 $0
Exch $2 ; $2 $1 $0
Push $3 ; $3 $2 $1 $0
Push $4 ; $4 $3 $2 $1 $0
StrCpy $4 $0 ; $4 = DestPath
StrCpy $3 $1 ; $3 = BasePath
IntOp $2 $2 - 1 ; $2 = NumFiles - 1
; 各パートのファイル名を連結していく
StrCpy $1 ""
${ForEach} $0 0 $2 + 1
StrCpy $1 `$1 + "$3.$0"`
${Next}
; ` + "BasePath.0" + "BasePath.1"`
; のような構造になっているので最初の3文字を削る
StrCpy $1 $1 "" 3
; ファイルを連結する
nsExec::ExecToStack '"$SYSDIR\cmd.exe" /C COPY /B $1 "$4"'
Pop $0 ; ステータス
Pop $1 ; エラーメッセージ(ここでは使わない)
${If} $0 == "0"
StrCpy $0 "OK"
${Else}
Delete "$4"
StrCpy $0 "Failed"
${EndIf}
; Stack $4 $3 $2 $1 $0
Pop $4 ; $3 $2 $1 $0
Pop $3 ; $2 $1 $0
Pop $2 ; $1 $0
Pop $1 ; $0
Exch $0 ; <Result>
Pop "${Result}" ; -empty-
!macroend
; ${getUncompressedSizeFrom7z} Result Path
; 7z アーカイブから展開後の総容量を求める
; "$PLUGINSDIR\7zr.exe" に事前にプログラムを配置しておくこと
; @param Path 7zアーカイブへのパス
; @return Result バイト単位での総容量, "Failed to execute 7zr.exe", "Failed to open file list" のどれか
!define getUncompressedSizeFrom7z "!insertmacro getUncompressedSizeFrom7z"
!macro getUncompressedSizeFrom7z Result Path
Push "${Path}" ; Stack <Path>
Exch $0 ; $0
Push $1 ; $1 $0
Push $2 ; $2 $1 $0
Push $3 ; $3 $2 $1 $0
; /C の後ろ全体をダブルクォートで括る必要がある
; https://superuser.com/a/238813
nsExec::ExecToStack '"$SYSDIR\cmd.exe" /C ""$PLUGINSDIR\7zr.exe" l -slt "$0" > "$PLUGINSDIR\7zlist.txt""'
Pop $0 ; ステータス
Pop $1 ; エラーメッセージ(ここでは使わない)
${If} $0 != "0"
StrCpy $0 "Failed to execute 7zr.exe"
Goto getUncompressedSizeFrom7z_finish
${EndIf}
ClearErrors
FileOpen $2 "$PLUGINSDIR\7zlist.txt" "r"
${If} ${Errors}
StrCpy $0 "Failed to open file list"
Goto getUncompressedSizeFrom7z_finish
${EndIf}
; 1行ずつ読んで展開後のサイズを加算していく
; $1 = 現在行のテキスト
; $2 = ファイルポインター
; $3 = 総容量
StrCpy $3 0
FileRead $2 $1
${DoUntil} ${Errors}
StrCpy $0 $1 7 ; 最初の7文字を取り出す
${If} $0 == "Size = " ; 展開後のサイズが書いてある行か?
StrCpy $0 $1 "" 7 ; 数値部分を取り出す
System::Int64Op $3 + $0
Pop $3
${EndIf}
FileRead $2 $1
${Loop}
FileClose $2
StrCpy $0 $3
getUncompressedSizeFrom7z_finish:
; Stack $3 $2 $1 $0
Pop $3 ; $2 $1 $0
Pop $2 ; $1 $0
Pop $1 ; $0
Exch $0 ; <Result>
Pop "${Result}" ; -empty-
!macroend
; ${updateBannerText} Text
; 表示中の Banner のテキストを更新する
; Example の内容に基づく
; https://github.com/NSIS-Dev/Documentation/blob/master/Plugins/Banner.md#example
; @param Text 表示するテキスト
!define updateBannerText "!insertmacro updateBannerText"
!macro updateBannerText Text
Push "${Text}" ; Stack <Text>
Exch $0 ; $0
Push $1 ; $1 $0
Push $2 ; $2 $1 $0
Banner::getWindow
Pop $1
GetDlgItem $2 $1 1030
SendMessage $2 ${WM_SETTEXT} 0 "STR:$0"
Pop $2
Pop $1
Pop $0
!macroend
!endif