Skip to content
⌘ NSIS Forum Archive

Want use only SimpleSC with admin rights

8 posts

ikreb#

Want use only SimpleSC with admin rights

Hello,

i have a nsis file with the setting

RequestExecutionLevel user
but I want to start a windows service. I use NSIS Simple Service Plugin for it.

So I want that the UAC request will come only if I try to start a service. Is this possible? And if could you give me a hint, please?
Anders#
A process cannot elevate itself after it has been started.

The easy way is to create another mini installer that does the elevated operation. You must start it with ExecShell[Wait] when required.
ikreb#
I will show more code. Because the return code looks very randomly.

This is my nsis file which I want to execute with admin permissions.




;======================================================
; General

Name "Start service wlansvc"
OutFile "start_wlansvc.exe"

RequestExecutionLevel admin

;======================================================
; Functions

Function .onInit
; SilentInstall silent

; start wlansvc
SimpleSC::StartService "wlansvc" "" 30

FunctionEnd

;======================================================
; Sections

Section
SetAutoClose true

SectionEnd
And then I use this in my main nsis file


StrCpy $1 "start_wlansvc.exe" ; File to execute
System::Call '*(&l4, i ${SEE_MASK_NOCLOSEPROCESS}, p$HWNDPARENT, p0, tr1, p0, p0, p5, p0, p0, p0, p0, p0, p0, p)p.r1'
System::Call 'SHELL32::ShellExecuteEx(t)i.r0 (pr1)' ; (t) is a hint for A/W detection
${If} $0 <> 0
System::Call '*$1(i, i, p, p, p, p, p, p, p, p, p, p, p, p, p.r0)'
System::Call 'KERNEL32::WaitForSingleObject(p r0, i ${INFINITE})'
System::Call 'KERNEL32::GetExitCodeProcess(p r0 s,*i.r0)'
System::Call 'KERNEL32::CloseHandle(p s)'
DetailPrint ExitCode=$0
${EndIf}
MessageBox MB_OK $0
MessageBox MB_OK $1
System::Free $1
I think the problem is that the first nsis file returns the wrong return code. I tried this, but doesn't helps


SimpleSC::StartService "wlansvc" "" 30

Pop $0
Pop $1
${If} $0 == 0
${If} $1 == 0
SetErrorLevel 4
${EndIf}
${Else}
SetErrorLevel 4
${EndIf}
Anders#
The ShellExecute code works correctly and is not random as far as I can tell:

Section
System::Call '*(&l4, i ${SEE_MASK_NOCLOSEPROCESS}, p$HWNDPARENT, p0, t "cmd.exe", t "/c exit /b 666", p0, p5, p0, p0, p0, p0, p0, p0, p)p.r1'
System::Call 'SHELL32::ShellExecuteEx(t)i.r0 (pr1)' ; (t) is a hint for A/W detection
${If} $0 <> 0
    System::Call '*$1(i, i, p, p, p, p, p, p, p, p, p, p, p, p, p.r0)'
    System::Call 'KERNEL32::WaitForSingleObject(p r0, i ${INFINITE})'
    System::Call 'KERNEL32::GetExitCodeProcess(p r0 s,*i.r0)'
    System::Call 'KERNEL32::CloseHandle(p s)'
    MessageBox mb_ok ExitCode=$0 ; 666 every time
${EndIf}
System::Free $1
SectionEnd 
$1 will be "random" be cause it is a memory address but you don't need to look at it, just free it.

You can use Process Monitor from SysInternals to verify the exit code of start_wlansvc.exe.
ikreb#
Yes, this works with cmd.exe, but not with the nsis exe file "start_wlansvc.exe" which I showed at my last post.
Anders#
Section
SetErrorLevel 4
GetErrorLevel $0
MessageBox mb_ok ErrorLevel=$0
Quit
SectionEnd 
Process exit code is 4, confirmed by Process Monitor.