Skip to content
⌘ NSIS Forum Archive

Create Service

34 posts

stonkers#

Create Service

Is it possible to create a service with Sunjammers Service Plugin?

Maybe:

Services::SendServiceCommand 'create' 'myServiceName'
kichik#
dselkirk's service library can create services. Find it in the following link:

stonkers#
Great! For this guy, I just place it in the NSIS\Include folder and do a "!include servicelib.nsh" prior to using it? Sorry, another newbie question...
stonkers#
OK, yep, that worked. Now having trouble using multiple parameters. In the comments, it looks like the parameters should be separated by semicolons, but that would comment out those parameters. Any help?

Thanks
stonkers#
Guess I'm having a conversation with myself. It doesn't seem to be multiple paramaters. I'm trying to tell it to run by a domain account using:

!insertmacro SERVICE "create" "myService" \
"path=D:\pathToExe\Service.exe;autostart=0; \
user=DOMAIN\user;password=userPassword"

Changing autostart on and off works; thus multiple params works. However, I can't get it to create the service with a domain account. Is there a trick?

Thanks,
kichik#
; doesn't start a comment if within quotes. dselkirk would have to answer the domain question.
dselkirk#
I'm looking at the problem right now. I'll release it with version 1.2 which I'm hoping will be done today or tomorrow. It will have some extra features as well.
dselkirk#
Please excuse the delay, I haven't had as much time as I wanted on updating the servicelib. I've attached the new version, it still needs to be tested but it gives you something to try.

New in version 1.2
- fixed domain name (from what info I found) use: domain\user
- add desc paramater
- changed autostart to type with more options
- added dispplay for settings the service displayname
- added log for setting the eventlog
- added quick macro for the service macro

Let me know if you find any problems. I'll do my best to try and finish it up.

Don
stonkers#
I got an error with the new servicelib.nsh:

"Install corrupted: invalid opcode"

Any clue dselkirk?
Joost Verburg#
That's probably a wrong relative jump.

There are also some relative jumps used to jump over plug-in calls, which will result in unexpected behavior, because plug-in calls are being converted by the compiler (see documentation for details).
stonkers#
I don't have any relative jumps in my script, and the only places where dselkirk possibly (is System:: a plug-in?) breaks the rules in the doc is:

IntCmp $5 0 +2
System::Call 'advapi32::CloseServiceHandle(i r5) n'
IntCmp $4 0 +2
System::Call 'advapi32::CloseServiceHandle(i r4) n'
Pop $4

But I changed the relative jumps to labels and still got the error.
stonkers#
I stuck a bunch of debug statements in there (message boxes) and the last command it executes is:

!macro CALL_GETPARAM VAR NAME DEFAULT LABEL
Push $1
Push ${NAME}
Call ${UN}GETPARAM
Pop $6
StrCpy ${VAR} "${DEFAULT}"

<!--this one below-->
StrCmp $6 "" "${LABEL}" 0
<!--this one above-->

StrCpy ${VAR} $6
!macroend

Unfortunately, I don't have much of a grip on this scripting language yet. Sorry I can't be of more help.
stonkers#
No, that was wrong. I stuck a TON more debug statements in there (is there a better way to debug than with message boxes?) and found the actual last line to compile as follows:

lbl_good:
StrCpy $0 "true"
lbl_done:
IntCmp $5 0 +2
System::Call 'advapi32::CloseServiceHandle(i r5) n'
IntCmp $4 0 +2
System::Call 'advapi32::CloseServiceHandle(i r4) n'
Pop $4
Pop $3
Pop $2
Pop $1
<!--Right after here-->
Exch 3
<!--Right before here-->
Pop $5
Pop $6
Pop $7
Exch $0
!macroend

So by the doc, it looks like this means the stack is too low to perform this command???
stonkers#
I don't know if my debugging is valid here:

lbl_good:
StrCpy $0 "true"
lbl_done:
IntCmp $5 0 mylabel1
MessageBox MB_OK "using first system call"
System::Call 'advapi32::CloseServiceHandle(i r5) n'
mylabel1:
IntCmp $4 0 mylabel2
MessageBox MB_OK "using second system call"
System::Call 'advapi32::CloseServiceHandle(i r4) n'
mylabel2:
Pop $4
MessageBox MB_OK "$4"
Pop $3
MessageBox MB_OK "$3"
Pop $2
MessageBox MB_OK "$2"
Pop $1
MessageBox MB_OK "$1"

Exch 3

Pop $5
Pop $6
Pop $7
Exch $0
!macroend

but if so, the problem is that the system call doesn't put anything on the stack for this guy. It went into the second system call and each Pop put nothing into $?.
deguix#
Hmmmm.... This code is not wrong to give that error.... Attach the WHOLE script used to compile the program.
fraefel#
Originally posted by stonkers
No, that was wrong. I stuck a TON more debug statements in there (is there a better way to debug than with message boxes?) and found the actual last line to compile as follows:
Have a look at DumpState on NSIS Archive 👍
stonkers#
I have the servicelib.nsh file in the includes folder. Running the beta version of NSIS. Here's the script. Pretty straight-forward:

;----------------------------------

;NSIS Script For Doc

;Included file(s)

!include servicelib.nsh

;Backgound Colors
BGGradient 800080 000000 FFFFFF
BrandingText " "

;Title Of Your Application
Name "MyApp"

;Do A CRC Check
CRCCheck On

;Output File Name
OutFile "CreateService.exe"

;The Default Installation Directory
InstallDir "$PROGRAMFILES\MyApp"

;The text to prompt the user to enter a directory
DirText "Stick it in here"

Section 1

!insertmacro SERVICE "create" "MyService" \
"path=$INSTDIR\MyApp\bin\Service.exe;user=DOMAIN\MyUser;password=psswd"

SectionEnd
kichik#
Exch can cause Invalid Op errors too if not used properly. According to your test it is Exch that causes it and that indicates something is wrong with the stack operations in the macros.
dselkirk#
Found the problem. You forgot an extra ";" at the end of your parameter list. It should look like this:

!insertmacro SERVICE "create" "MyService" \
"path=$INSTDIR\MyApp\bin\Service.exe;user=DOMAIN\MyUser;password=psswd;"
stonkers#
I've got dumpstate fired up now, I'll be able to give you more info. I'll put that ";" in there also.
dselkirk#
Found the problem. Quick fix. In the library, goto "lbl_create:". There are serveral Push statements. After "Push $R8 ;desc", add "Push $R9 ;log". Let me know
stonkers#
So here's the code that's being executed:

System::Call 'advapi32::CloseServiceHandle(i r4) n'
Dumpstate::debug ;1
Pop $4
Dumpstate::debug ;2
Pop $3
Dumpstate::debug ;3
Pop $2
Dumpstate::debug ;4
Pop $1
Dumpstate::debug ;5
Exch 3

At each of the dumpstate commands:

1) $0 = true
$1 = the path to my executable
$2 = my app name
$3 = create
$4 = 1315648
$5 = empty
$6 = 1322456
$7-> empty
2) $0 = true
$1 = the path to my executable
$2 = my app name
$3 = create
$4 = empty
$5 = empty
$6 = 1322456
$7-> empty
3) $0 = true
$1 = the path to my executable
$2 = my app name
$3 = empty
$4 = empty
$5 = empty
$6 = 1322456
$7-> empty
4) $0 = true
$1 = the path to my executable
$2 = empty
$3 = empty
$4 = empty
$5 = empty
$6 = 1322456
$7-> empty
5) $0 = true
$1 = empty
$2 = empty
$3 = empty
$4 = empty
$5 = empty
$6 = 1322456
$7-> empty

Install corrupted: invalid opcode

How can I see the stack? It's obviously empty. What should be there?
dselkirk#
Try the fix I posted. As for the stack, at that point of the library its cleaning up my variables. The only things in the stack would be values set in those variables before running the service command.
stonkers#
Well, I don't get the error anymore! But:

;----------------------------------

;NSIS Script For Doc

;Included file(s)

!include servicelib.nsh

;Backgound Colors
BGGradient 800080 000000 FFFFFF
BrandingText " "

;Title Of Your Application
Name "MyApp"

;Do A CRC Check
CRCCheck On

;Output File Name
OutFile "CreateService.exe"

;The Default Installation Directory
InstallDir "$PROGRAMFILES\MyApp"

;The text to prompt the user to enter a directory
DirText "Stick it in here"

Section 1

!insertmacro SERVICE "create" "MyService" \
"path=$INSTDIR\MyApp\bin\Service.exe;user=DOMAIN\MyUser;password=psswd;type=3;"

SectionEnd

;---------------------

gives me a service run by localhost that is of type "manual startup".
stonkers#
I've monkeyed around a bit more, and it looks like there is a misprint in the comments. type=2 creates automatic startup and 3 manual. I can't figure out for the life of me how to make it run by domain user though.
stonkers#
Well, I have a theory. The user tag is being used to create the service but not determine who to run it by. If I use my userID without the domain name (because I'm not a true user without the domain), the service will be created in "disabled" state.
jeff_hanna#
I realize this reply is almost 2 years after the last post in the thread. But, I'm having the exact same problem. Was a solution to starting a network service with a user/password ever found?