sign code and uninstallers

This commit is contained in:
antelle 2016-07-22 22:13:39 +03:00
parent 43582ffbef
commit 595142b0ae
14 changed files with 436 additions and 353 deletions

View File

@ -178,11 +178,14 @@ module.exports = function(grunt) {
dest: 'tmp/desktop/KeeWeb-win32-x64/', dest: 'tmp/desktop/KeeWeb-win32-x64/',
nonull: true nonull: true
}, },
'desktop-win32-dist': { 'desktop-win32-dist-x64': {
cwd: 'tmp/desktop', src: 'tmp/desktop/KeeWeb.win.x64.exe',
src: ['KeeWeb.win.x64.exe', 'KeeWeb.win.ia32.exe'], dest: `dist/desktop/KeeWeb-${pkg.version}.win.x64.exe`,
dest: 'dist/desktop/', nonull: true
expand: true, },
'desktop-win32-dist-ia32': {
src: 'tmp/desktop/KeeWeb.win.ia32.exe',
dest: `dist/desktop/KeeWeb-${pkg.version}.win.ia32.exe`,
nonull: true nonull: true
} }
}, },
@ -353,19 +356,19 @@ module.exports = function(grunt) {
files: [{ cwd: 'tmp/desktop/app', src: '**', expand: true }] files: [{ cwd: 'tmp/desktop/app', src: '**', expand: true }]
}, },
'win32-x64': { 'win32-x64': {
options: { archive: 'dist/desktop/KeeWeb.win.x64.zip' }, options: { archive: `dist/desktop/KeeWeb-${pkg.version}.win.x64.zip` },
files: [{ cwd: 'tmp/desktop/KeeWeb-win32-x64', src: '**', expand: true }] files: [{ cwd: 'tmp/desktop/KeeWeb-win32-x64', src: '**', expand: true }]
}, },
'win32-ia32': { 'win32-ia32': {
options: { archive: 'dist/desktop/KeeWeb.win.ia32.zip' }, options: { archive: `dist/desktop/KeeWeb-${pkg.version}.win.ia32.zip` },
files: [{ cwd: 'tmp/desktop/KeeWeb-win32-ia32', src: '**', expand: true }] files: [{ cwd: 'tmp/desktop/KeeWeb-win32-ia32', src: '**', expand: true }]
}, },
'linux-x64': { 'linux-x64': {
options: { archive: 'dist/desktop/KeeWeb.linux.x64.zip' }, options: { archive: `dist/desktop/KeeWeb-${pkg.version}.linux.x64.zip` },
files: [{ cwd: 'tmp/desktop/KeeWeb-linux-x64', src: '**', expand: true }] files: [{ cwd: 'tmp/desktop/KeeWeb-linux-x64', src: '**', expand: true }]
}, },
'linux-ia32': { 'linux-ia32': {
options: { archive: 'dist/desktop/KeeWeb.linux.ia32.zip' }, options: { archive: `dist/desktop/KeeWeb-${pkg.version}.linux.ia32.zip` },
files: [{ cwd: 'tmp/desktop/KeeWeb-linux-ia32', src: '**', expand: true }] files: [{ cwd: 'tmp/desktop/KeeWeb-linux-ia32', src: '**', expand: true }]
} }
}, },
@ -383,12 +386,11 @@ module.exports = function(grunt) {
] ]
}, },
app: { app: {
dest: 'dist/desktop/KeeWeb.mac.dmg' dest: `dist/desktop/KeeWeb-${pkg.version}.mac.dmg`
} }
}, },
nsis: { nsis: {
options: { options: {
installScript: 'package/nsis/main.nsi',
vars: { vars: {
version: pkg.version, version: pkg.version,
rev: function() { return grunt.config.get('gitinfo.local.branch.current.shortSHA'); }, rev: function() { return grunt.config.get('gitinfo.local.branch.current.shortSHA'); },
@ -397,15 +399,31 @@ module.exports = function(grunt) {
}, },
'win32-x64': { 'win32-x64': {
options: { options: {
installScript: 'package/nsis/main.nsi',
arch: 'x64', arch: 'x64',
output: 'tmp/desktop/KeeWeb.win.x64.exe' output: 'tmp/desktop/KeeWeb.win.x64.exe'
} }
}, },
'win32-un-x64': {
options: {
installScript: 'package/nsis/main-un.nsi',
arch: 'x64',
output: 'tmp/desktop/KeeWeb-win32-x64/uninst.exe'
}
},
'win32-ia32': { 'win32-ia32': {
options: { options: {
installScript: 'package/nsis/main.nsi',
arch: 'ia32', arch: 'ia32',
output: 'tmp/desktop/KeeWeb.win.ia32.exe' output: 'tmp/desktop/KeeWeb.win.ia32.exe'
} }
},
'win32-un-ia32': {
options: {
installScript: 'package/nsis/main-un.nsi',
arch: 'ia32',
output: 'tmp/desktop/KeeWeb-win32-ia32/uninst.exe'
}
} }
}, },
deb: { deb: {
@ -423,7 +441,7 @@ module.exports = function(grunt) {
info: { info: {
arch: 'amd64', arch: 'amd64',
targetDir: 'dist/desktop', targetDir: 'dist/desktop',
pkgName: 'KeeWeb.linux.x64.deb', pkgName: `KeeWeb-${pkg.version}.linux.x64.deb`,
appName: 'KeeWeb', appName: 'KeeWeb',
depends: 'libappindicator1', depends: 'libappindicator1',
scripts: { scripts: {
@ -488,16 +506,54 @@ module.exports = function(grunt) {
keytarPasswordService: 'code-sign-win32-keeweb', keytarPasswordService: 'code-sign-win32-keeweb',
keytarPasswordAccount: 'code-sign-win32-keeweb' keytarPasswordAccount: 'code-sign-win32-keeweb'
}, },
'win32-build-x64': {
options: {
files: {
'tmp/desktop/KeeWeb-win32-x64/KeeWeb.exe': 'KeeWeb',
'tmp/desktop/KeeWeb-win32-x64/ffmpeg.dll': '',
'tmp/desktop/KeeWeb-win32-x64/libEGL.dll': 'ANGLE libEGL Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-x64/libGLESv2.dll': 'ANGLE libGLESv2 Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-x64/node.dll': 'Node.js'
}
}
},
'win32-build-ia32': {
options: {
files: {
'tmp/desktop/KeeWeb-win32-ia32/KeeWeb.exe': 'KeeWeb',
'tmp/desktop/KeeWeb-win32-ia32/ffmpeg.dll': '',
'tmp/desktop/KeeWeb-win32-ia32/libEGL.dll': 'ANGLE libEGL Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-ia32/libGLESv2.dll': 'ANGLE libGLESv2 Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-ia32/node.dll': 'Node.js'
}
}
},
'win32-uninst-x64': {
options: {
files: {
'tmp/desktop/KeeWeb-win32-x64/uninst.exe': 'KeeWeb Uninstaller'
}
}
},
'win32-uninst-ia32': {
options: {
files: {
'tmp/desktop/KeeWeb-win32-ia32/uninst.exe': 'KeeWeb Uninstaller'
}
}
},
'win32-installer-x64': { 'win32-installer-x64': {
options: { options: {
file: 'tmp/desktop/KeeWeb.win.x64.exe', files: {
name: 'KeeWeb Setup' 'tmp/desktop/KeeWeb.win.x64.exe': 'KeeWeb Setup'
}
} }
}, },
'win32-installer-ia32': { 'win32-installer-ia32': {
options: { options: {
file: 'tmp/desktop/KeeWeb.win.ia32.exe', files: {
name: 'KeeWeb Setup' 'tmp/desktop/KeeWeb.win.ia32.exe': 'KeeWeb Setup'
}
} }
} }
}, },
@ -547,6 +603,8 @@ module.exports = function(grunt) {
grunt.registerTask('build-desktop-executables', [ grunt.registerTask('build-desktop-executables', [
'electron', 'electron',
'sign-exe:win32-build-x64',
'sign-exe:win32-build-ia32',
'copy:desktop-windows-helper-ia32', 'copy:desktop-windows-helper-ia32',
'copy:desktop-windows-helper-x64' 'copy:desktop-windows-helper-x64'
]); ]);
@ -563,11 +621,16 @@ module.exports = function(grunt) {
]); ]);
grunt.registerTask('build-desktop-dist-win32', [ grunt.registerTask('build-desktop-dist-win32', [
'nsis:win32-un-x64',
'nsis:win32-un-ia32',
'sign-exe:win32-uninst-x64',
'sign-exe:win32-uninst-ia32',
'nsis:win32-x64', 'nsis:win32-x64',
'nsis:win32-ia32', 'nsis:win32-ia32',
'sign-exe:win32-installer-x64', 'sign-exe:win32-installer-x64',
'sign-exe:win32-installer-ia32', 'sign-exe:win32-installer-ia32',
'copy:desktop-win32-dist' 'copy:desktop-win32-dist-x64',
'copy:desktop-win32-dist-ia32'
]); ]);
grunt.registerTask('build-desktop-dist-linux', [ grunt.registerTask('build-desktop-dist-linux', [

View File

@ -12,11 +12,14 @@ module.exports = function (grunt) {
if (typeof value === 'function') { if (typeof value === 'function') {
value = value(); value = value();
} }
args.push(`${prefix}D${key}=${value}`); if (value) {
args.push(`${prefix}D${key}=${value}`);
}
}); });
args.push(`${prefix}Darch=${opt.arch}`); args.push(`${prefix}Darch=${opt.arch}`);
args.push(`${prefix}Doutput=${opt.output}`); args.push(`${prefix}Doutput=${opt.output}`);
args.push(`${prefix}NOCD`); args.push(`${prefix}NOCD`);
args.push(`${prefix}V2`);
args.push(opt.installScript); args.push(opt.installScript);
let executable = win ? 'C:\\Program Files (x86)\\NSIS\\makensis.exe' : 'makensis'; let executable = win ? 'C:\\Program Files (x86)\\NSIS\\makensis.exe' : 'makensis';
grunt.log.writeln('Running NSIS:', args.join(' ')); grunt.log.writeln('Running NSIS:', args.join(' '));

View File

@ -2,6 +2,8 @@
// https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Signing_an_executable_with_Authenticode // https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Signing_an_executable_with_Authenticode
const fs = require('fs');
module.exports = function (grunt) { module.exports = function (grunt) {
grunt.registerMultiTask('sign-exe', 'Signs exe file with authenticode certificate', function () { grunt.registerMultiTask('sign-exe', 'Signs exe file with authenticode certificate', function () {
const keytar = require('keytar'); const keytar = require('keytar');
@ -11,30 +13,44 @@ module.exports = function (grunt) {
if (!password) { if (!password) {
return grunt.warn('Code sign password not found'); return grunt.warn('Code sign password not found');
} }
let spawned = grunt.util.spawn({ let promises = Object.keys(opt.files).map(file => signFile(file, opt.files[file], opt, password));
cmd: 'signcode', Promise.all(promises).then(done);
args: [ });
function signFile(file, name, opt, password) {
let signedFile = file + '.sign';
return new Promise((resolve, reject) => {
let args = [
'-spc', opt.spc, '-spc', opt.spc,
'-v', opt.pvk, '-key', require('path').resolve(opt.pvk),
'-a', opt.algo, '-h', opt.algo,
'-$', 'commercial', '-n', name,
'-n', opt.name,
'-i', opt.url, '-i', opt.url,
'-t', 'http://timestamp.verisign.com/scripts/timstamp.dll', '-t', 'http://timestamp.verisign.com/scripts/timstamp.dll',
'-tr', 10, '-pass', password,
opt.file '-in', file,
] '-out', signedFile
}, (error, result, code) => { ];
if (error || code) { let spawned = grunt.util.spawn({
spawned.kill(); cmd: 'osslsigncode',
return grunt.warn(`signtool error ${code}: ${error}`); args: args
} }, (error, result, code) => {
done(); if (error || code) {
spawned.kill();
grunt.warn(`Cannot sign file ${file}, signtool error ${code}: ${error}`);
return reject();
}
if (fs.existsSync(file)) {
fs.renameSync(signedFile, file);
}
grunt.log.writeln(`Signed: ${file}: ${name}`);
resolve();
});
// spawned.stdout.pipe(process.stdout);
spawned.stderr.pipe(process.stderr);
// spawned.stdin.setEncoding('utf-8');
// spawned.stdin.write(password);
// spawned.stdin.write('\n');
}); });
spawned.stdout.pipe(process.stdout); }
spawned.stderr.pipe(process.stderr);
spawned.stdin.setEncoding('utf-8');
spawned.stdin.write(password);
spawned.stdin.write('\n');
});
}; };

42
package/nsis/check-running.nsh Normal file → Executable file
View File

@ -1,21 +1,21 @@
!macro EnsureAppIsNotRunning !macro EnsureAppIsNotRunning
${Do} ${Do}
nsExec::ExecToStack /OEM 'tasklist /NH /FI "IMAGENAME eq ${PRODUCT_EXE}"' nsExec::ExecToStack /OEM 'tasklist /NH /FI "IMAGENAME eq ${PRODUCT_EXE}"'
Pop $0 Pop $0
${If} $0 != 0 ${If} $0 != 0
DetailPrint "Error checking ${PRODUCT_EXE}: $0" DetailPrint "Error checking ${PRODUCT_EXE}: $0"
MessageBox MB_ICONSTOP|MB_OK "Failed to check whether process is running" MessageBox MB_ICONSTOP|MB_OK "Failed to check whether process is running" /SD IDOK
Quit Quit
${EndIf} ${EndIf}
Pop $1 Pop $1
${StrContains} $0 "${PRODUCT_EXE}" $1 ${StrStr} $0 $1 "${PRODUCT_EXE}"
${If} $0 == "" ${If} $0 == ""
DetailPrint "${PRODUCT_EXE} is not running" DetailPrint "${PRODUCT_EXE} is not running"
${ExitDo} ${ExitDo}
${Else} ${Else}
MessageBox MB_ICONQUESTION|MB_OKCANCEL|MB_DEFBUTTON1 "To proceed, please close ${PRODUCT_NAME} and click OK" /SD IDCANCEL IDOK ok MessageBox MB_ICONQUESTION|MB_OKCANCEL|MB_DEFBUTTON1 "To proceed, please close ${PRODUCT_NAME} and click OK" /SD IDCANCEL IDOK ok
Quit Quit
ok: ok:
${EndIf} ${EndIf}
${Loop} ${Loop}
!macroend !macroend

View File

@ -1,5 +0,0 @@
Name "${PRODUCT_NAME}"
OutFile "${output}"
InstallDir "$PROGRAMFILES\KeeWeb"
ShowInstDetails show
ShowUnInstDetails show

32
package/nsis/defines.nsh Normal file → Executable file
View File

@ -1,18 +1,22 @@
!define PRODUCT_NAME "KeeWeb" !define PRODUCT_NAME "KeeWeb"
!define PRODUCT_VERSION "${version}" !define PRODUCT_VERSION "${version}"
!define PRODUCT_PUBLISHER "KeeWeb" !define PRODUCT_PUBLISHER "KeeWeb"
!define PRODUCT_WEB_SITE "${homepage}" !define PRODUCT_WEB_SITE "${homepage}"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM" !define PRODUCT_UNINST_ROOT_KEY "HKLM"
!define PRODUCT_EXE "KeeWeb.exe" !define PRODUCT_EXE "KeeWeb.exe"
!define PRODUCT_UNINST_TEMP_EXE "KeeWebUninst.exe"
!define MUI_ABORTWARNING
!define MUI_ABORTWARNING
!define MUI_ICON "graphics\icon.ico" !define MUI_ICON "graphics\icon.ico"
!define MUI_UNICON "graphics\icon.ico" !define MUI_FINISHPAGE_RUN "$INSTDIR\${PRODUCT_EXE}"
!define MUI_FINISHPAGE_RUN "$INSTDIR\KeeWeb.exe"
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_MUI
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_MUI
!define MULTIUSER_INSTALLMODE_COMMANDLINE
SetCompressor lzma SetCompressor lzma
Name "${PRODUCT_NAME}"
OutFile "${output}"
InstallDir "$PROGRAMFILES\${PRODUCT_NAME}"
ShowInstDetails show

14
package/nsis/includes.nsh Normal file → Executable file
View File

@ -1,10 +1,10 @@
!include MultiUser.nsh !include MultiUser.nsh
!include MUI2.nsh !include MUI2.nsh
!include Util.nsh !include Util.nsh
!include x64.nsh !include x64.nsh
!include nsDialogs.nsh !include nsDialogs.nsh
!include LogicLib.nsh !include LogicLib.nsh
!include StrFunc.nsh
!include WinVer.nsh !include WinVer.nsh
!include package\nsis\lib\FileAssoc.nsh !include package\nsis\lib\FileAssoc.nsh
!include package\nsis\lib\StrContains.nsh

141
package/nsis/install.nsh Normal file → Executable file
View File

@ -1,71 +1,82 @@
!insertmacro MUI_PAGE_WELCOME
#!insertmacro MULTIUSER_PAGE_INSTALLMODE
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE "English"
Function .onInit Function .onInit
${If} ${RunningX64} ${If} ${RunningX64}
${If} ${arch} == "x64" ${If} ${arch} == "x64"
SetRegView 64 SetRegView 64
StrCpy $InstDir "$PROGRAMFILES64\KeeWeb" StrCpy $InstDir "$PROGRAMFILES64\${PRODUCT_NAME}"
${Else} ${Else}
MessageBox MB_ICONSTOP|MB_OK "Please use 64-bit installer on 64-bit system" MessageBox MB_ICONSTOP|MB_OK "Please use 64-bit installer on 64-bit system"
Quit Quit
${EndIf} ${EndIf}
${Else} ${Else}
${If} ${arch} == "x64" ${If} ${arch} == "x64"
MessageBox MB_ICONSTOP|MB_OK "Please use 32-bit installer on 32-bit system" MessageBox MB_ICONSTOP|MB_OK "Please use 32-bit installer on 32-bit system"
Quit Quit
${EndIf} ${EndIf}
${EndIf} ${EndIf}
${IfNot} ${AtLeastWin7} ${IfNot} ${AtLeastWin7}
MessageBox MB_ICONSTOP|MB_OK "Windows 7 and above required" MessageBox MB_ICONSTOP|MB_OK "Windows 7 and above required"
Quit Quit
${EndIf} ${EndIf}
System::Call 'kernel32::CreateMutex(i 0, i 0, t "KeeWeb-Installer-Mutex-8843DCD0") ?e' System::Call 'kernel32::CreateMutex(i 0, i 0, t "KeeWeb-Installer-Mutex-8843DCD0") ?e'
Pop $R0 Pop $R0
${If} $R0 != 0 ${If} $R0 != 0
MessageBox MB_ICONSTOP|MB_OK "The installer is already running." MessageBox MB_ICONSTOP|MB_OK "The installer is already running."
Abort Abort
${EndIf} ${EndIf}
!insertmacro MULTIUSER_INIT !insertmacro MULTIUSER_INIT
FunctionEnd FunctionEnd
Section "MainSection" SEC01 Section "MainSection" SEC01
!insertmacro EnsureAppIsNotRunning !insertmacro EnsureAppIsNotRunning
ReadRegStr $R0 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" SetOverwrite on
ReadRegStr $R0 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString"
${If} $R0 != "" ${If} $R0 != ""
ExecWait '$R0 /S _?=$INSTDIR' CopyFiles "$R0" "$TEMP\${PRODUCT_UNINST_TEMP_EXE}"
${EndIf} ExecWait '"$TEMP\${PRODUCT_UNINST_TEMP_EXE}" /S'
${EndIf}
ReadRegStr $R0 "HKCU" "${PRODUCT_UNINST_KEY}" "QuietUninstallString"
${If} $R0 != "" ReadRegStr $R0 "HKCU" "${PRODUCT_UNINST_KEY}" "QuietUninstallString"
ExecWait '$R0' ${If} $R0 != ""
${EndIf} ExecWait '$R0'
${EndIf}
ReadRegStr $R0 "HKCU" "${PRODUCT_UNINST_KEY}" "UninstallString"
${If} $R0 != "" ReadRegStr $R0 "HKCU" "${PRODUCT_UNINST_KEY}" "UninstallString"
ExecWait '$R0' ${If} $R0 != ""
${EndIf} ExecWait '$R0'
${EndIf}
SetOutPath "$INSTDIR"
SetOverwrite ifnewer SetOutPath "$INSTDIR"
File /r "tmp\desktop\KeeWeb-win32-${arch}\*" SetOverwrite on
CreateDirectory "$SMPROGRAMS\KeeWeb" File /r "tmp\desktop\KeeWeb-win32-${arch}\*"
CreateShortCut "$SMPROGRAMS\KeeWeb\KeeWeb.lnk" "$INSTDIR\KeeWeb.exe" CreateDirectory "$SMPROGRAMS\KeeWeb"
CreateShortCut "$DESKTOP\KeeWeb.lnk" "$INSTDIR\KeeWeb.exe" CreateShortCut "$SMPROGRAMS\KeeWeb\KeeWeb.lnk" "$INSTDIR\${PRODUCT_EXE}"
CreateShortCut "$DESKTOP\KeeWeb.lnk" "$INSTDIR\${PRODUCT_EXE}"
!insertmacro APP_ASSOCIATE "kdbx" "kdbxfile" "KeePass Password Database" \
"$INSTDIR\KeeWeb.exe,0" "Open with KeeWeb" "$INSTDIR\KeeWeb.exe $\"%1$\"" !insertmacro APP_ASSOCIATE "kdbx" "kdbxfile" "KeePass Password Database" \
!insertmacro UPDATEFILEASSOC "$INSTDIR\${PRODUCT_EXE},0" "Open with KeeWeb" "$INSTDIR\${PRODUCT_EXE} $\"%1$\""
SectionEnd !insertmacro UPDATEFILEASSOC
SectionEnd
Section -Post Section -Post
WriteUninstaller "$INSTDIR\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" '"$INSTDIR\uninst.exe"'
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" '"$INSTDIR\uninst.exe"' WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "QuietUninstallString" '"$INSTDIR\uninst.exe" /S'
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "QuietUninstallString" '"$INSTDIR\uninst.exe" /S' WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXE}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\KeeWeb.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
SectionEnd WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "InstallDir" "$INSTDIR"
SectionEnd

242
package/nsis/lib/FileAssoc.nsh Normal file → Executable file
View File

@ -1,121 +1,121 @@
# http://nsis.sourceforge.net/FileAssoc # http://nsis.sourceforge.net/FileAssoc
; fileassoc.nsh ; fileassoc.nsh
; File association helper macros ; File association helper macros
; Written by Saivert ; Written by Saivert
; ;
; Features automatic backup system and UPDATEFILEASSOC macro for ; Features automatic backup system and UPDATEFILEASSOC macro for
; shell change notification. ; shell change notification.
; ;
; |> How to use <| ; |> How to use <|
; To associate a file with an application so you can double-click it in explorer, use ; To associate a file with an application so you can double-click it in explorer, use
; the APP_ASSOCIATE macro like this: ; the APP_ASSOCIATE macro like this:
; ;
; Example: ; Example:
; !insertmacro APP_ASSOCIATE "txt" "myapp.textfile" "Description of txt files" \ ; !insertmacro APP_ASSOCIATE "txt" "myapp.textfile" "Description of txt files" \
; "$INSTDIR\myapp.exe,0" "Open with myapp" "$INSTDIR\myapp.exe $\"%1$\"" ; "$INSTDIR\myapp.exe,0" "Open with myapp" "$INSTDIR\myapp.exe $\"%1$\""
; ;
; Never insert the APP_ASSOCIATE macro multiple times, it is only ment ; Never insert the APP_ASSOCIATE macro multiple times, it is only ment
; to associate an application with a single file and using the ; to associate an application with a single file and using the
; the "open" verb as default. To add more verbs (actions) to a file ; the "open" verb as default. To add more verbs (actions) to a file
; use the APP_ASSOCIATE_ADDVERB macro. ; use the APP_ASSOCIATE_ADDVERB macro.
; ;
; Example: ; Example:
; !insertmacro APP_ASSOCIATE_ADDVERB "myapp.textfile" "edit" "Edit with myapp" \ ; !insertmacro APP_ASSOCIATE_ADDVERB "myapp.textfile" "edit" "Edit with myapp" \
; "$INSTDIR\myapp.exe /edit $\"%1$\"" ; "$INSTDIR\myapp.exe /edit $\"%1$\""
; ;
; To have access to more options when registering the file association use the ; To have access to more options when registering the file association use the
; APP_ASSOCIATE_EX macro. Here you can specify the verb and what verb is to be the ; APP_ASSOCIATE_EX macro. Here you can specify the verb and what verb is to be the
; standard action (default verb). ; standard action (default verb).
; ;
; And finally: To remove the association from the registry use the APP_UNASSOCIATE ; And finally: To remove the association from the registry use the APP_UNASSOCIATE
; macro. Here is another example just to wrap it up: ; macro. Here is another example just to wrap it up:
; !insertmacro APP_UNASSOCIATE "txt" "myapp.textfile" ; !insertmacro APP_UNASSOCIATE "txt" "myapp.textfile"
; ;
; |> Note <| ; |> Note <|
; When defining your file class string always use the short form of your application title ; When defining your file class string always use the short form of your application title
; then a period (dot) and the type of file. This keeps the file class sort of unique. ; then a period (dot) and the type of file. This keeps the file class sort of unique.
; Examples: ; Examples:
; Winamp.Playlist ; Winamp.Playlist
; NSIS.Script ; NSIS.Script
; Photoshop.JPEGFile ; Photoshop.JPEGFile
; ;
; |> Tech info <| ; |> Tech info <|
; The registry key layout for a file association is: ; The registry key layout for a file association is:
; HKEY_CLASSES_ROOT ; HKEY_CLASSES_ROOT
; <applicationID> = <"description"> ; <applicationID> = <"description">
; shell ; shell
; <verb> = <"menu-item text"> ; <verb> = <"menu-item text">
; command = <"command string"> ; command = <"command string">
; ;
!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND !macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND
; Backup the previously associated file class ; Backup the previously associated file class
ReadRegStr $R0 HKCR ".${EXT}" "" ReadRegStr $R0 HKCR ".${EXT}" ""
WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0" WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0"
WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}" WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}"
WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}` WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}`
WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}` WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}`
WriteRegStr HKCR "${FILECLASS}\shell" "" "open" WriteRegStr HKCR "${FILECLASS}\shell" "" "open"
WriteRegStr HKCR "${FILECLASS}\shell\open" "" `${COMMANDTEXT}` WriteRegStr HKCR "${FILECLASS}\shell\open" "" `${COMMANDTEXT}`
WriteRegStr HKCR "${FILECLASS}\shell\open\command" "" `${COMMAND}` WriteRegStr HKCR "${FILECLASS}\shell\open\command" "" `${COMMAND}`
!macroend !macroend
!macro APP_ASSOCIATE_EX EXT FILECLASS DESCRIPTION ICON VERB DEFAULTVERB SHELLNEW COMMANDTEXT COMMAND !macro APP_ASSOCIATE_EX EXT FILECLASS DESCRIPTION ICON VERB DEFAULTVERB SHELLNEW COMMANDTEXT COMMAND
; Backup the previously associated file class ; Backup the previously associated file class
ReadRegStr $R0 HKCR ".${EXT}" "" ReadRegStr $R0 HKCR ".${EXT}" ""
WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0" WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0"
WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}" WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}"
StrCmp "${SHELLNEW}" "0" +2 StrCmp "${SHELLNEW}" "0" +2
WriteRegStr HKCR ".${EXT}\ShellNew" "NullFile" "" WriteRegStr HKCR ".${EXT}\ShellNew" "NullFile" ""
WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}` WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}`
WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}` WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}`
WriteRegStr HKCR "${FILECLASS}\shell" "" `${DEFAULTVERB}` WriteRegStr HKCR "${FILECLASS}\shell" "" `${DEFAULTVERB}`
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}` WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}` WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
!macroend !macroend
!macro APP_ASSOCIATE_ADDVERB FILECLASS VERB COMMANDTEXT COMMAND !macro APP_ASSOCIATE_ADDVERB FILECLASS VERB COMMANDTEXT COMMAND
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}` WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}` WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
!macroend !macroend
!macro APP_ASSOCIATE_REMOVEVERB FILECLASS VERB !macro APP_ASSOCIATE_REMOVEVERB FILECLASS VERB
DeleteRegKey HKCR `${FILECLASS}\shell\${VERB}` DeleteRegKey HKCR `${FILECLASS}\shell\${VERB}`
!macroend !macroend
!macro APP_UNASSOCIATE EXT FILECLASS !macro APP_UNASSOCIATE EXT FILECLASS
; Backup the previously associated file class ; Backup the previously associated file class
ReadRegStr $R0 HKCR ".${EXT}" `${FILECLASS}_backup` ReadRegStr $R0 HKCR ".${EXT}" `${FILECLASS}_backup`
WriteRegStr HKCR ".${EXT}" "" "$R0" WriteRegStr HKCR ".${EXT}" "" "$R0"
DeleteRegKey HKCR `${FILECLASS}` DeleteRegKey HKCR `${FILECLASS}`
!macroend !macroend
!macro APP_ASSOCIATE_GETFILECLASS OUTPUT EXT !macro APP_ASSOCIATE_GETFILECLASS OUTPUT EXT
ReadRegStr ${OUTPUT} HKCR ".${EXT}" "" ReadRegStr ${OUTPUT} HKCR ".${EXT}" ""
!macroend !macroend
; !defines for use with SHChangeNotify ; !defines for use with SHChangeNotify
!ifdef SHCNE_ASSOCCHANGED !ifdef SHCNE_ASSOCCHANGED
!undef SHCNE_ASSOCCHANGED !undef SHCNE_ASSOCCHANGED
!endif !endif
!define SHCNE_ASSOCCHANGED 0x08000000 !define SHCNE_ASSOCCHANGED 0x08000000
!ifdef SHCNF_FLUSH !ifdef SHCNF_FLUSH
!undef SHCNF_FLUSH !undef SHCNF_FLUSH
!endif !endif
!define SHCNF_FLUSH 0x1000 !define SHCNF_FLUSH 0x1000
!macro UPDATEFILEASSOC !macro UPDATEFILEASSOC
; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we ; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we
; can update the shell. ; can update the shell.
System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)" System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
!macroend !macroend
;EOF ;EOF

View File

@ -1,50 +0,0 @@
# http://nsis.sourceforge.net/StrContains
; StrContains
; This function does a case sensitive searches for an occurrence of a substring in a string.
; It returns the substring if it is found.
; Otherwise it returns null("").
; Written by kenglish_hi
; Adapted from StrReplace written by dandaman32
Var STR_HAYSTACK
Var STR_NEEDLE
Var STR_CONTAINS_VAR_1
Var STR_CONTAINS_VAR_2
Var STR_CONTAINS_VAR_3
Var STR_CONTAINS_VAR_4
Var STR_RETURN_VAR
Function StrContains
Exch $STR_NEEDLE
Exch 1
Exch $STR_HAYSTACK
; Uncomment to debug
;MessageBox MB_OK 'STR_NEEDLE = $STR_NEEDLE STR_HAYSTACK = $STR_HAYSTACK '
StrCpy $STR_RETURN_VAR ""
StrCpy $STR_CONTAINS_VAR_1 -1
StrLen $STR_CONTAINS_VAR_2 $STR_NEEDLE
StrLen $STR_CONTAINS_VAR_4 $STR_HAYSTACK
loop:
IntOp $STR_CONTAINS_VAR_1 $STR_CONTAINS_VAR_1 + 1
StrCpy $STR_CONTAINS_VAR_3 $STR_HAYSTACK $STR_CONTAINS_VAR_2 $STR_CONTAINS_VAR_1
StrCmp $STR_CONTAINS_VAR_3 $STR_NEEDLE found
StrCmp $STR_CONTAINS_VAR_1 $STR_CONTAINS_VAR_4 done
Goto loop
found:
StrCpy $STR_RETURN_VAR $STR_NEEDLE
Goto done
done:
Pop $STR_NEEDLE ;Prevent "invalid opcode" errors and keep the
Exch $STR_RETURN_VAR
FunctionEnd
!macro _StrContainsConstructor OUT NEEDLE HAYSTACK
Push `${HAYSTACK}`
Push `${NEEDLE}`
Call StrContains
Pop `${OUT}`
!macroend
!define StrContains '!insertmacro "_StrContainsConstructor"'

4
package/nsis/main-un.nsi Executable file
View File

@ -0,0 +1,4 @@
!include package\nsis\defines.nsh
!include package\nsis\includes.nsh
!include package\nsis\check-running.nsh
!include package\nsis\uninstall.nsh

7
package/nsis/main.nsi Normal file → Executable file
View File

@ -1,7 +1,4 @@
!include package\nsis\defines.nsh !include package\nsis\defines.nsh
!include package\nsis\includes.nsh !include package\nsis\includes.nsh
!include package\nsis\mui.nsh
!include package\nsis\config.nsh
!include package\nsis\check-running.nsh !include package\nsis\check-running.nsh
!include package\nsis\install.nsh !include package\nsis\install.nsh
!include package\nsis\uninstall.nsh

View File

@ -1,9 +0,0 @@
!insertmacro MUI_PAGE_WELCOME
#!insertmacro MULTIUSER_PAGE_INSTALLMODE
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"

81
package/nsis/uninstall.nsh Normal file → Executable file
View File

@ -1,29 +1,78 @@
Function un.onInit !insertmacro MUI_PAGE_INSTFILES
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Remove $(^Name) from your computer?" /SD IDYES IDYES yes
Abort !insertmacro MUI_LANGUAGE "English"
yes:
Function .onInit
${If} ${RunningX64} ${If} ${RunningX64}
SetRegView 64 SetRegView 64
StrCpy $InstDir "$PROGRAMFILES64\${PRODUCT_NAME}"
${EndIf} ${EndIf}
!insertmacro MULTIUSER_UNINIT
FunctionEnd
Function un.onUninstSuccess !insertmacro MULTIUSER_INIT
HideWindow
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." /SD IDOK
FunctionEnd
Section Uninstall ${StrStr} $0 "$EXEPATH" "${PRODUCT_UNINST_TEMP_EXE}"
${If} $0 == ""
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Remove $(^Name) from your computer?" /SD IDYES IDYES yes
Abort
yes:
!insertmacro EnsureAppIsNotRunning
SetOverwrite on
CopyFiles "$EXEPATH" "$TEMP\${PRODUCT_UNINST_TEMP_EXE}"
${If} ${Silent}
Exec '"$TEMP\${PRODUCT_UNINST_TEMP_EXE}" /S'
${Else}
Exec '"$TEMP\${PRODUCT_UNINST_TEMP_EXE}"'
${EndIf}
Quit
${EndIf}
FunctionEnd
Function .onInstSuccess
HideWindow
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." /SD IDOK
FunctionEnd
Section "MainSection" SEC01
!insertmacro EnsureAppIsNotRunning
DetailPrint "Removing desktop shortcut"
Delete "$DESKTOP\KeeWeb.lnk" Delete "$DESKTOP\KeeWeb.lnk"
Delete "$SMPROGRAMS\KeeWeb\KeeWeb.lnk" DetailPrint "Removing menu shortcut"
Delete "$SMPROGRAMS\KeeWeb\KeeWeb.lnk"
DetailPrint "Removing menu items"
RMDir "$SMPROGRAMS\KeeWeb" RMDir "$SMPROGRAMS\KeeWeb"
RMDir /r "$INSTDIR"
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" ReadRegStr $R0 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "InstallDir"
${If} $R0 == ""
DetailPrint "InstallDir key is absent"
Abort
${EndIf}
StrCpy $InstDir "$R0"
ClearErrors
DetailPrint "Removing app files from $InstDir"
Var /GLOBAL deleteRetry
${ForEach} $deleteRetry 1 3 + 1
RMDir /r "$InstDir"
${If} ${Errors}
ClearErrors
DetailPrint "Error removing files, retrying in a second"
Sleep 1000
${Else}
${ExitFor}
${EndIf}
${Next}
DetailPrint "Deleting registry keys"
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
DetailPrint "Unregistering file associations"
!insertmacro APP_UNASSOCIATE "kdbx" "kdbxfile" !insertmacro APP_UNASSOCIATE "kdbx" "kdbxfile"
!insertmacro UPDATEFILEASSOC DetailPrint "Updating file associations"
!insertmacro UPDATEFILEASSOC
DetailPrint "Done"
SetAutoClose true SetAutoClose true
SectionEnd SectionEnd