How can I enable the cancel button in an electron-built application? - electron

I'm working with an electron application that is built via electron-builder. When I generate the installer and begin installing with it, I see that the cancel button is disabled.
I've looked around at some electron builder documentation and done a few google searches but I seem to be coming up blank here.
edit: Discovered that I can use build/installer.nsh to actually modify UI elements, now I'm just wondering, how do I gain access to the button to enable / disable it, the examples I've seen use an .ini file to store options or something similar, but I'm getting recommendations to use nsDialogs.
Is nsDialogs something that's already readily accessible to me or do I need to import something into my installer.nsh file to use nsDialogs?
And by that token, how would I access the cancel button in nsDialogs?
Is there a configurable value that enables me to... enable that cancel button so users can choose to cancel during installation?
Thanks!

NSIS installers do not support canceling the installation when you enter the InstFiles page (or any page after it). This is by design because of how the scripting language works.
If you don't mind hacks you can call the uninstaller when the user clicks cancel during the install phase:
Var Cancel
!include LogicLib.nsh
!include WinMessages.nsh
Function .onUserAbort
StrCmp $Cancel "" +3
IntOp $Cancel $Cancel | 1
Abort
FunctionEnd
!macro FakeWork c
!if "${c}" < 10
Sleep 333
DetailPrint .
!define /redef /math c "${c}" + 1
!insertmacro ${__MACRO__} "${c}"
!endif
!macroend
Section Uninstall
!insertmacro FakeWork 0
Delete "$InstDir\Uninst.exe"
RMDir "$InstDir"
SectionEnd
Function CheckCancel
${If} $Cancel = 1
IntOp $Cancel $Cancel + 1
GetDlgItem $0 $hwndParent 2
EnableWindow $0 0
DetailPrint "Canceling..."
SetDetailsPrint none
ExecWait '"$InstDir\Uninst.exe" /S _?=$InstDir'
Delete "$InstDir\Uninst.exe"
RMDir "$InstDir"
SetDetailsPrint both
Quit
${EndIf}
FunctionEnd
Section
SetOutPath $InstDir
WriteUninstaller "$InstDir\Uninst.exe"
StrCpy $Cancel 0 ; Allow special cancel mode
GetDlgItem $0 $hwndParent 2
EnableWindow $0 1 ; Enable cancel button
!insertmacro FakeWork 0 ; Replace these with File or other instructions
Call CheckCancel
!insertmacro FakeWork 0
Call CheckCancel
!insertmacro FakeWork 0
Call CheckCancel
StrCpy $Cancel "" ; We are done, ignore special cancel mode
SectionEnd
(I have no idea how to integrate this with electron-builder, sorry)
If you want a proper roll-back installer, try Inno Setup or WiX (MSI).

Related

NSIS Setting temporary Environment Variables does not work

I'm trying to update the path of my JAVA_HOME Following the instruction of this page
But just after having set new value, the value seems not to have changed.
This is my code :
StrCpy $TemplateJavaPath "$INSTDIR\jdk1.7.0_03"
System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("JAVA_HOME", "$TempJavaPath").r0'
ReadEnvStr $R0 "JAVA_HOME"
MessageBox MB_OK $R0 ; The value is still C:\program Files\Java6...
ExecWait '"C:\test.bat" ;containing the single line echo %JAVA_HOME%, set to Java6...
I made the same test with PATH with the same result.
Any idea ?
The wiki page where you got that code is/was wrong, you should never mix the A/W function suffix with the t type.
Var /Global TempJavaPath
StrCpy $TempJavaPath "C:\foo\bar"
System::Call 'kernel32::SetEnvironmentVariable(t "JAVA_HOME", t "$TempJavaPath")i'
Exec '"cmd" /k echo %JAVA_HOME%'
This will only work for processes started by your setup, you need to write to the registry if this variable should apply to all processes...

Batch File Help-Youtube Auto viewer. How to stop loop after specfic amount of time and user input beforehand

Hiya made a simple Youtube autoviewer using notepad*BATCH FILE but i want to have user input--> so the user can change the link before pressing start
And i wont it to stop script after its LOOPS 250 times.
:top
start /min iexplore.exe http://www.youtube.com/watch?v=u5DzRTyhs_0
#echo "waiting"
ping -n 5 127.0.0.1>nul
#echo "done waiting"
TASKKILL /F /IM "iexplore.exe"
ipconfig /release /renew
GOTO top
So USER CAN CHANGE URL LINK THEN PRESS START.
Many thks
Add after "start /min iexplore.exe http://www.youtube.com/watch?v=u5DzRTyhs_0":
set /a number=%number% + 1
if "%number%"=="250" (goto whereever)
if not "%number%"=="250" (goto whereever)
http://www.mpgh.net/forum/showthread.php?t=754730 <-- Working EXE version, finlayy finish coding it!
for /L %a in (1,1,10) do #(echo run %a&batch.exe)
http://www.pcreview.co.uk/forums/loop-example-cmd-window-t1468124.html

Calling an embedded installer in NSIS on UAC with timeout

I have an NSIS installer which has 'RequestExecutionLevel user'. That installer contains an embedded NSIS installer which has 'RequestExecutionLevel admin'. This child installer is only called in certain scenarios. This was done so that certain admin operations could be contained in the child installer and the user would only be prompted for UAC approval when nessacary.
My question is, how can I invoke the child installer so that:
a) the user will be prompted with the UAC dialog (if UAC is enabled), and
b) the child installer will be terminated if the user does not click Yes or No within a given time period.
I have been using ShellExecWait (http://nsis.sourceforge.net/ShellExecWait), which works well, but does not provide the option to specify a timeout value (i.e. it will wait forever).
Note that I have already tried using the following NSIS functions:
* ShellExecWait - Does not allow timeout
* ExecWait - The child installer fails as it inherits the parent installer's execution level.
* ExecShell - Does not allow timeout
* nsExec::Exec - The child installer fails as it inherits the parent installer's execution level.
I'm getting pretty desperate here - any help would be appreciated.
UAC is not designed to support this and any attempt to do this should be considered a hack!
Part of the problem is that ShellExecuteEx in your process is part of the elevation operation so it cannot be killed without killing the thread or process. To work around this I allow the setup to act as a middle man that we can kill. One flaw with this design is that the UAC dialog stays around after the timeout has killed the process (The UAC GUI is in consent.exe running as SYSTEM) This means that the user could elevate the child installer after your main installer is gone! I only tested this on Win7 and there UAC does not start a new process if the parent is gone but this could be a bug or at least the behavior is not documented AFAIK and probably not something that should be used in production code!
Outfile "test.exe"
RequestExecutionlevel User
!include LogicLib.nsh
!include WinMessages.nsh
!include FileFunc.nsh
Page Instfiles
!macro ElevateWithTimeout_OnInit
${GetParameters} $0
${GetOptions} $0 '--ExecTimer' $1
${If} $1 != ""
StrCpy $1 $0 "" 12
ExecShell 'runas' $1 ;RunAs is not really required as long as the .exe has a manifest that requests elevation...
Quit
${EndIf}
!macroend
Function ElevateWithTimeout
InitPluginsDir
System::Call '*(&i60,tsr1)i.r0'
StrCpy $1 "--ExecTimer $1"
System::Call '*$0(i 60,i 0x40,i $HwndParent,i0,t"$ExePath",tr1,to,i1)i.r0'
System::Call 'shell32::ShellExecuteEx(ir0)i.r1'
System::Call '*$0(i,i,i,i,i,i,i,i,i,i,i,i,i,i,i.r2)'
System::Free $0
Pop $0 ; Timeout (MS)
${If} $1 <> 0
System::Call 'kernel32::WaitForSingleObject(ir2,ir0)i.r0'
${If} 0x102 = $0 ;WAIT_TIMEOUT
System::Call 'kernel32::TerminateProcess(ir2,i666)'
${EndIf}
System::Call 'kernel32::CloseHandle(ir2)'
${EndIf}
FunctionEnd
Function .onInit
!insertmacro ElevateWithTimeout_OnInit
FunctionEnd
Section
Push 30000
Push "regedit.exe"
call ElevateWithTimeout
SectionEnd
To create a safer more robust solution the child installer would have to be in on the game and know when to abort itself if the parent is gone but doing that in pure NSIS code is way too much work.
I would probably recommend that you drop the timeout requirement and use RequestExecutionlevel highest in the outer installer and only run the child if you are admin (UserInfo::GetAccountType).

Responsive Compile-and-Run Vim Mapping

I have the following mapping in my .vimrc.
:nmap <F5> :<C-U>make %:r && ./%:r<CR>
I press F5 in VIM, and it compiles, exits VIM, and runs my code. When the program terminates, it asks me to "press ENTER or enter a command to continue." It then takes me to a blank screen with the text (1 of 5): and the same "press ENTER or enter a command to continue" prompt. I press enter and it finally returns me back to VIM. This behavior is consistent across the board. Is there a way to remove any or both of those occurrences? Perhaps have the mapping press ENTER twice after the program terminates? If so, how?
EDIT: So I realized appending two more <CR>'s doesn't quite solve the problem. As soon as the program terminates, it IMMEDIATELY goes back to VIM and I don't have time to review the output. Can I make the mapping wait for ME to press the first enter, and automatically press the 2nd ENTER afterwards?
Would this work:
nmap <F5> :<C-U>silent make %:r<CR>:redraw!<CR>:!./%:r<CR>
A longer solution but this one also allows you to see errors (reference):
:function! MakeAndRun()
: silent make %:r
: redraw!
: if len(getqflist()) == 1
: !./%:r
: else
: for i in getqflist()
: if i['valid']
: cwin
: winc p
: return
: endif
: endfor
: endif
:endfunction
:nmap <F5> :call MakeAndRun()<cr>
Yes and yes (you answered your own question):
:nmap <F5> :<C-U>make %:r && ./%:r<CR><CR>
For me this works fine:
" Compile
noremap <F4> :<C-U>silent make<CR>:redraw!<CR>
" Automatically open, but do not go to (if there are errors) the quickfix /
" location list window, or close it when is has become empty.
autocmd QuickFixCmdPost [^l]* nested cwindow
autocmd QuickFixCmdPost l* nested lwindow
It compiles, and immediately jumps to vim, showing the quickfix window. No intermediate enters.

Vim script to compile TeX source and launch PDF only if no errors

I am switching to using Vim for for my LaTeX editing environment. I would like to be able to tex the source file from within Vim, and launch an external viewing if the compile was successful.
I know about the Vim-Latex suite, but, if possible, would prefer to avoid using it: it is pretty heavy-weight, hijacks a lot of my keys, and clutters up my vimruntime with a lot of files.
Here is what I have now:
if exists('b:tex_build_mapped')
finish
endif
" use maparg or mapcheck to see if key is free
command! -buffer -nargs=* BuildTex call BuildTex(0, <f-args>)
command! -buffer -nargs=* BuildAndViewTex call BuildTex(1, <f-args>)
noremap <buffer> <silent> <F9> <Esc>:call BuildTex(0)<CR>
noremap <buffer> <silent> <S-F9> <Esc>:call BuildTex(1)<CR>
let b:tex_build_mapped = 1
if exists('g:tex_build_loaded')
finish
endif
let g:tex_build_loaded = 1
function! BuildTex(view_results, ...)
write
if filereadable("Makefile")
" If Makefile is available in current working directory, run 'make' with arguments
echo "(using Makefile)"
let l:cmd = "!make ".join(a:000, ' ')
echo l:cmd
execute l:cmd
if a:view_results && v:shell_error == 0
call ViewTexResults()
endif
else
let b:tex_flavor = 'pdflatex'
compiler tex
make %
if a:view_results && v:shell_error == 0
call ViewTexResults()
endif
endif
endfunction
function! ViewTexResults(...)
if a:0 == 0
let l:target = expand("%:p:r") . ".pdf"
else
let l:target = a:1
endif
if has('mac')
execute "! open -a Preview ".l:target
endif
endfunction
The problem is that v:shell_error is not set, even if there are compile errors. Any suggestions or insight on how to detect whether a compile was successful or not would be greatly appreciated! Thanks!
Between the answers given here, plus some study of other approaches, I think that this has been satisfactorily solved. I am posting the solution here in case anyone else is interested.
Basically, the best solution appears to be to use Rubber, a wrapper around LaTeX, that generally "just works", and provides very clean output/errors. The solution I present below preferentially uses Rubber if it is found on the system and no Makefile is found in the current directory. If a Makefile is found, it uses that instead. If there is no Makefile and Rubber is not installed, it uses pdflatex. In all cases, if the source fails to compile, the (filtered and parsed) errors are sent to the QuickFix buffer and the QuickFix window is automatically opened. If it compiles successfully, a short message is written, and if the user requested it, the PDF will be opened for viewing.
In my own installation, I have lifted the (excellent) "SetLatexEfm()" function from Vim-Latex to parse and filter the tex build output. If this function is not found, however, the function below defaults to setting an error message format that works fine enough for the errors to be identified and highlighted in the QuickFix window, albeit with lots of crud.
function! BuildTex(view_results, ...)
" record position
let save_cursor = getpos(".")
" save work
silent write
" From: http://stackoverflow.com/questions/2679475/vim-script-to-compile-tex-source-and-launch-pdf-only-if-no-errors
" If your shell is bash, you can use the ${PIPESTATUS} array variable to get
" the correct exit code (borrowed from this answer to another question).
silent setlocal shell=bash
silent setlocal shellpipe=2>&1\ \|\ tee\ %s;exit\ \${PIPESTATUS[0]}
let success = 1
if filereadable("Makefile")
" If Makefile is available in current working directory, run 'make' with arguments
echon "compiling using Makefile ..."
let l:makecmd = "make\\ ".join(a:000, '\\ ')
silent execute "setlocal makeprg=" . l:makecmd
try
" This function is defined in the Vim-Latex package,
" and provides excellent parsing and filtering of the error messages
" when running latex outside of the Rubber wrapper.
call s:SetLatexEfm()
catch /E117/
set errorformat=%E!\ LaTeX\ %trror:\ %m,
\%E!\ %m,
\%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%#,
\%+W%.%#\ at\ lines\ %l--%*\\d,
\%WLaTeX\ %.%#Warning:\ %m,
\%Cl.%l\ %m,
\%+C\ \ %m.,
\%+C%.%#-%.%#,
\%+C%.%#[]%.%#,
\%+C[]%.%#,
\%+C%.%#%[{}\\]%.%#,
\%+C<%.%#>%.%#,
\%C\ \ %m,
\%-GSee\ the\ LaTeX%m,
\%-GType\ \ H\ <return>%m,
\%-G\ ...%.%#,
\%-G%.%#\ (C)\ %.%#,
\%-G(see\ the\ transcript%.%#),
\%-G\\s%#,
\%+O(%f)%r,
\%+P(%f%r,
\%+P\ %\\=(%f%r,
\%+P%*[^()](%f%r,
\%+P[%\\d%[^()]%#(%f%r,
\%+Q)%r,
\%+Q%*[^()])%r,
\%+Q[%\\d%*[^()])%r
endtry
silent make
else
let l:special_tex_compiler = "rubber"
if executable(l:special_tex_compiler)
echon "compiling with Rubber ..."
silent execute "setlocal makeprg=" . l:special_tex_compiler . "\\ -dfs\\ %"
setlocal errorformat=%f:%l:\ %m
silent make %
else
echon "compiling ..."
let b:tex_flavor = 'pdflatex'
compiler tex
silent make %
endif
endif
" set/report compile status
if v:shell_error
let l:success = 0
" let l:wheight = winheight(bufnr("%")) / 2
" execute "copen ".l:wheight
copen
else
let l:success = 1
cclose
redraw
echon "successfully compiled"
endif
" view results if successful compile
if l:success && a:view_results
call ViewTexResults()
endif
" restore position
call setpos('.', save_cursor)
endfunction
function! ViewTexResults(...)
if a:0 == 0
let l:target = expand("%:p:r") . ".pdf"
else
let l:target = a:1
endif
if has('mac')
silent execute "! open -a Preview ".l:target
" obviously, you will need to write specific commands for other systems
" left as an exercise for the reader ...
endif
endfunction
command! -buffer -nargs=* BuildTex call BuildTex(0, <f-args>)
command! -buffer -nargs=* BuildAndViewTex call BuildTex(1, <f-args>)
noremap <buffer> <silent> <F9> <Esc>:call BuildTex(0)<CR>
noremap <buffer> <silent> <S-F9> <Esc>:call BuildTex(1)<CR>
Update: I have packaged and published this as a Vim file-type plugin script, available at: http://www.vim.org/scripts/script.php?script_id=3230.
Assuming you're falling into the else-theres-no-makefile section, the issue may be with the shellpipe variable.
On my system (Ubuntu), shellpipe=2>&1| tee and the built-in make call doesn't set v:shell_error if it fails.
The return status of | tee might be what v:shell_error is getting set to.
If your shell is bash, you can use the ${PIPESTATUS} array variable to get the correct exit code (borrowed from this answer to another question).
:set shellpipe=2>&1\ \|\ tee\ %s;exit\ \${PIPESTATUS[0]}
Otherwise, you can try:
:set shellpipe=\>
:make %
This sets v:shell_error when it fails but I'm not sure if that will mess with the go-to-error-line-number functionality, if there is any.
To see what the variable is set to:
:set shellpipe?
I know it's not related to vim, but I think that latexmk does the job.
It's a script (written in perl) which compile the latex file and update the pdf. The most useful future is the auto-update one. As soon as you save your file, 'latexmk' compile it, and if your pdf viewer supports it, the view is updated.
latexmk -pdf -pvc
If latexmk runs latex with the '-halt-on-error' option (or in nonstop mode), compilation will cease without pausing for input.

Resources