I've created a bare-bones NServiceBus endpoint (which doesn't do anything for now), and when I install it (using NServiceBus.Host.exe /install /displayName:"MyEndpoint"), it gets installed as a service
that runs under Local Service, and it works perfectly.
Now, when I change the Run as account for this Windows Service to my own local service account (lets call it "svcTestAccount" for now, it has Logon as a service permission), the service starts and then unexpectedly stops halfway during its initialization.
I can't tell why, since no exceptions get logged to log4net, the process just terminates.
I've seen this behaviour before in a previous project when the endpoint couldn't access the queue it needed, but this time I have configured the 5 queues that my endpoint to give "Everyone" "Full Control", so it shouldn't be that, right?
What's strange is that, when I run it (using the NServiceBus.Host.exe on production profile), it happily runs in all the following situations:
From within Visual Studio 2012, running as local admin.
As a windows service, running under Local Service
As a windows service, running under Network Service
As a windows service, running under svcTestAccount, if svcTestAccount is a member of the local Administrators group.
From a command prompt running under svcTestAccount (i.e. "runas /user:svcTestAccount cmd" to open the command prompt, then NServiceBus.Host.exe to run my endpoint)
The only thing that doesn't work is getting it to run as a Windows Service under svcTestAccount (and not being a member of the local Administrators group).
Can anybody tell me what's going on?
For completeness sake, my endpoint only consists of:
public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
public void Init()
{
Configure.With()
.DefaultBuilder()
.Log4Net();
}
}
And my web.config:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<configuration>
<configSections>
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
</configSections>
<UnicastBusConfig>
<MessageEndpointMappings>
</MessageEndpointMappings>
</UnicastBusConfig>
</configuration>
I'm using NServiceBus 4.3.0 on Windows Server 2012.
To run NServiceBus host as a different account (not Local System) you need to execute the installer with /username and /password, eg:
NServiceBus.Host.exe /install /displayName:"MyEndpoint" /username:"mydomain\username" /password:"mysecretpassword"
See http://docs.particular.net/NServiceBus/the-nservicebus-host#installation for more info.
Related
I’m getting the following behavior when I try to launch an Azure Cloud Service locally
1) Popup that the debugging environment is getting ready is shown (step1.jpg)
2) Message “Your about to be signed out, crypto settings changed” is shown (step2.jpg)
3) Force restart of the notebook is performed (step3.jpg)
This is happening constantly in both debug and start without debugging options.
I tried changing the properties of the azure cloud service but it didn’t help. I also tried to use the internet what does this message mean and could not find any relevant data. appreciate ANY help. Thanks!
Check you ServiceDefinition.csdef for startup tasks. I think you maybe running the DisableSslv3.cmd script on your local machine causing it to force a restart. Just comment out the line while debugging locally.
In addition to the answer of #user2282308, I would say that in a more global approach, it worth to check the startup tasks in the serviceDefinition.csdef and verify that all tasks are executed as "expected".
#user22822308 spoke about DisableSslv3.cmd, but on my side, the issue was that the script runTLSsettings.cmd should be executed only when running on Azure service (this script ends with a reboot of the machine and the famous "crypto settings changed")
This is the serviceDefinition.csdef integration that is proposed by Microsoft for the runTLSSettings script:
<Startup>
<Task executionContext="elevated" taskType="simple" commandLine="RunTLSSettings.cmd">
</Task>
</Startup>
This is ok when debugging your cloud service in Visual Studio 2019, but as soon as you try to debug with Visual Studio 2022 you will receive the "Crypto settings changed".
My feeling is that the startup task is not done in VS 2019 meanwhile it is done in VS 2022.
Thus, what is missing is the definition of the environment variable that indicate to runTLSSettings script if we are running on emulator or not.
The environment variable definition is well explained in this other microsoft documentation:
https://learn.microsoft.com/en-us/azure/cloud-services/cloud-services-startup-tasks#environment-variables
At the end, this is the correct csdef:
<Startup>
<Task commandLine="runTLSSettings.cmd" executionContext="limited" taskType="simple">
<Environment>
<Variable name="ComputeEmulatorRunning">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/#emulated" />
</Variable>
</Environment>
</Task>
This happens every single time I run Visual Studio without elevated privilege's. When I start debugging the cloud service and the azure emulator starts, I get this message and the computer reboots.
I've used a simple windows service to make a method work in specific time and it works fine. Following that I've already tried:
protected override void OnStart(string[] args)
{
this.WriteToFile("Simple Service started {0}");
this.ScheduleService();
}
protected override void OnStop()
{
this.WriteToFile("Simple Service stopped {0}");
this.Schedular.Dispose();
}
private Timer Schedular;
public void ScheduleService()
{
try
{
Schedular = new Timer(new TimerCallback(SchedularCallback));
string mode = ConfigurationManager.AppSettings["Mode"].ToUpper();
this.WriteToFile("Simple Service Mode: " + mode + " {0}");
//Rest of the code here
}
catch(Exception ex)
{
WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);
//Stop the Windows Service.
using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SimpleService"))
{
serviceController.Stop();
}
}
}
This is done in a simple windows application. So what I am trying to do is to call a web service (A specific method to operate in a specific time) in a windows service. The application I am building is web-based and am little bit confused how would I integrate the windows service into it? Do I need any alternatives or any suggestions would be appreciated.
Note: What I would like to know is it required to create another project for windows service in the web application or any other way to implement?
To call a web service from a Windows Service application, you would first generate a DLL from that web service, then instantiate its namespace. Assuming you have the code for that web service and/or know its namespace, you can perform these commands to do this:
Perform these lines on a command line:
cd C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools
wsdl /l:CS /protocol:SOAP %svc%?WSDL
where %svc% is the URL for your web service, i.e. http://localhost:777/MyWebService.asmx
If the code is in VB instead of C#, change /l:CS to /l:VB.
This will output a proxy class file that can be converted to a DLL.
Move the MyWebService.cs file from C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools to the C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ directory.
Run these two commands on the command line:
cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
csc /t:library %name%.cs /reference:System.Web.Services.dll /optimize
where %name% is the name of the class (without the .cs, since the command will append this). In our case, we'd use MyWebService. (Change .cs to .vb for a VB class.)
Navigate to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 via Windows Explorer. You should see a DLL created in that folder with the name of the class (MyWebService.dll). Copy this file to the bin folder of your Service project. You will need to set the bin folder to be included in your project, and right-click the folder to Add > Existing Item. Select the DLL. Once imported, select the DLL and change its properties to:
Build Action: Content
Copy to Output Directory: Copy if newer (or Copy always, as you prefer)
Right-click References > Add References. Navigate to the DLL in the bin folder for your web service.
Right-click References > Add Service References. Assuming your web service is running, take its full URL (i.e. http://localhost:777/MyWebService.asmx) and put that on the Address line. In the Namespace textbox, give it something more meaningful than ServiceReference1, but it should not be the same as MyWebService (the name/namespace of the ASMX file). Perhaps MWS.
Instantiate your web service in your Windows Service:
MWS.MyWebServiceSoapClient webService = new MWS.MyWebServiceSoapClient();
webService.Open();
string someDataYouWant = webService.SomeMethodToGetData();
webService.Close();
Or you can probably do:
MyWebService webService = new MyWebService();
string someDataYouWant = webService.SomeMethodToGetData();
webService.Dispose();
In answer to your query on my comment;
Another approach is to use an IIS Auto-Start website contaning your Windows Service logic. The IIS Auto-start is supierior to using a Windows Service as it contains all the IIS application hosting logic including auto-restart, and aggressive resource management. A poorly written Windows Service can take down a Server but it takes a lot for an ASP.net IIS hosted application to take down its host (its almost impossible).
Your Auto-Start website need not be visibile to the outside world - it just needs to have an internal timer that keeps it alive when it starts up. Note that the web application might be started and stopped by IIS for various reasons; but the outcome is that it will be running whenever your other web service application is running. The internal timer can wait for a specific time to execute the logic you need to call your second web service.
The key thing to remember is that a Windows Service is designed to be an application that is hosted by Windows and is continually running. An IIS application is designed to be run by Windows but runs only when called. The IIS Auto-Start website concept allows you to provide a "continually running" website but hosted by the robust IIS application hosting components, instead of it running directly as an OS process.
Generally people dont do this because either they dont know about it, or want to avoid needing the IIS infrastructure to run "Windows Service" type applications, but in your case you have already paid the cost of using IIS to host your second web service, so you may as well make full use of IIS (and avoid the second technology stack and deployment headaches of Windows Service deployment).
So I suggest using an IIS Auto Start in preference to a Windows Service in your situation because;
You only need to use on tech stack in your solution, which was what your OP was asking about
IIS carries out active resource management on all its applications, terminating, restarting as neccessary if they become non-functional. Windows Services do not have that capability.
Your IIS based service code is XCOPY deployable with no administrator access credentials on the target machine.
Your IIS service is hot upgradeable without needing OS level administrator rights - IIS handles the stopping and restarting on upgrade without you needing to do anything.
We have a client Windows application calling C# Web Services. Everything is in .Net Framework 4.0.
So basically, we deploy Web Services in IIS, and also the client application will be located on the server. The application will be executed on client PCs via a network share.
Everything works fine, every functionality works ok (Web Services, Windows functionalities, etc).
But we have an error reporting functionality that reads customs definition in the .Config file. The section looks like this:
<configuration>
<configSections>
<section name="exceptionManagement" type="Some.Namespace.ExceptionManagerSectionHandler,Some.Assembly"/>
<section name="ProductInformation" type="Some.Namespace.ProductInfoManagerHandler,Some.Assembly"></section>
</configSections>
The section will be read only when the application encounters an exception.
When executing the application locally on the server, the error reporting will work fine, but when executing the same assemblies from a network share (even on the same machine with a shortcut using the FQN of the machine and share), I will get this exception (line 5 is my "ProductInformation" custom definition):
Exception has been thrown by the target of an invocation. An error
occurred creating the configuration section handler for
ProductInformation: Request failed.
(\\Server\PATH\Some.exe.config line
5) Request failed.
But as I told before, every other functionalitiy will work just fine. And, of course, I got this at the end of my config :
loadFromRemoteSources enabled="true"
I really don't get it, since basically the code is fine when ran locally, but fails when ran from network share, but all other functionalities will work fine over network.
Any ideas?
I recently upgraded my publisher/subscriber solution to NServiceBus version 3.2.2 using Nuget. My NServiceBus publisher and subscriber are both self-hosted.
Publisher code:
I start the NServiceBus publisher using NServiceBus.Host.exe (debug start action - start external program in project property).
app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
<section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
</configSections>
<MsmqTransportConfig ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5" />
<UnicastBusConfig ForwardReceivedMessagesTo="">
<MessageEndpointMappings></MessageEndpointMappings>
</UnicastBusConfig>
<MessageForwardingInCaseOfFaultConfig ErrorQueue="error" />
</configuration>
EndpointConfig.cs:
namespace TrackEventPublisher.EventPublisher
{
[EndpointName("EventPublisher")]
public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher
{
}
}
I ran into the following error when running the publisher:
Exception when starting endpoint, error has been logged. Reason: An exception was thrown while invoking the constructor 'Void .ctor(Raven.Client.IDocumentStore)' on type 'RavenTimeoutPersistence'.
StackTrace:
at NServiceBus.Hosting.GenericHost.Start() in d:\BuildAgent-03\work\nsb.master22\src\hosting\NServiceBus.Hosting\GenericHost.cs:line 45
at NServiceBus.Hosting.Windows.WindowsHost.Start() in d:\BuildAgent-03\work\nsb.master22\src\hosting\NServiceBus.Hosting.Windows\WindowsHost.cs:line 56
at NServiceBus.Hosting.Windows.Program.<>c_DisplayClass8.b_4(WindowsHost service) in d:\BuildAgent-03\work\nsb.master22\src\hosting\NServiceBus.Hosting.Windows\Program.cs:line 95
at Topshelf.Internal.ControllerDelegates1.StartActionObject(Object obj) in d:\dev\open-source\topshelf\src\Topshelf\Internal\ControllerDelegates.cs:line 18
at Topshelf.Internal.IsolatedServiceControllerWrapper1.<>c_DisplayClass2.b_1(TService service) in d:\dev\open-source\topshelf\src\Topshelf\Internal\IsolatedServiceControllerWrapper.cs:line 65
at Topshelf.Internal.ServiceController1.<.cctor>b__1(ServiceController1 sc) in d:\dev\open-source\topshelf\src\Topshelf\Internal\ServiceController.cs:line 35
at Magnum.StateMachine.LambdaAction1.Execute(T instance, Event event, Object parameter) in :line 0
at Magnum.StateMachine.EventActionList1.Execute(T stateMachine, Event event, Object parameter) in :line 0
What might cause this error?
Can anyone tell me what is wrong with my endpoint configuration?
My solution worked great with an earlier version of NServiceBus (pre version 3.0).
Update:
Here is the inner exception message: "Unable to connect to the remote server"
Is the Raven server started automatically by NServiceBus? It would appear that it is not running on my machine...
Update
Well, for some reason the RavenDB service was not running on my machine - although it is set to start automatically. My solution is working correctly now. I guess I had to learn about the RavenDB the hard way :).
Has anyone out there had problems running the RavenDB service?
Update
Now that I have my service up and running, I try and run it on a different machine. The msmq folders are not created, and I get an error that the RavenDB is not available. In fact, RavenDB service is not installed after I ran my solution on a different windows OS machine. I tried running the "RunMeFirst.bat" that posted with version 3.2.2. However, the bat file attempts to install an extension with visual studio. Another error is posted if visual studio is installed, but Nuget extension is not installed.
Is there a better way to enable NServiceBus.Host.exe to install the RavenDB server and msmq folders without an instance of visual studio installed on the Windows OS machine?
Update
Wow, most updates ever! I added the following class to my publisher project which successfully created the msmq folders:
class MsmqTransportConfigOverride : IWantCustomInitialization, INeedToInstallInfrastructure<Windows>
{
public void Init()
{
Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install();
}
public void Install(System.Security.Principal.WindowsIdentity identity)
{
}
}
This new class which implements the IWantCustomIntialization interface seems to work great. However, I am still struggling to update my publisher to install the RavenDB on the windows host machine. I know there is a commandline prompt out there that can facilitate this, but is there another way? I tried to implement INeedToInstallInfrastructure interface, but I cannot find any examples out there. Does anyone have any ideas?
We only run the installers if you:
1. Install the endpoint as a windows service (if running in the production profile => the default)
2. Run in debug mode
3. Run in the integration/lite profiles
So that would explain why the queues are not created (assuming none of the above is true for you?)
I have some code that wraps the PayflowPro .NET API. It essentially posts to a HTTPS address (a payment gateway) from C#. I can run this code locally and it works nicely. I can run it in my MSUnit tests and it works, and I can run it from a console application on my test environment and it also works.
I have a workflow hosted in IIS 6.1, which instantiates a class which in turn calls this code. When this workflow is started the code fails everytime; I get an error like System.Exception: Failed to connect to host Input Server Uri = https://pilot-payflowpro.paypal.com/ from the API object.
This exception is coming from the API, but I am completely lost as to how I can succesfully post from a console application but not from an IIS process.
The class is exactly the same, word for word.
I log in as administrator, so the console app is running as administrator. Therefore I have tried using the administrator account for the application pool for the website (for this testing only, obviously)
The console app can post so therefore the firewall / proxy aren't interfering... right?
Is there anything I need to adjust in IIS to allow an application to communicate outside? Are there any obvious security settings that I'm overlooking? Any suggestions for test cases to run to find out what might be going on?
edit: Turns out that this problem is somehow related to the VM environment in which the server is running. This problem doesn't occur on my development box, the test server or the production server - it's only occurring on the integration server. The cause is still unknown but I am no longer working on it.
This might be caused by an ASP.NET trust configuration issue. To check the trust level open the following file in an editor:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config (if ASP.NET 2.0)
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\CONFIG\web.config (if ASP.NET 4.0)
You may also need to edit the C:\WINDOWS\Microsoft.NET\Framework64 versions of these if you're running on 64 bit Windows.
Scroll down to the <securityPolicy> configuration section which looks like:
<location allowOverride="false">
<system.web>
<securityPolicy>
<trustLevel name="Full" policyFile="internal"/>
<trustLevel name="High" policyFile="web_hightrust.config"/>
<trustLevel name="Medium" policyFile="web_mediumtrust.config"/>
<trustLevel name="Low" policyFile="web_lowtrust.config"/>
<trustLevel name="Minimal" policyFile="web_minimaltrust.config"/>
</securityPolicy>
<trust level="Medium" originUrl=""/>
</system.web>
</location>
If you see anything other than <trust level="Full" originUrl=""/> it means the server is running under Partial Trust.
Open the .config file specified by the relevant policyFile attribute, for example web_mediumtrust.config if level="Medium".
It's highly unlikely that the server will be running under anything less than Low Trust.
Locate the <NamedPermissionSets> section, under this there is a <PermissionSet> that looks like:
<PermissionSet
class="NamedPermissionSet"
version="1"
Name="ASP.Net">
This contains a number of <IPermission> nodes. Look for one that called WebPermission, it looks like this:
<IPermission
class="WebPermission"
version="1">
If it's missing or looks like:
<IPermission
class="WebPermission"
version="1">
<ConnectAccess>
<URI uri="$OriginHost$"/>
</ConnectAccess>
</IPermission>
You need to add or modify so it looks like:
<IPermission
class="WebPermission"
version="1"
Unrestricted="true"/>
This setting controls outbound and inbound access from your application to or from a URI.
It may also be necessary to ensure that the SocketPermission configuration is similarly configured:
<IPermission
class="SocketPermission"
version="1"
Unrestricted="true"/>
Turns out that this problem is somehow related to the VM environment in which the server is running. This problem doesn't occur on my development box, the test server or the production server - it's only occurring on the integration server. The cause is still unknown but I am no longer working on it.