file association on windows installer

This commit is contained in:
alemuntoni 2020-04-10 17:51:15 +02:00
parent c2516bc5c0
commit 77cc5a52a8
4 changed files with 252 additions and 11 deletions

View File

@ -5,9 +5,9 @@
- [ ] Every platform
#### What type of issue is?
- [ ] bug or unexpected behavior;
- [ ] crash;
- [ ] feature request;
- [ ] bug or unexpected behavior
- [ ] crash
- [ ] feature request
- [ ] other (specify...)
#### Describe your issue
@ -16,11 +16,8 @@
####Guidelines for a good issue
Please before submitting an issue, check if your issue has been already reported by someone else. In this case, do not open another issue: just add your experience in the existing issue.
#####Subject
If the issue is specific of a platform, please specify it on the subject in square brackets (example: `[MacOS] crash when opening obj`).
Please specify also if the issue concerns a bug, crash, or it is a feature request.
#####Description
Please be as detailed as possible. If the issue is related to a specific mesh or file, please attach it. Delete these guidelines before submitting :)
Before submitting an issue:
- check if your issue has been already reported by someone else. In this case, do not open another issue: just add your experience in the existing issue;
- If the issue is specific of a platform, please specify it on the subject in square brackets (example: `[MacOS] crash when opening obj`);
- be as detailed as possible. If the issue is related to a specific mesh or file, please attach it. Make sure that the problem is reproducible;
- delete these guidelines before submitting :)

View File

@ -0,0 +1,54 @@
!ifndef ExecWaitJob_INCLUDED
!define ExecWaitJob_INCLUDED
; this macro executes a process and waits until has finished
; example call:
; StrCpy $8 '"uninstall.exe"'
; !insertmacro ExecWaitJob r8
;
!macro ExecWaitJob _exec
/*
0=ErrChk+JOBOBJECTASSOCIATE*+PROCESS_INFO
1=hPort
2=hJob
3=ErrChk+hProcess+ioX
4=STARTINFO+hThread+ioOLAP
9="Stage"
*/
StrCpy $9 0
System::Call 'kernel32::CreateIoCompletionPort(i -1,i0,i0,i0)i.r1'
${IfThen} $1 != 0 ${|} IntOp $9 $9 + 1 ${|}
System::Call 'kernel32::CreateJobObject(i0,i0)i.r2'
${IfThen} $2 != 0 ${|} IntOp $9 $9 + 1 ${|}
System::Call '*(i 0,i $1)i.r0'
System::Call 'kernel32::SetInformationJobObject(i $2,i 7,i $0,i 8)i.r3'
${IfThen} $3 != 0 ${|} IntOp $9 $9 + 1 ${|}
System::Free $0
System::Call '*(i,i,i,i)i.r0'
System::Alloc 72
pop $4
System::Call "*$4(i 72)"
System::Call 'kernel32::CreateProcess(i0,t ${_exec},i0,i0,i0,i 0x01000004,i0,i0,i $4,i $0)i.r3'
${IfThen} $3 != 0 ${|} IntOp $9 $9 + 1 ${|}
System::Free $4
System::Call "*$0(i.r3,i.r4,i,i)"
System::Free $0
System::Call 'kernel32::AssignProcessToJobObject(i $2,i $3)i.r0'
${IfThen} $0 != 0 ${|} IntOp $9 $9 + 1 ${|}
System::Call 'kernel32::ResumeThread(i $4)i.r0'
${IfThen} $0 != -1 ${|} IntOp $9 $9 + 1 ${|}
System::Call 'kernel32::CloseHandle(i $3)'
System::Call 'kernel32::CloseHandle(i $4)'
!define __ExecWaitJob__ ExecWaitJob${__LINE__}
${__ExecWaitJob__}ioportwait:
System::Call 'kernel32::GetQueuedCompletionStatus(i $1,*i.r3,*i,*i.r4,i -1)i.r0'
${IfThen} $0 = 0 ${|} StrCpy $9 0 ${|}
${IfThen} $3 != 4 ${|} goto ${__ExecWaitJob__}ioportwait ${|}
System::Call 'kernel32::CloseHandle(i $2)'
System::Call 'kernel32::CloseHandle(i $1)'
!undef __ExecWaitJob__
${IfThen} $9 < 6 ${|} MessageBox mb_iconstop `ExecWaitJob "${_exec}" failed!` ${|}
!macroend
!endif # !ExecWaitJob_INCLUDED

View File

@ -0,0 +1,190 @@
/*
_____________________________________________________________________________
File Association
_____________________________________________________________________________
Based on code taken from http://nsis.sourceforge.net/File_Association
Usage in script:
1. !include "FileAssociation.nsh"
2. [Section|Function]
${FileAssociationFunction} "Param1" "Param2" "..." $var
[SectionEnd|FunctionEnd]
FileAssociationFunction=[RegisterExtension|UnRegisterExtension]
_____________________________________________________________________________
${RegisterExtension} "[executable]" "[extension]" "[description]"
"[executable]" ; executable which opens the file format
;
"[extension]" ; extension, which represents the file format to open
;
"[description]" ; description for the extension. This will be display in Windows Explorer.
;
${UnRegisterExtension} "[extension]" "[description]"
"[extension]" ; extension, which represents the file format to open
;
"[description]" ; description for the extension. This will be display in Windows Explorer.
;
_____________________________________________________________________________
Macros
_____________________________________________________________________________
Change log window verbosity (default: 3=no script)
Example:
!include "FileAssociation.nsh"
!insertmacro RegisterExtension
${FileAssociation_VERBOSE} 4 # all verbosity
!insertmacro UnRegisterExtension
${FileAssociation_VERBOSE} 3 # no script
*/
!ifndef FileAssociation_INCLUDED
!define FileAssociation_INCLUDED
!include Util.nsh
!verbose push
!verbose 3
!ifndef _FileAssociation_VERBOSE
!define _FileAssociation_VERBOSE 3
!endif
!verbose ${_FileAssociation_VERBOSE}
!define FileAssociation_VERBOSE `!insertmacro FileAssociation_VERBOSE`
!verbose pop
!macro FileAssociation_VERBOSE _VERBOSE
!verbose push
!verbose 3
!undef _FileAssociation_VERBOSE
!define _FileAssociation_VERBOSE ${_VERBOSE}
!verbose pop
!macroend
!macro RegisterExtensionCall _EXECUTABLE _EXTENSION _DESCRIPTION
!verbose push
!verbose ${_FileAssociation_VERBOSE}
Push `${_DESCRIPTION}`
Push `${_EXTENSION}`
Push `${_EXECUTABLE}`
${CallArtificialFunction} RegisterExtension_
!verbose pop
!macroend
!macro UnRegisterExtensionCall _EXTENSION _DESCRIPTION
!verbose push
!verbose ${_FileAssociation_VERBOSE}
Push `${_EXTENSION}`
Push `${_DESCRIPTION}`
${CallArtificialFunction} UnRegisterExtension_
!verbose pop
!macroend
!define RegisterExtension `!insertmacro RegisterExtensionCall`
!define un.RegisterExtension `!insertmacro RegisterExtensionCall`
!macro RegisterExtension
!macroend
!macro un.RegisterExtension
!macroend
!macro RegisterExtension_
!verbose push
!verbose ${_FileAssociation_VERBOSE}
Exch $R2 ;exe
Exch
Exch $R1 ;ext
Exch
Exch 2
Exch $R0 ;desc
Exch 2
Push $0
Push $1
ReadRegStr $1 HKCR $R1 "" ; read current file association
StrCmp "$1" "" NoBackup ; is it empty
StrCmp "$1" "$R0" NoBackup ; is it our own
WriteRegStr HKCR $R1 "backup_val" "$1" ; backup current value
NoBackup:
WriteRegStr HKCR $R1 "" "$R0" ; set our file association
ReadRegStr $0 HKCR $R0 ""
StrCmp $0 "" 0 Skip
WriteRegStr HKCR "$R0" "" "$R0"
WriteRegStr HKCR "$R0\shell" "" "open"
WriteRegStr HKCR "$R0\DefaultIcon" "" "$R2,0"
Skip:
WriteRegStr HKCR "$R0\shell\open\command" "" '"$R2" "%1"'
WriteRegStr HKCR "$R0\shell\edit" "" "Edit $R0"
WriteRegStr HKCR "$R0\shell\edit\command" "" '"$R2" "%1"'
Pop $1
Pop $0
Pop $R2
Pop $R1
Pop $R0
!verbose pop
!macroend
!define UnRegisterExtension `!insertmacro UnRegisterExtensionCall`
!define un.UnRegisterExtension `!insertmacro UnRegisterExtensionCall`
!macro UnRegisterExtension
!macroend
!macro un.UnRegisterExtension
!macroend
!macro UnRegisterExtension_
!verbose push
!verbose ${_FileAssociation_VERBOSE}
Exch $R1 ;desc
Exch
Exch $R0 ;ext
Exch
Push $0
Push $1
ReadRegStr $1 HKCR $R0 ""
StrCmp $1 $R1 0 NoOwn ; only do this if we own it
ReadRegStr $1 HKCR $R0 "backup_val"
StrCmp $1 "" 0 Restore ; if backup="" then delete the whole key
DeleteRegKey HKCR $R0
Goto NoOwn
Restore:
WriteRegStr HKCR $R0 "" $1
DeleteRegValue HKCR $R0 "backup_val"
DeleteRegKey HKCR $R1 ;Delete key with association name settings
NoOwn:
Pop $1
Pop $0
Pop $R1
Pop $R0
!verbose pop
!macroend
!endif # !FileAssociation_INCLUDED