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/',
nonull: true
},
'desktop-win32-dist': {
cwd: 'tmp/desktop',
src: ['KeeWeb.win.x64.exe', 'KeeWeb.win.ia32.exe'],
dest: 'dist/desktop/',
expand: true,
'desktop-win32-dist-x64': {
src: 'tmp/desktop/KeeWeb.win.x64.exe',
dest: `dist/desktop/KeeWeb-${pkg.version}.win.x64.exe`,
nonull: true
},
'desktop-win32-dist-ia32': {
src: 'tmp/desktop/KeeWeb.win.ia32.exe',
dest: `dist/desktop/KeeWeb-${pkg.version}.win.ia32.exe`,
nonull: true
}
},
@ -353,19 +356,19 @@ module.exports = function(grunt) {
files: [{ cwd: 'tmp/desktop/app', src: '**', expand: true }]
},
'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 }]
},
'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 }]
},
'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 }]
},
'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 }]
}
},
@ -383,12 +386,11 @@ module.exports = function(grunt) {
]
},
app: {
dest: 'dist/desktop/KeeWeb.mac.dmg'
dest: `dist/desktop/KeeWeb-${pkg.version}.mac.dmg`
}
},
nsis: {
options: {
installScript: 'package/nsis/main.nsi',
vars: {
version: pkg.version,
rev: function() { return grunt.config.get('gitinfo.local.branch.current.shortSHA'); },
@ -397,15 +399,31 @@ module.exports = function(grunt) {
},
'win32-x64': {
options: {
installScript: 'package/nsis/main.nsi',
arch: 'x64',
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': {
options: {
installScript: 'package/nsis/main.nsi',
arch: 'ia32',
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: {
@ -423,7 +441,7 @@ module.exports = function(grunt) {
info: {
arch: 'amd64',
targetDir: 'dist/desktop',
pkgName: 'KeeWeb.linux.x64.deb',
pkgName: `KeeWeb-${pkg.version}.linux.x64.deb`,
appName: 'KeeWeb',
depends: 'libappindicator1',
scripts: {
@ -488,16 +506,54 @@ module.exports = function(grunt) {
keytarPasswordService: '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': {
options: {
file: 'tmp/desktop/KeeWeb.win.x64.exe',
name: 'KeeWeb Setup'
files: {
'tmp/desktop/KeeWeb.win.x64.exe': 'KeeWeb Setup'
}
}
},
'win32-installer-ia32': {
options: {
file: 'tmp/desktop/KeeWeb.win.ia32.exe',
name: 'KeeWeb Setup'
files: {
'tmp/desktop/KeeWeb.win.ia32.exe': 'KeeWeb Setup'
}
}
}
},
@ -547,6 +603,8 @@ module.exports = function(grunt) {
grunt.registerTask('build-desktop-executables', [
'electron',
'sign-exe:win32-build-x64',
'sign-exe:win32-build-ia32',
'copy:desktop-windows-helper-ia32',
'copy:desktop-windows-helper-x64'
]);
@ -563,11 +621,16 @@ module.exports = function(grunt) {
]);
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-ia32',
'sign-exe:win32-installer-x64',
'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', [

View File

@ -12,11 +12,14 @@ module.exports = function (grunt) {
if (typeof value === 'function') {
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}Doutput=${opt.output}`);
args.push(`${prefix}NOCD`);
args.push(`${prefix}V2`);
args.push(opt.installScript);
let executable = win ? 'C:\\Program Files (x86)\\NSIS\\makensis.exe' : 'makensis';
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
const fs = require('fs');
module.exports = function (grunt) {
grunt.registerMultiTask('sign-exe', 'Signs exe file with authenticode certificate', function () {
const keytar = require('keytar');
@ -11,30 +13,44 @@ module.exports = function (grunt) {
if (!password) {
return grunt.warn('Code sign password not found');
}
let spawned = grunt.util.spawn({
cmd: 'signcode',
args: [
let promises = Object.keys(opt.files).map(file => signFile(file, opt.files[file], opt, password));
Promise.all(promises).then(done);
});
function signFile(file, name, opt, password) {
let signedFile = file + '.sign';
return new Promise((resolve, reject) => {
let args = [
'-spc', opt.spc,
'-v', opt.pvk,
'-a', opt.algo,
'-$', 'commercial',
'-n', opt.name,
'-key', require('path').resolve(opt.pvk),
'-h', opt.algo,
'-n', name,
'-i', opt.url,
'-t', 'http://timestamp.verisign.com/scripts/timstamp.dll',
'-tr', 10,
opt.file
]
}, (error, result, code) => {
if (error || code) {
spawned.kill();
return grunt.warn(`signtool error ${code}: ${error}`);
}
done();
'-pass', password,
'-in', file,
'-out', signedFile
];
let spawned = grunt.util.spawn({
cmd: 'osslsigncode',
args: args
}, (error, result, code) => {
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
${Do}
nsExec::ExecToStack /OEM 'tasklist /NH /FI "IMAGENAME eq ${PRODUCT_EXE}"'
Pop $0
${If} $0 != 0
DetailPrint "Error checking ${PRODUCT_EXE}: $0"
MessageBox MB_ICONSTOP|MB_OK "Failed to check whether process is running"
Quit
${EndIf}
Pop $1
${StrContains} $0 "${PRODUCT_EXE}" $1
${If} $0 == ""
DetailPrint "${PRODUCT_EXE} is not running"
${ExitDo}
${Else}
MessageBox MB_ICONQUESTION|MB_OKCANCEL|MB_DEFBUTTON1 "To proceed, please close ${PRODUCT_NAME} and click OK" /SD IDCANCEL IDOK ok
Quit
ok:
${EndIf}
${Loop}
!macroend
!macro EnsureAppIsNotRunning
${Do}
nsExec::ExecToStack /OEM 'tasklist /NH /FI "IMAGENAME eq ${PRODUCT_EXE}"'
Pop $0
${If} $0 != 0
DetailPrint "Error checking ${PRODUCT_EXE}: $0"
MessageBox MB_ICONSTOP|MB_OK "Failed to check whether process is running" /SD IDOK
Quit
${EndIf}
Pop $1
${StrStr} $0 $1 "${PRODUCT_EXE}"
${If} $0 == ""
DetailPrint "${PRODUCT_EXE} is not running"
${ExitDo}
${Else}
MessageBox MB_ICONQUESTION|MB_OKCANCEL|MB_DEFBUTTON1 "To proceed, please close ${PRODUCT_NAME} and click OK" /SD IDCANCEL IDOK ok
Quit
ok:
${EndIf}
${Loop}
!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_VERSION "${version}"
!define PRODUCT_PUBLISHER "KeeWeb"
!define PRODUCT_WEB_SITE "${homepage}"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
!define PRODUCT_NAME "KeeWeb"
!define PRODUCT_VERSION "${version}"
!define PRODUCT_PUBLISHER "KeeWeb"
!define PRODUCT_WEB_SITE "${homepage}"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
!define PRODUCT_EXE "KeeWeb.exe"
!define MUI_ABORTWARNING
!define PRODUCT_UNINST_TEMP_EXE "KeeWebUninst.exe"
!define MUI_ABORTWARNING
!define MUI_ICON "graphics\icon.ico"
!define MUI_UNICON "graphics\icon.ico"
!define MUI_FINISHPAGE_RUN "$INSTDIR\KeeWeb.exe"
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_MUI
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MUI_FINISHPAGE_RUN "$INSTDIR\${PRODUCT_EXE}"
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_MUI
!define MULTIUSER_INSTALLMODE_COMMANDLINE
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 MUI2.nsh
!include Util.nsh
!include x64.nsh
!include nsDialogs.nsh
!include MultiUser.nsh
!include MUI2.nsh
!include Util.nsh
!include x64.nsh
!include nsDialogs.nsh
!include LogicLib.nsh
!include StrFunc.nsh
!include WinVer.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
${If} ${RunningX64}
${If} ${arch} == "x64"
SetRegView 64
StrCpy $InstDir "$PROGRAMFILES64\KeeWeb"
${Else}
MessageBox MB_ICONSTOP|MB_OK "Please use 64-bit installer on 64-bit system"
Quit
${EndIf}
${Else}
${If} ${arch} == "x64"
MessageBox MB_ICONSTOP|MB_OK "Please use 32-bit installer on 32-bit system"
Quit
${EndIf}
${EndIf}
${IfNot} ${AtLeastWin7}
MessageBox MB_ICONSTOP|MB_OK "Windows 7 and above required"
Quit
${EndIf}
System::Call 'kernel32::CreateMutex(i 0, i 0, t "KeeWeb-Installer-Mutex-8843DCD0") ?e'
Pop $R0
${If} $R0 != 0
MessageBox MB_ICONSTOP|MB_OK "The installer is already running."
Abort
${EndIf}
!insertmacro MULTIUSER_INIT
FunctionEnd
Section "MainSection" SEC01
${If} ${RunningX64}
${If} ${arch} == "x64"
SetRegView 64
StrCpy $InstDir "$PROGRAMFILES64\${PRODUCT_NAME}"
${Else}
MessageBox MB_ICONSTOP|MB_OK "Please use 64-bit installer on 64-bit system"
Quit
${EndIf}
${Else}
${If} ${arch} == "x64"
MessageBox MB_ICONSTOP|MB_OK "Please use 32-bit installer on 32-bit system"
Quit
${EndIf}
${EndIf}
${IfNot} ${AtLeastWin7}
MessageBox MB_ICONSTOP|MB_OK "Windows 7 and above required"
Quit
${EndIf}
System::Call 'kernel32::CreateMutex(i 0, i 0, t "KeeWeb-Installer-Mutex-8843DCD0") ?e'
Pop $R0
${If} $R0 != 0
MessageBox MB_ICONSTOP|MB_OK "The installer is already running."
Abort
${EndIf}
!insertmacro MULTIUSER_INIT
FunctionEnd
Section "MainSection" SEC01
!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 != ""
ExecWait '$R0 /S _?=$INSTDIR'
${EndIf}
ReadRegStr $R0 "HKCU" "${PRODUCT_UNINST_KEY}" "QuietUninstallString"
${If} $R0 != ""
ExecWait '$R0'
${EndIf}
ReadRegStr $R0 "HKCU" "${PRODUCT_UNINST_KEY}" "UninstallString"
${If} $R0 != ""
ExecWait '$R0'
${EndIf}
SetOutPath "$INSTDIR"
SetOverwrite ifnewer
File /r "tmp\desktop\KeeWeb-win32-${arch}\*"
CreateDirectory "$SMPROGRAMS\KeeWeb"
CreateShortCut "$SMPROGRAMS\KeeWeb\KeeWeb.lnk" "$INSTDIR\KeeWeb.exe"
CreateShortCut "$DESKTOP\KeeWeb.lnk" "$INSTDIR\KeeWeb.exe"
!insertmacro APP_ASSOCIATE "kdbx" "kdbxfile" "KeePass Password Database" \
"$INSTDIR\KeeWeb.exe,0" "Open with KeeWeb" "$INSTDIR\KeeWeb.exe $\"%1$\""
!insertmacro UPDATEFILEASSOC
SectionEnd
CopyFiles "$R0" "$TEMP\${PRODUCT_UNINST_TEMP_EXE}"
ExecWait '"$TEMP\${PRODUCT_UNINST_TEMP_EXE}" /S'
${EndIf}
ReadRegStr $R0 "HKCU" "${PRODUCT_UNINST_KEY}" "QuietUninstallString"
${If} $R0 != ""
ExecWait '$R0'
${EndIf}
ReadRegStr $R0 "HKCU" "${PRODUCT_UNINST_KEY}" "UninstallString"
${If} $R0 != ""
ExecWait '$R0'
${EndIf}
SetOutPath "$INSTDIR"
SetOverwrite on
File /r "tmp\desktop\KeeWeb-win32-${arch}\*"
CreateDirectory "$SMPROGRAMS\KeeWeb"
CreateShortCut "$SMPROGRAMS\KeeWeb\KeeWeb.lnk" "$INSTDIR\${PRODUCT_EXE}"
CreateShortCut "$DESKTOP\KeeWeb.lnk" "$INSTDIR\${PRODUCT_EXE}"
!insertmacro APP_ASSOCIATE "kdbx" "kdbxfile" "KeePass Password Database" \
"$INSTDIR\${PRODUCT_EXE},0" "Open with KeeWeb" "$INSTDIR\${PRODUCT_EXE} $\"%1$\""
!insertmacro UPDATEFILEASSOC
SectionEnd
Section -Post
WriteUninstaller "$INSTDIR\uninst.exe"
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}" "QuietUninstallString" '"$INSTDIR\uninst.exe" /S'
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}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
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}" "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}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
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
; fileassoc.nsh
; File association helper macros
; Written by Saivert
;
; Features automatic backup system and UPDATEFILEASSOC macro for
; shell change notification.
;
; |> How to use <|
; To associate a file with an application so you can double-click it in explorer, use
; the APP_ASSOCIATE macro like this:
;
; Example:
; !insertmacro APP_ASSOCIATE "txt" "myapp.textfile" "Description of txt files" \
; "$INSTDIR\myapp.exe,0" "Open with myapp" "$INSTDIR\myapp.exe $\"%1$\""
;
; Never insert the APP_ASSOCIATE macro multiple times, it is only ment
; to associate an application with a single file and using the
; the "open" verb as default. To add more verbs (actions) to a file
; use the APP_ASSOCIATE_ADDVERB macro.
;
; Example:
; !insertmacro APP_ASSOCIATE_ADDVERB "myapp.textfile" "edit" "Edit with myapp" \
; "$INSTDIR\myapp.exe /edit $\"%1$\""
;
; 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
; standard action (default verb).
;
; And finally: To remove the association from the registry use the APP_UNASSOCIATE
; macro. Here is another example just to wrap it up:
; !insertmacro APP_UNASSOCIATE "txt" "myapp.textfile"
;
; |> Note <|
; 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.
; Examples:
; Winamp.Playlist
; NSIS.Script
; Photoshop.JPEGFile
;
; |> Tech info <|
; The registry key layout for a file association is:
; HKEY_CLASSES_ROOT
; <applicationID> = <"description">
; shell
; <verb> = <"menu-item text">
; command = <"command string">
;
!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND
; Backup the previously associated file class
ReadRegStr $R0 HKCR ".${EXT}" ""
WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0"
WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}"
WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}`
WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}`
WriteRegStr HKCR "${FILECLASS}\shell" "" "open"
WriteRegStr HKCR "${FILECLASS}\shell\open" "" `${COMMANDTEXT}`
WriteRegStr HKCR "${FILECLASS}\shell\open\command" "" `${COMMAND}`
!macroend
!macro APP_ASSOCIATE_EX EXT FILECLASS DESCRIPTION ICON VERB DEFAULTVERB SHELLNEW COMMANDTEXT COMMAND
; Backup the previously associated file class
ReadRegStr $R0 HKCR ".${EXT}" ""
WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0"
WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}"
StrCmp "${SHELLNEW}" "0" +2
WriteRegStr HKCR ".${EXT}\ShellNew" "NullFile" ""
WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}`
WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}`
WriteRegStr HKCR "${FILECLASS}\shell" "" `${DEFAULTVERB}`
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
!macroend
!macro APP_ASSOCIATE_ADDVERB FILECLASS VERB COMMANDTEXT COMMAND
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
!macroend
!macro APP_ASSOCIATE_REMOVEVERB FILECLASS VERB
DeleteRegKey HKCR `${FILECLASS}\shell\${VERB}`
!macroend
!macro APP_UNASSOCIATE EXT FILECLASS
; Backup the previously associated file class
ReadRegStr $R0 HKCR ".${EXT}" `${FILECLASS}_backup`
WriteRegStr HKCR ".${EXT}" "" "$R0"
DeleteRegKey HKCR `${FILECLASS}`
!macroend
!macro APP_ASSOCIATE_GETFILECLASS OUTPUT EXT
ReadRegStr ${OUTPUT} HKCR ".${EXT}" ""
!macroend
; !defines for use with SHChangeNotify
!ifdef SHCNE_ASSOCCHANGED
!undef SHCNE_ASSOCCHANGED
!endif
!define SHCNE_ASSOCCHANGED 0x08000000
!ifdef SHCNF_FLUSH
!undef SHCNF_FLUSH
!endif
!define SHCNF_FLUSH 0x1000
!macro UPDATEFILEASSOC
; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we
; can update the shell.
System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
!macroend
;EOF
# http://nsis.sourceforge.net/FileAssoc
; fileassoc.nsh
; File association helper macros
; Written by Saivert
;
; Features automatic backup system and UPDATEFILEASSOC macro for
; shell change notification.
;
; |> How to use <|
; To associate a file with an application so you can double-click it in explorer, use
; the APP_ASSOCIATE macro like this:
;
; Example:
; !insertmacro APP_ASSOCIATE "txt" "myapp.textfile" "Description of txt files" \
; "$INSTDIR\myapp.exe,0" "Open with myapp" "$INSTDIR\myapp.exe $\"%1$\""
;
; Never insert the APP_ASSOCIATE macro multiple times, it is only ment
; to associate an application with a single file and using the
; the "open" verb as default. To add more verbs (actions) to a file
; use the APP_ASSOCIATE_ADDVERB macro.
;
; Example:
; !insertmacro APP_ASSOCIATE_ADDVERB "myapp.textfile" "edit" "Edit with myapp" \
; "$INSTDIR\myapp.exe /edit $\"%1$\""
;
; 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
; standard action (default verb).
;
; And finally: To remove the association from the registry use the APP_UNASSOCIATE
; macro. Here is another example just to wrap it up:
; !insertmacro APP_UNASSOCIATE "txt" "myapp.textfile"
;
; |> Note <|
; 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.
; Examples:
; Winamp.Playlist
; NSIS.Script
; Photoshop.JPEGFile
;
; |> Tech info <|
; The registry key layout for a file association is:
; HKEY_CLASSES_ROOT
; <applicationID> = <"description">
; shell
; <verb> = <"menu-item text">
; command = <"command string">
;
!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND
; Backup the previously associated file class
ReadRegStr $R0 HKCR ".${EXT}" ""
WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0"
WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}"
WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}`
WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}`
WriteRegStr HKCR "${FILECLASS}\shell" "" "open"
WriteRegStr HKCR "${FILECLASS}\shell\open" "" `${COMMANDTEXT}`
WriteRegStr HKCR "${FILECLASS}\shell\open\command" "" `${COMMAND}`
!macroend
!macro APP_ASSOCIATE_EX EXT FILECLASS DESCRIPTION ICON VERB DEFAULTVERB SHELLNEW COMMANDTEXT COMMAND
; Backup the previously associated file class
ReadRegStr $R0 HKCR ".${EXT}" ""
WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0"
WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}"
StrCmp "${SHELLNEW}" "0" +2
WriteRegStr HKCR ".${EXT}\ShellNew" "NullFile" ""
WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}`
WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}`
WriteRegStr HKCR "${FILECLASS}\shell" "" `${DEFAULTVERB}`
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
!macroend
!macro APP_ASSOCIATE_ADDVERB FILECLASS VERB COMMANDTEXT COMMAND
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
!macroend
!macro APP_ASSOCIATE_REMOVEVERB FILECLASS VERB
DeleteRegKey HKCR `${FILECLASS}\shell\${VERB}`
!macroend
!macro APP_UNASSOCIATE EXT FILECLASS
; Backup the previously associated file class
ReadRegStr $R0 HKCR ".${EXT}" `${FILECLASS}_backup`
WriteRegStr HKCR ".${EXT}" "" "$R0"
DeleteRegKey HKCR `${FILECLASS}`
!macroend
!macro APP_ASSOCIATE_GETFILECLASS OUTPUT EXT
ReadRegStr ${OUTPUT} HKCR ".${EXT}" ""
!macroend
; !defines for use with SHChangeNotify
!ifdef SHCNE_ASSOCCHANGED
!undef SHCNE_ASSOCCHANGED
!endif
!define SHCNE_ASSOCCHANGED 0x08000000
!ifdef SHCNF_FLUSH
!undef SHCNF_FLUSH
!endif
!define SHCNF_FLUSH 0x1000
!macro UPDATEFILEASSOC
; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we
; can update the shell.
System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
!macroend
;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\includes.nsh
!include package\nsis\mui.nsh
!include package\nsis\config.nsh
!include package\nsis\defines.nsh
!include package\nsis\includes.nsh
!include package\nsis\check-running.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
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Remove $(^Name) from your computer?" /SD IDYES IDYES yes
Abort
yes:
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Function .onInit
${If} ${RunningX64}
SetRegView 64
StrCpy $InstDir "$PROGRAMFILES64\${PRODUCT_NAME}"
${EndIf}
!insertmacro MULTIUSER_UNINIT
FunctionEnd
Function un.onUninstSuccess
HideWindow
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." /SD IDOK
FunctionEnd
!insertmacro MULTIUSER_INIT
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 "$SMPROGRAMS\KeeWeb\KeeWeb.lnk"
DetailPrint "Removing menu shortcut"
Delete "$SMPROGRAMS\KeeWeb\KeeWeb.lnk"
DetailPrint "Removing menu items"
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 UPDATEFILEASSOC
DetailPrint "Updating file associations"
!insertmacro UPDATEFILEASSOC
DetailPrint "Done"
SetAutoClose true
SectionEnd
SectionEnd