Failed to install and start Windows services in WiX installer - windows-services

I am creating an MSI package for installing and starting Windows services using WiX v3.8. The code as follows:
<Component Id="INSTALLAPSSERVICE" Guid="991D5F82-0E77-4FE3-B1D8-4C941B84C7CD" Win64="yes">
<File Id="ApsService.exe"
Name="ApsService.exe"
Source="Resource\ApsService.exe"
KeyPath="yes"
Vital="yes"
DiskId="1"></File>
<ServiceInstall Id="ApsServiceInstaller"
Name="ApsService"
DisplayName="ApsService"
Type="ownProcess"
Start="auto"
ErrorControl="normal"
Description="A monitor service for windows application."
Account="[SERVICEACCOUNT]"
Password="[SERVICEPASSWORD]"
Vital="yes"
Interactive="no"></ServiceInstall>
<ServiceControl Id="StartService"
Start="install"
Stop="both"
Remove="uninstall"
Name="ApsService"
Wait="yes"/>
</Component>
But install fails with the following errors in the log:
Executing op: ServiceControl(,Name=ApsService,Action=1,Wait=1,)
StartServices: Service: ApsService
Error 1920. Service 'ApsService' (ApsService) failed to start. Verify that you have sufficient privileges to start system services.
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 3676 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 1888 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 1764 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 3504 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 2100 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 2752 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 3672 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 3876 could not be cancelled. Error: 1168
MSI (s) (F0:D0) [15:57:28:630]: I/O on thread 1400 could not be cancelled. Error: 1168
MSI (s) (F0:C0) [15:57:28:630]: Product: WinApsSetup64 -- Error 1920. Service 'ApsService' (ApsService) failed to start. Verify that you have sufficient privileges to start system services.
How can I fix the errors?

The error message you are getting is the generic message the Windows Installer sends when it fails to start a service during install. Almost always the issue is that the Service is missing a dependency or otherwise not fully configured when the start occurs. To debug the root issue try:
Install the MSI package.
When the error dialog comes up indicating there is a failure to start the service *do not dismiss the dialog.
Start services.msc or use sc.exe from the command-line to attempt to start your service. The Windows Installer should have configured enough of the service to be able to debug deeper why it failed.
If necessary debug into your service executable directly to see why it cannot be started.
If this is a service written in managed code, ensure that it does not depend on files being placed in the GAC. Files are not in the GAC until very, very late during the installation process. If you must use files in the GAC, you will not be able to use the built-in ServiceControl element and will have to write a custom action to run after InstallFinalize. Note that after InstallFinalize a custom action will not be elevated so your service will have to support being started by non-elevated users. Again, I recommend not depending on the GAC.
Good luck debugging your service!

The ServiceInstall Account is obfuscated in the OP's example, but this error can happen if one forgets to fully qualify the account, as such:
<ServiceInstall ... Account="NT AUTHORITY\LocalService" />
Your installer will fail if you only specify the username (w/o the NT Authority) like this:
<ServiceInstall ... Account="LocalService" />

Remember to add "Log on as a service" rights to the [SERVICEACCOUNT],
To add the "Log on as a service" right to an account on your local computer
1) Open Local Security Policy.
2) In the console tree, double-click Local Policies, and then click User Rights Assignments.
3) In the details pane, double-click Log on as a service.
4) Click Add User or Group, and then add the appropriate account to the list of accounts that possess the Log on as a service right.
From: http://technet.microsoft.com/en-us/library/cc739424%28v=ws.10%29.aspx.

When debugging a service startup issue, I always just use a simple if() statement that checks for the existence of a particular file in the installation directory. When the service fails, I open a command prompt (before dismissing the dialog indicating the failure) and use "echo >thatfile" to create the file that I am looking for in the if(). The object of the if() is the Debugger.Launch() invocation.
Now, I can dismiss the dialog and rerun the installer and this time it will start the debugger and I can see what happens. I tend to use static class init as the moment to launch the debugger, but you can try to do it in "OnStart()", but if there are loading/binding issues, you probably won't get to that point before it dies. Whereas doing it during static class init will almost always tell you the things that you need to address as dependencies.

So I got this error today because my service had dependencies that had to be GACed before starting the service. As it turns out, dependencies are GACed last by the installer, and there's really no good way to get around this without building some kind of bootstraper/multipart installer.
However, I found the following resolution: deploy the assemblies both to the GAC and install them in the same directory as the service. This way, the service will be able to find the DLLs on start in the program files directory, and they will be GACed (which was a requirement for other reasons).
To do this, I had to create two separate component groups, and a "dummy" Directory:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="NameOfProgram" />
<Directory Id="GacDlls" Name="libs" />
</Directory>
</Directory>
I then create two Component Groups: one that has the exe and all libraries, and a second with the same libraries with the Assembly attribute set to ".net":
<ComponentGroup Id="ServiceLibs" Directory="GACDlls">
<Component Id="log4netGAC"
Guid="a23099ac-5880-4b6e-af3f-fa7cef113226">
<File Id="log4net.dllGAC"
Name="log4net.dll"
Source="..\ProjectDir\bin\$(var.Configuration)\log4net.dll"
KeyPath="yes"
Vital="yes"
DiskId="1"
Assembly=".net"
/>
</Component>
</ComponentGroup>
<ComponentGroup Id="ProductComponents" Directory="INSTALLDIR">
<Component Id="log4net"
Guid="463e05db-e248-44d7-bbde-467358b7310f">
<!-- normally we'd want to GAC this (Assembly=".net"), but that would prevent us from starting the service up during install so we'll just drop it in the program folder -->
<File Id="log4net.dll"
Name="log4net.dll"
Source="..\ProjectName\bin\$(var.Configuration)\log4net.dll"
KeyPath="yes"
Vital="yes"
DiskId="1"
/>
</Component>
... other components ...
</ComponentGroup>
And now it works!

I was also having this issue, an error kept occurring during installation even though the service registry keys were created and I was able to manually start the service.
So I solved it this way:
Instead of starting the service right at installation with the Service control:
<ServiceControl Id="StartService"
Start="install"
.. />
I just removed Start from the ServiceControl so the installer's success is not dependent on the service being started. You just need to start the service manually after successful installation which can be done easilly with a script.

Related

Jenkins Windows Slave setup using Winsw not working

Using this info https://hayato-iriumi.net/2019/05/23/how-to-install-jenkins-slave-as-windows-service/ we are setting up the Jenkins Slave on Windows server. Jenkins agent start from command line. but when we start from Windows service, its giving below error message? How to resolve this error message?
Service cannot be started. System.IO.InvalidDataException: Attribute <className> is missing in configuration XML
at winsw.Util.XmlHelper.SingleAttribute[TAttributeType](XmlElement node, String attributeName)
at winsw.Extensions.WinSWExtensionDescriptor.FromXml(XmlElement node)
at winsw.Extensions.WinSWExtensionManager.LoadExtension(String id)
at winsw.Extensions.WinSWExtensionManager.LoadExtensions()
at winsw.WrapperService.OnStart(String[] args)
at System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(Object state)
xml file we have
<service>
<id>JenkinsSlave</id>
<name>Jenkins agent</name>
<description>This service runs an agent for Jenkins automation server.</description>
<executable>c:\java\jdk-11\bin\java.exe</executable>
<arguments>-Xrs -jar "c:\jenkins\slave.jar" -jnlpUrl https://jenkinsmaster/jenkins/computer/slave01/slave-agent.jnlp -secret a4b5b4ddfd34a016cd3a8eb94cbe8f908613e33a66db5fa6f5f43a080aea3116 -workDir=c:\jenkins</arguments>
<workingdirectory>c:\jenkins</workingdirectory>
<logmode>rotate</logmode>
<onfailure action="restart">
<download from="https://jenkinsmaster/jenkins/jnlpJars/slave.jar" to="c:\jenkins\slave.jar">
<extensions>
<extension enabled="false" classname="winsw.Plugins.RunawayProcessKiller.RunawayProcessKillerExtension" id="killOnStartup">
<pidfile>c:\jenkins\jenkins_agent.pid</pidfile>
<stoptimeout>5000</stoptimeout>
<stopparentfirst>false</stopparentfirst>
</extension>
</extensions>
</download>
</onfailure>
</service>
Thanks
There are some errors in the sample "Jenkins-Slave.xml" that is presented at the linked web page (which yours is apparently based on). It has all elements and attributes named in lowercase, but actually some of them should be mixed case (as can be seen by the error message that it doesn't find attribute className).
Try this one instead:
<service>
<id>YourJenkinsSlaveServiceId</id>
<name>Your Jenkins Slave Service Name</name>
<description>This service runs an agent for Jenkins automation server.</description>
<executable>C:\Program Files\Java\JRE8\bin\java.exe</executable>
<arguments>-Xrs -jar "%BASE%\slave.jar" -jnlpUrl http://YourJenkinsServer:8080/computer/YourNodeName/slave-agent.jnlp -secret YourSecretStringConsistingOfHexadecimalCharacters -workDir=C:\YourNodeWorkDir</arguments>
<logmode>rotate</logmode>
<onfailure action="restart" />
<download from="http://YourJenkinsServer:8080/jnlpJars/agent.jar" to="%BASE%\slave.jar"/>
<extensions>
<extension enabled="true" className="winsw.Plugins.RunawayProcessKiller.RunawayProcessKillerExtension" id="killOnStartup">
<pidfile>%BASE%\jenkins_agent.pid</pidfile>
<stopTimeout>5000</stopTimeout>
<stopParentFirst>false</stopParentFirst>
</extension>
</extensions>
</service>
This is from a more detailed explanation of how to install an agent as a Windows service which I have given in this answer.
I too has the same issue similarly..
System.IO.FileNotFoundException: Unable to locate jenkins.xml file within executable directory or any parents
at winsw.ServiceDescriptor..ctor()
at winsw.WrapperService.Run(String[] _args, ServiceDescriptor descriptor)
at winsw.WrapperService.Main(String[] args)
Solution:
Save your jenkins-agent file as xml format. not just jenkins-agent.xml
we can use notepad++ to save the xml type.
similarly remove .exe at end of jenkins-agent.exe
Hope its useful.... cheers !!
The className, stopTimeout and stopParentFirst should not be in lower case.

get jmx attributes with jolokia telegraf

I have a JAVA application which I want to monitor its JMX attributes using telegraf tool.
The tool provides jolikia plugin to monitor JMX attributes. I have added following dependencies to my app's pom.xml file regarding Maven section of Jolokia documentation:
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-client-java</artifactId>
<version>1.3.7</version>
</dependency>
This is my /etc/telegraf/telegraf.conf file:
[[inputs.jolokia]]
context = "/jolokia/"
[[inputs.jolokia.servers]]
name = "wr-core"
host = "192.168.100.175"
port = "1998"
[[inputs.jolokia.metrics]]
name = "send_success"
mbean = "wr-core:type=monitor,name=execution"
attribute = "MessageSendSuccessCount"
The application is up in the provided IP/port (I can connect to it with jconsole). The application has a monitoring section which its object name (as shown in jconsole) is wr-core:type=monitor,name=execution and has the attribute MessageSendSuccessCount. But when I start telegraf service, following error occurs:
Jan 14 14:30:32 ZiZi telegraf[17258]: 2018-01-14T11:00:32Z E! Error in plugin [inputs.jolokia]: error performing request: Error decoding JSON response: invalid character '\x00' looking for beginning of value:
Note that 1998 is my app's jmx port. I also tried using 8778 which is jolokia-agent port; got:
Jan 14 14:40:03 ZiZi telegraf[9150]: 2018-01-14T11:10:03Z E! Error in plugin [inputs.jolokia]: error performing request: Post http://192.168.100.175:8778/jolokia/: dial tcp 192.168.100.175:8778: getsockopt: connection refused
EDIT 1:
I have checked my CLASSPATH and both jolokia-client and jolokia-core were listed: ../lib/jolokia-client-java-1.3.7.jar:../lib/jolokia-core-1.3.7.jar.
EDIT 2:
I have put following lines into my app's execution file:
JOLOKIA_OPTS=-javaagent:$LIB_PATH/jolokia-core-java-1.3.7.jar=port=8778,host=0.0.0.0
JAVA_OPTS="-mx4096M $JAVA_OPTS $JACOCO_OPTS $JOLOKIA_OPTS"
But when I run the file, I get this error (even though ../lib/jolokia-core-java-1.3.7.jar has been listed in the CLASSPATH):
Error opening zip file or JAR manifest missing : ../lib/jolokia-core-java-1.3.7.jar
Error occurred during initialization of VM
agent library failed to init: instrument
Found the solution.
I have skipped maven solution and tried the javaagent approach, but I had misunderstood the usage of javaagent previously; I should address jolokia jvm agent (this helped):
JOLOKIA_OPTS=-javaagent:/root/jolokia-jvm-1.3.7-agent.jar=port=8778,host=0.0.0.0
JAVA_OPTS="-mx4096M $JAVA_OPTS $JACOCO_OPTS $JOLOKIA_OPTS"
Now, my app starts with this log (successfully):
I> No access restrictor found, access to any MBean is allowed
Jolokia: Agent started with URL http://192.168.100.175:8778/jolokia/
In the other side there is no error in the telegraf console for jolokia anymore.
All the observation are implying the jolokia jvm library has been started and works successfully.
I have also found jolokia jmx documentation for using it as dependencies in the project; but since I'm not a JAVA expert (I'm testing the app), I prefer to currently use the javaagent approach and leave it for future study/experience. BTW, it may help the others.
EDIT 1:
I have found and deployed jolokia jvm agent using its spring support.
Configuring it in the spring XML file, I can now have jolokia jvm agent start listening at my app's startup.

SCP / SSHEXEC - number of connection attempts

I am using scp task followed by sshexec in my ant build.xml. I derive the value for password from a Password field on the screen. The user doesnt have the ability to check if its the right password or not until the task completes successfully.
As a result, if the entered password is incorrect, does Scp / sshexec retry to connect? Is there any handle to limit the number of connection retries?
The sshexec and scp tasks use Java Secure Channel JSch, see ant manual library dependencies.
I had a similiar problem, as JSch tries to authenticate 6 times configured in the com.jcraft.jsch.JSch Class. When wrong password was used, the user account got locked.
Simply patched the com.jcraft.jsch.JSch Class like this :
from :
config.put("MaxAuthTries", "6");
to :
config.put("MaxAuthTries", "3");
Means JSch will only try 3 times to authenticate.
-- Edit after comment --
Download JSch release zip here - the latest version is 0.1.51
Unzip
Open jsch-0.1.51/src/main/java/com/jcraft/jsch/JSch.java
Change line 124
from
config.put("MaxAuthTries", "6");
to
config.put("MaxAuthTries", "3");
Save
Run jsch-0.1.51/build.bat or build.sh according to your OS
Use jsch-0.1.51/dist/lib/jsch-0.1.5.jar
Here a solution which does not require you to manually patch and rebuild the JSch library.
In order to limit the retry count to 1, just add the following script snippet either at the beginning of your Ant script, or before invoking scp and sshexec tasks, e.g.:
<script language="javascript"> <![CDATA[
com.jcraft.jsch.JSch.setConfig("MaxAuthTries", "1");
]]> </script>
<sshexec host="..." username="..." password="..." command="..."/>
You'll need JSch 0.1.46 or higher! I tested with Ant 1.9.4 and JSch 0.1.51 / 0.1.52.

Openbravo ant build fails

I am trying to setup openbravo on eclipse environment with the above URL.
Development stack setup is done successfully. (ANT, Java, Postgresql)
At the openbravo source directory when i apply the command
ant install.source
Build failure due to errors -
/home/pos/sourcecode_openbravo/Openbravo-3.0MP21/build.xml:480: The following error occurred while executing this line:
480 <ant dir="${base.src}" target="compile.complete.development" inheritAll="true" inheritRefs="true" />
/home/pos/sourcecode_openbravo/Openbravo-3.0MP21/src/build.xml:874: The following error occurred while executing this line:
874 <jvmarg line="${env.CATALINA_OPTS}" />
/home/pos/sourcecode_openbravo/Openbravo-3.0MP21/src/build.xml:880: Directory
880 <jvmarg value="-Djava.io.tmpdir=${env.CATALINA_BASE}/temp" />
/var/lib/tomcat6/webapps/openbravo/WEB-INF/lib creation was not successful for an unknown reason
Any help would be appreciated. Thanks.
Sounds like a permission problem.
See the related section 'Permission issues' in openbravo wiki
EDIT
for the remaining issues, i believe the properties base.src, CATALINA_OPTS and CATALINA_BASE are not set properly. Check this via :
<echo>
$${base.src} => ${base.src}
$${env.CATALINA_OPTS} => ${env.CATALINA_OPTS}
$${env.CATALINA_BASE} => ${env.CATALINA_BASE}
</echo>
or simply output all available properties use :
<echoproperties/>
also consider, before using ${env.whatever} you need to use :
<property environment="env"/>
before !
/var/lib/tomcat6/webapps/openbravo/WEB-INF/lib creation was not successful for an unknown reason
Give the permission to webapps folder
sudo chmod -R 777 /var/lib/tomcat6/webapps/
/var/lib/tomcat6/webapps/openbravo/WEB-INF/lib creation was not
successful for an unknown reason
it seem permission problem. It is important to always us the correct user account to start / stop tomcat!
Conceptually there are two user accounts involved in working with Openbravo:
command-line user used to work with files & compile Openbravo
user account used by Apache Tomcat service
There are several overlapping areas in which one of the accounts needs to access and modify files from the other account in both directions.
To avoid any problems Openbravo strongly recommends to run Apache Tomcat services with the same user account which is used on command line. As that way the above topic will be perfectly solved easily.
source: http://wiki.openbravo.com/wiki/Installation/Custom/Apache_Tomcat

Messages from Gelf4Net are not stored in Graylog2

I have an Ubuntu server with Elasticsearch, MongoDB, and Graylog2 running in Azure, and I have an asp.net mvc4 application I am trying to send logs from. (I am using Gelf4Net / Log4Net as the logging component). To cut to the chase, nothing is being logged.
(skip to the update to see what is wrong)
The setup
1 Xsmall Ubuntu VM running the needed software for graylog2
everything is running as a daemon
1 Xsmall cloud service with the MVC4 app (2 instnaces)
A virtual network setup so they can talk.
So what have I tried?
From the linux box the follow command will cause a message to be logged echo "<86>Dec 24 17:05:01 foo-bar CRON[10049]: pam_unix(cron:session):" |
nc -w 1 -u 127.0.0.1 514
I can change the IP address to use the public IP and it works fine as well.
using this powershell script I can log the same message from my dev machine as well as the production web server
Windows firewall turned off and it still doesn't work.
I can log to a FileAppender Log4Net, so I know Log4Net is working.
tailing the graylog2.log shows nothing of interest. Just a few warning about my plugin directory
So I know everything is working, but I can't get the Gelf4Net appender to work. I'm a loss here. Where can I look? Is there something I am missing
GRAYLOG2.CONF
#only showing the connection stuff here. If you need something else let me know
syslog_listen_port = 514
syslog_listen_address = 0.0.0.0
syslog_enable_udp = true
syslog_enable_tcp = false
web.config/Log4Net
//application_start() has log4net.Config.XmlConfigurator.Configure();
<log4net >
<root>
<level value="ALL" />
<appender-ref ref="GelfUdpAppender" />
</root>
<appender name="GelfUdpAppender" type="Gelf4net.Appender.GelfUdpAppender, Gelf4net">
<remoteAddress value="public.ip.of.server"/>
<remotePort value="514" />
<layout type="Gelf4net.Layout.GelfLayout, Gelf4net">
<param name="Facility" value="RandomPhrases" />
</layout>
</appender>
</log4net>
update
for some reason it didn't occur to me to run graylog in debug mode :) Doing so shows this message.
2013-04-09 03:00:56,202 INFO : org.graylog2.inputs.syslog.SyslogProcessor - Date could not be parsed. Was set to NOW because allow_override_syslog_date is true.
2013-04-09 03:00:56,202 DEBUG: org.graylog2.inputs.syslog.SyslogProcessor - Skipping incomplete message.
So it is sending an incomplete message. How can I see what is wrong with it?
I was using the wrong port (DOH!)
I should have been using the port specified in graylog2.config / gelf_listen_port = 12201
so my web.config/log4net/gelf appender should have had
<appender name="GelfUdpAppender" type="Gelf4net.Appender.GelfUdpAppender, Gelf4net">
...
<remotePort value="12201" />
...
</appender>
For anyone who may have the same problem, make sure Log4Net reloads the configuration after you change it. I don't have it set to watch the config file for changes, so it took me a few minutes to realize that I was using the wrong port. When I changed it from 514 to 12201 the first time, messages still weren't getting though. I had to restart the server for Log4Net to pick up the new config, and then it started to work.

Resources