wix service not starting with localized accounts - localization

I have a couple of WIX projects that start install and start services. As I need the installers to work on non-English machines, I have been using WixQueryOsWellKnownSID properties to provide localised account names for the services.
But I have obviously got something wrong; because although the services install, they do not start in certain locales. So far, I know the installers work in Holland, France, Japan, & China; but do not work in Germany & Belgium, (the language on the Belgium machines was French).
During install, we get an "Service 'ServiceName' failed to start. Verify that you have sufficient privileges to start system services." error message.
If I ignore the error and then open the Services MMC, the Service is shown as having a localised account name, (NT-AUTORITÄT\NETZWERKDIENST on a German machine); if I then manually set the service account to network service, the Services MMC displays Netzwerkdienst, and the service runs fine.
I have tested this with Windows7 and Server2008R2 - same issue on both OS's.
The WIX service code:
<PropertyRef Id="WIX_ACCOUNT_NETWORKSERVICE"/>
<Component Id="ProductComponent" Guid="5bcdeb4a-9832-4a01-9863-60bc0634a8fd">
<File Id="$(var.WebLoggerSR2Service.TargetName)" Name="$(var.WebLoggerSR2Service.TargetFileName)"
Source="$(var.WebLoggerSR2Service.TargetPath)" DiskId="1" KeyPath="yes" Checksum="yes"></File>
<ServiceInstall Id="ServiceInstaller" Type="ownProcess" Name="$(var.WebLoggerSR2Service.TargetName)"
Description="!(loc.SVCINST_DESCRIPTION)"
ErrorControl="normal" Start="auto" Account="[WIX_ACCOUNT_NETWORKSERVICE]"/>
<ServiceControl Id="StartWixServiceInstaller"
Name="$(var.WebLoggerSR2Service.TargetName)" Start="install" Wait="no" />
<ServiceControl Id="StopWixServiceInstaller" Name="$(var.WebLoggerSR2Service.TargetName)"
Stop="both" Wait="yes" Remove="uninstall" />
<Util:EventSource xmlns:Util="http://schemas.microsoft.com/wix/UtilExtension"
Name="$(var.WebLoggerSR2Service.TargetName)" Log="Application"
EventMessageFile="[NETFRAMEWORK20INSTALLROOTDIR]EventLogMessages.dll" />
<RemoveFolder Id="INSTALLLOCATION" On="uninstall"/>
</Component>
I am using WIX version 3.9.16.0 with Votive on Visual Studio 2012

Maybe just a comment but too long for that space....
The docs on NetworkServiceAccount say:
This account can be specified in a call to the CreateService and ChangeServiceConfig functions. Note that this account does not have a password, so any password information that you provide in this call is ignored. While the security subsystem localizes this account name, the SCM does not support localized names. Therefore, you will receive a localized name for this account from the LookupAccountSid function, but the name of the account must be NT AUTHORITY\NetworkService when you call CreateService or ChangeServiceConfig, regardless of the locale, or unexpected results can occur.
(learn.microsoft.com)
This is pretty weird if it's correct because it seems to be saying that CreateService (which is what MSI is ultimately calling) needs the English form of the name, but when you actually ask for it you'll get the localized name. That's why you see the localized name n MMC, so my dumb question is have you tried just using the standard English form on the other language OS versions?

Related

Application Settings in Azure Portal not Overwriting Generic Values

This is my process for setting some connection strings in my Azure hosted app:
When debugging, the strings are stored in Web.Config as normal, and this is encrypted with aspnet_regiis to hide them in the version control.
At publish, these are set to some generic values in Web.Release.Config:
<add xdt:Transform="Insert" name="SPsvcUsername" connectionString="username"/>
<add xdt:Transform="Insert" name="SPsvcPassword" connectionString="password"/>
I then go into the App Service on the Azure portal and under Application Settings -> Connection Strings I add the actual values required, just using the same name, e.g. SPsvcUsername. This overwrites the generic values and everything is fine and dandy.
This has always worked since I started doing it and I have had 0 issues apart from ocasionally I would have to wait a couple of minutes for it to update.
However, today it just doesn't apply the settings that I input in Azure Portal.
When I go into the command prompt and call
more web.config
I can see that the connection string scontains the generic values username and password
What gives? Why did this suddenly stop working? Was there an update that addressed this that I haven't read about?
Any advice is much appreciated. Including anything on whether my original process actually makes any sense.
They are replaced at runtime, not in the file.
So when you access the connection string via:
string username = ConfigurationManager.ConnectionStrings["SPsvcUsername"].ConnectionString;
It will have the value from the Application Settings blade.

Service installation fails as event source already exists

I'm trying to configure a Topshelf-based Windows service to log to a custom event log using Topshelf.Log4Net and log4net. This works fine if I run the application in command-line mode. When I try to install the service with BillsTestService.exe install, I get:
INFO Topshelf v3.1.107.0, .NET Framework v4.0.30319.18052
DEBUG Attempting to install 'BillsTestService'
Running a transacted installation.
...
Service BillsTestService has been successfully installed.
Creating EventLog source BillsTestService in log Application...
An exception occurred during the Install phase.
System.ArgumentException: Source BillsTestService already exists on the local computer.
...
at System.Diagnostics.EventLog.CreateEventSource(EventSourceCreationData sourceData)
I've tried running EventLog.DeleteEventSource("BillsTestService"); in LINQPad before installing; that succeeds, but a subsequent service install still fails.
My log4net appender configuration is:
<appender name="ErrorEventLogAppender" type="log4net.Appender.EventLogAppender" >
<threshold value="ERROR" />
<logName value="MyCompanyServices" />
<applicationName value="BillsTestService" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %logger - %message%newline" />
</layout>
</appender>
What am I doing wrong?
The intent is to have multiple services log errors to the same log name (with different application names); the log would be created by Operations.
Part of the issue is that Topshelf automatically creates an eventlog source named after the service when you install. Since the log4net appender applicationName is also used as an eventlog source, that cannot be the actual application/service name. The source must be unique on the local computer. I added a "Source" suffix to the name in the log4net configuration.
The other part is that the service does not have rights to create the log. It can create a new source, but not a new log. One way to do this is in code (I used LINQPad):
EventLog.CreateEventSource("FOODEBUG", "MyCoSvc");
EventLog mylog = new EventLog("MyCoSvc");
mylog.Source = "FOODEBUG";
mylog.WriteEntry("This is a test.");
EventLog.DeleteEventSource("FOODEBUG");
I'm not positive if you actually have to write to the log to create it; after spending over two days on this, I'd rather be safe.
Also note that log names are limited to 8 characters; you can go longer, but the system only considers the first 8 characters as significant.
There's no need to move the log4net initialization as Chris Patterson suggested. Simply including
configurator.DependsOnEventLog();
configurator.UseLog4Net("MyService.exe.config");
in the HostFactory.Run delegate is sufficient. (I'm using Topshelf.Log4Net.)
Finally, I'm reasonably sure that the entire Windows event logging system is flaky. Event Viewer's refresh doesn't work in all cases, at one point my Application log entries disappeared, and I believe I've seen different results after a reboot.
Move your log4net initialization to the ConstructUsing() configuration delegate for the service instead of specifying for use during install/uninstall which doesn't require the service class to be instantiated.
Or, only use the event log appender when the actual service is running, by either adding the appender outside of the config file or modifying the configuration to eliminate the event log appender unless an ERROR or FATAL event occurs.
My guess is the DEBUG/INFO level events are trying to log to the appender, and the source does not exist yet.

How does CXF translate WSDL's localhost to actual server URL?

All WSDLs I have seen so far, use localhost to describe the services address. e.g.:
<wsdl:service name="SQLService">
<wsdl:port name="SQLServiceSoap" binding="tns:SQLServiceSoap">
<soap:address location="http://localhost:8080/rservice/services/SQLServiceSoap" />
</wsdl:port>
</wsdl:service>
But when the client of such service is run, it somehow knows where the real URL of that service, even if run on a remote machine!
How does CXF perform this "magic"?
IOW, how does the client JAR on a test machine which is not the machine on which the service runs, know where that server is and its address?
I grep-ed the source code and strings-ed the client's jar file and found no trace whatsoever to the server's URL.
So how does that work?
UPDATE: In my super natural detective efforts, I just found a file named config.xml in the directory where the client's JAR file is located. That config.xml contains the actual server's URL. So it appears that this is how this is done in the particular case of the project I inherited.
Now the question(s) is:
Is this the standard way of doing this?
Is there a standard (or recommended way) at all in CXF?
Or is it pretty much left to the developer to decide?
In many cases, the web service will have a production URL and a test/QA/UAT URL. The developer will develop against the test URL, and then once it's ready for production he will switch the URL to point to production.
It is up to the developer to decide how this is accomplished and there is no standard way of handling it.

AppFabric Cache Error:The AppFabric Caching Service service terminated unexpectedly

I am running cluster machine in Virtual Box in domain, by default service is running under Network service , service stopped all the time with the following error in the event log.
please find the error details from error log below. any help will be great.
Log Name: System
Source: Service Control Manager
Date: 21-07-2010 16:42:07
Event ID: 7034
Task Category: None
Level: Error
Keywords: Classic
User: N/A
Computer:
Description:
The AppFabric Caching Service service terminated unexpectedly. It has done this 5 time(s).
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Service Control Manager" Guid="{555908D1-A6D7-4695-8E1E-26931D2012F4}" EventSourceName="Service Control Manager" />
<EventID Qualifiers="49152">7034</EventID>
<Version>0</Version>
<Level>2</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2010-07-21T14:42:07.000Z" />
<EventRecordID>13342</EventRecordID>
<Correlation />
<Execution ProcessID="0" ThreadID="0" />
<Channel>System</Channel>
<Computer>
<Security />
</System>
<EventData>
<Data Name="param1">AppFabric Caching Service</Data>
<Data Name="param2">5</Data>
</EventData>
</Event>
thanks for the support.
kazim
There is no much information in the above error to guess what went wrong. Try to take a look at events right before this particular event (maybe there will be hint/warning about something). Another thing might be not to look only at a regular eventlog Windows Logs > Application but also at eventlog Applications and Services Logs > Microsoft > Application Server-System Services.
[Resolved]
I got the same issue. Couldn't find a definite answer anywhere. However after looking at all the configurations and connections, I figured out the root cause.
For information, in my case, I was using a SQL Configuration.
The issue was that my AppFabric database was not part of a cluster and availability group which it should have been actually. Once I added it to the availability group and after it got replicated in all the SQL nodes, I re-configured app fabric on the cache servers (using configure app fabric tool) and stopped and started my cache cluster again.
This time, everything worked as expected.
Hope this helps you too!
P.S.: I'm not sure if the "reconfiguring app fabric using the tool" is a mandatory step. I just did it from my side. Perhaps you can try stopping and starting the cache cluster without doing this. Do let me know in case it is not mandatory so that I can update this answer accordingly.
Agreed with David that there is not much one could make out of this log entry.
Another thing worth checking would be to make sure that your configuration is available to AppFabric services. May it be an xml or SQL based configuration provider, AppFabric services should be able to access it. This is the most common reason of crashing services at the load time.
You can very easily check this by running your appFabric configuration wizard.

Windows Service running as a logged-in user has access issues b/c of UAC

I have a Windows service that runs as a logged-in user (local admin). During start-up, I get a message along the lines: "Unable to generate a temporary class (result=1)".
So, I went to windows/temp folder and was prompted by UAC to elevate my privileges -- after I did this, the service would start up fine. So, how do I deal with this UAC prompt from the perspective of a Windows Service?
Thanks!
Regarding the original question - beyond the specific problem of event order that fixed your symptoms.When an user who is a member of the Local Administrators group logs on to a machine under UAC, two security tokens are granted - one with limited rights, and one with the higher permission set. By default, the lower permissions are used - unless the higher is actively specified. The primary means of specifying is through the UI - as you did. The other method is to use an application manifest: an XML file that specifies how the OS is to treat this application. The manifest file should be placed in the same folder as the executable, and named using the following format: "my_application_name.exe.manifest" The XML in the manifest will look something like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="MY_APPLICATION_NAME" type="win32"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
I'm sure you can find a bunch more specific info by googling "UAC Manifest" ...
Hope this is useful ...
I solved my problem even though I still don't know how to answer my question. Basically, my service was inheriting the temp directory from the bootstrapping process, so I changed it to use current's users' temp dir. You will need to do something along these lines:
myProcess.StartInfo.EnvironmentVariables.Add("TempPath", "C:\Temp")
Why not have the Windows Service run as LocalSystem?

Resources