So basically, I have an app that modifies the registry at run time which breaks portability unless I rewrite it after the fact. I've hacked together two approaches - one using a bat script to launch the app, sleep, and then rewrite the registry, and one using OverrideExecute. It's just a slightly modified version of execute block from the launcher source. The bat file is basically the same thing.
${SegmentFile}
Var URLCommand
${OverrideExecute}
${!getdebug}
!ifdef DEBUG
${If} $WaitForProgram != false
${DebugMsg} "About to execute the following string and wait till it's done: $ExecString"
${Else}
${DebugMsg} "About to execute the following string and finish: $ExecString"
${EndIf}
!endif
${EmptyWorkingSet}
ClearErrors
${ReadLauncherConfig} $0 Launch HideCommandLineWindow
${If} $0 == true
; TODO: do this without a plug-in or at least some way it won't wait with secondary
ExecDos::exec $ExecString
Pop $0
${Else}
${IfNot} ${Errors}
${AndIf} $0 != false
${InvalidValueError} [Launch]:HideCommandLineWindow $0
${EndIf}
; There's probably a reason ExecWait was used here, but that prevents us from running things post exec but before the program has terminated
; The loop gated by WaitForProgram below seems to accomplish the same thing.
; In this case, we need to update the registry post exec, as the binary updates the registry at run time
Exec $ExecString
${EndIf}
${DebugMsg} "$ExecString has finished."
sleep 100
; TODO: make sure the program is still running (not a huge risk if sleep time is small)
StrCpy $URLCommand "%PAL:PortableAppsDir%\ObsidianPortable\ObsidianPortable.exe"
${ParseLocations} $URLCommand
${registry::Write} "HKCU\Software\Classes\obsidian\shell\open\command" "" "$URLCommand %1" "REG_SZ" $0
${DebugMsg} "Attempted to write to registry, operation returned $0"
${If} $WaitForProgram != false
; Wait till it's done
ClearErrors
${ReadLauncherConfig} $0 Launch WaitForOtherInstances
${If} $0 == true
${OrIf} ${Errors}
${GetFileName} $ProgramExecutable $1
${DebugMsg} "Waiting till any other instances of $1 and any [Launch]:WaitForEXE[N] values are finished."
${EmptyWorkingSet}
${Do}
${ProcessWaitClose} $1 -1 $R9
${IfThen} $R9 > 0 ${|} ${Continue} ${|}
StrCpy $0 1
${Do}
ClearErrors
${ReadLauncherConfig} $2 Launch WaitForEXE$0
${IfThen} ${Errors} ${|} ${ExitDo} ${|}
${ProcessWaitClose} $2 -1 $R9
${IfThen} $R9 > 0 ${|} ${ExitDo} ${|}
IntOp $0 $0 + 1
${Loop}
${LoopWhile} $R9 > 0
${DebugMsg} "All instances are finished."
${ElseIf} $0 != false
${InvalidValueError} [Launch]:WaitForOtherInstances $0
${EndIf}
${EndIf}
!macroend
My question is, is there a supported way to do this that I missed?
As an aside, it's my understanding that associations are horribly broken by win 8/10, but it seems that the user choice dialog is only triggered in certain flows - triggering url associations from within the app doesn't bring up the user choice dialog, it just works. The application needs a url association to open files in a different vault (vaults are just folders)