Windows service Problem When Accessing Remote Machine File - c#

I created a Windows Service which Access File from Remote Machine. but It gives error in Log file that File Does Not Exist.When i deployed it then and then only it gives error otherwise when i am debugging from Visual Studio 2005 then it is working fine.
I tried to change Properties of Service from Log On tab. gives Logon as: then choose this Account and Gives Name of Remote Machine and Password Still it is not working. Please Help me out.
Code:
if (File.Exists(FileName))
{
}
else
{
Log.append("File Not Exist Path=:" + FileName, 75);
}
Error:
File Not Exist Path=: \Computer-01\Trend Till_04Feb\Trend Till_04Feb\TREND\128.DBF

I assume you are using ServiceProcessInstaller and ServiceInstaller.
The most important property is Account within the ServiceProcessInstaller class. It specifies the Windows account under which the service runs (security context). The following options are available:
LocalService: Service presents the computer's credentials to remote servers.
LocalSystem: Service presents anonymous credentials to remote servers.
NetworkService: Service has limited local privileges and presents the computer's credentials to remote servers.
User: A local or network account is specified. You may specify the necessary username and password via properties, or you may type them during installation. The Service uses the security context of the specified user account.
Following three options are provided to specify how your service is started.
Manual :- The user starts the service.
Automatic :- The service starts automatically when the system starts.
Disabled :- The service is not available for use.
Go to Properties of ServiceInstaller object and set ServiceName and StartType to Automatic.
Go to Properties of ServiceProcessInstaller and set Account property to LocalService. This causes the service to run on local service account.
HTH

Related

Unable to start an NServiceBus Windows Service

Problem Description
I have a Windows service which is hosting an NServiceBus endpoint in NServiceBus.Host.exe.
The binaries are deployed to c:\inetpub\bus\services\myService folder on the server.
A DSC script makes sure the Windows service is created/exists on the server, with the "path to executable" property of the service set to "c:\inetpub\bus\services\myService´NServiceBus.Host.exe" -service NServicebus.Production.
Note! The -service switch is added when installing the service by using the built-in NServiceBus.Host.exe /install parameter, which is why I added it to the Windows service executable path in the DSC script.
Now, when I try to start the service manually on the server, it yields the following error message
Windows could not start the <service name> service on the Local Computer.
Error 1053: The service did not respond to the start or control request in a timely fashion.
Debugging Steps
I have looked through the event log and the following two error messages sticks out:
NServiceBust.Host.exe error:
Application: NServiceBus.Host.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info:
Topshelf.Exceptions.ConfigurationException
at Topshelf.Internal.Actions.RunAsServiceAction.Do(Topshelf.Configuration.IRunConfiguration)
at Topshelf.Runner.Host(Topshelf.Configuration.IRunConfiguration, System.String[])
at NServiceBus.Host.Program.Main(System.String[])
Local Activation permission error:
The application-specific permission settings do not grant Local
Activation permission for the COM Server application with CLSID
{D63B10C5-BB46-4990-A94F-E40B9D520160}
and APPID
{9CA88EE3-ACB7-47C8-AFC4-AB702511C276}
to the user <my_service_account_user> SID (<service_account_SID>) from
address LocalHost (Using LRPC) running in the application container
Unavailable SID (Unavailable). This security permission can be modified
using the Component Services administrative tool.`
Note! The error above only occurs once, i.e. the first time I try to start the service. It does not appear again in the event log for any subsequent attempts of starting the service.
What I have done so far:
Tried the suggestions in a closely related post here on SO, none of which were working.
Tried to install the service by using using the NServiceBus.Host.exe /install parameter. In this case, the service name is created with its name on the following format: MyService.EndpointConfig_v1.0.0.0. Using this approach, the service starts successfully without any error message
Stopping the service and then try to start the service created by the DSC script (with a different name) => success
Removing the service created by NServiceBus and then trying to start the DSC-created service again => failure
Tried granting the service account used for logon when running the service various privileges (neither of which yielded any success), among others:
Membership in the Administrators group
Membership in the Performance Log Users group
Full DCOM permissions via "Launch and Activation Permissions" in dcomcnfg
Tried running c:\inetpub\bus\services\myService´NServiceBus.Host.exe NServicebus.Production from the CLI => success
Code
My Init() method for the service looks like this:
namespace MyService
{
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomLogging, IWantCustomInitialization
{
public void Init()
{
Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);
SetLoggingLibrary.Log4Net(() => XmlConfigurator.Configure(File.OpenRead(#"log4net.config")));
GlobalContext.Properties["Hostname"] = Dns.GetHostName();
GlobalContext.Properties["Service"] = typeof(EndpointConfig).Namespace;
var container = new WindsorContainer(new XmlInterpreter());
Configure.With()
.CastleWindsorBuilder(container)
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.IsolationLevel(System.Transactions.IsolationLevel.RepeatableRead);
var connectionString = ConfigurationManager.ConnectionStrings["<some_conn_string>"].ConnectionString;
container.Register(
Component.For<IDatabaseProvider>()
.ImplementedBy<DatabaseProvider>()
.DependsOn(Property.ForKey("connectionString").Eq(connectionString)));
}
}
}
Theory
When installing the service using /install I assume that NServiceBus.Host.exe does some black magic under the hood - e.g. grants some necessary permissions - to make the service able to start.
Note! On the server, the latest version of NServiceBus is installed (v6.x). However, in my solution/service project version 2.x is used (please, do not ask if I can upgrade - unfortunately, that is not an option).
Appreciate any help I can get, as I am running out of ideas.
EDIT 1
I was asked why I can't just use the /install parameter of NServiceBus and be happy with that. The answer to that is that I could (and, actually, I currently am).
The reason I have still posted this question is split:
I wish to understand why one of two seemingly equivalent approaches fails
I am not completely happy with using the /install parameter. The reason? It boils down to a "chicken or the egg" problem. I use Powershell DSC to provision servers in Azure and I believe that ensuring that Windows Services exists on the server is the responsibility of DSC. However, the first time a server is provisioned the services cannot exist unless I script their creation with DSC, and point the executable path to where the service binaries will be deployed whenever that happens. The other alternative is to skip service creation in DSC, and run the NServiceBus.Host.exe /install as a part of the service/application deployment script instead. Obviously, deployment cannot happen until after a server has been provisioned. Thus, it requires the Windows Service part of the DSC script being stripped down to e.g. merely ensuring the service exist - a verification which will fail until a first time deployment of the application has been performed.

Access to the path 'Global\{xxx}_YYY-YYY:13552' is denied. Hangfire?

As the title says I encounter a "Access to the path" error in my MVC web application. The sites application pool is DefaultAppPool with identity Network Service. I have set Full Control to the Network Service user with no luck, I then tried to give Everyone full control but it still does not work. I'm running another application from the same folder (C:\Users\YYY\Documents\Visual Studio 2015\Projects) and it works without a problem.
The file that fails contains the method that starts Hangfire. Could this have something to do with it?
I'm running Windows 10 Pro with IIS 10.0.
public void Start()
{
lock (_lockObject)
{
if (_started) return;
_started = true;
HostingEnvironment.RegisterObject(this);
GlobalConfiguration.Configuration
.UseSqlServerStorage("connection string");
// Specify other options here
_backgroundJobServer = new BackgroundJobServer();
}
}
http://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html
Current permissions for
C:\Users\YYY\Documents\Visual Studio 2015\Project
Server Error in '/' Application.
Access to the path
'Global{4deecd4f-19f6-426b-xxxx-xxxxxxxxxxxx}_YYY-YYY:13552' is
denied.
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details: System.UnauthorizedAccessException: Access to the
path
'Global{4deecd4f-19f6-426b-xxxx-xxxxxxxxxxxx}_YYY-YYY:13552' is
denied.
ASP.NET is not authorized to access the requested resource. Consider
granting access rights to the resource to the ASP.NET request
identity. ASP.NET has a base process identity (typically
{MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6 and IIS 7, and
the configured application pool identity on IIS 7.5) that is used if
the application is not impersonating. If the application is
impersonating via , the identity will be
the anonymous user (typically IUSR_MACHINENAME) or the authenticated
request user.
To grant ASP.NET access to a file, right-click the file in File
Explorer, choose "Properties" and select the Security tab. Click "Add"
to add the appropriate user or group. Highlight the ASP.NET account,
and check the boxes for the desired access.
Source Error:
Line 36: _backgroundJobServer = new BackgroundJobServer();
Found the problem, I had two websites with Hangfire running on the same application pool. When I created a new application pool for each website everything started working.
It seems as both instances of Hangfire when running on the same application pool tried to communicate through the same port and because of this the application that got started first was the only one to be working. The reason they were on the same application pool to start with was pure laziness, I only created a virtual directory from within Visual Studio at my local IIS to run the project.

Creating windows service fails

I try installing my Windows service using InstallUtil.exe and running my command prompt as Administrator.
InstalUtil.exe WindowsService.exe /ShowCallStack
The above command opens a 'Set Service Login' window, see the picture at this link.
When I enter 'Jasper Catthoor' in the username field (my account name) and my windows password in the password fields, I get the following error:
System.ComponentModel.Win32Exception: The trust relationship between the primary domain and the trusted domain failed.
When I enter as username 'jasper#catthoor.com' (email of my account, see previous picture), I get the following error:
System.ComponentModel.Win32Exception: The specified domain either does not exist or could not be contacted.
By entering a random username I receive the same error as when I enter 'Jasper Catthoor'.
By entering a random email (with an # sign), I receive the error:
System.ComponentModel.Win32Exception: No mapping between account names and security IDs was carried out.
Try taking your machine out of the domain and then re-add into the domain. Post that re-start your machine.
Also in your ProjectInstaller.cs file set the Account as LocalSystem.
It should work. Hope this helps.
Regards,
Abhinaw
Does the service really require to run under your user account? You could also try to use the Local Service account which most of the service run under.
You can also try to set the account information in the Account property of the ServiceProcessInstaller.

How do I properly host a WCF Data Service that connects to SQLServer in IIS? Why am I getting errors?

I'm playing around with WCF Data Services (ADO.NET Data Services). I have an entity framework model pointed at the AdventureWorks database.
When I debug my svc file from within Visual Studio, it works great. I can say /awservice.svc/Customers and get back the ATOM feed I expect.
If I publish the service (hosted in an ASP.NET web application) to IIS7, the same query string returns a 500 fault. The root svc page itself works as expected and successfully returns ATOM. The /Customers path fails.
Here is what my grants look like in the svc file:
public class AWService : DataService<AWEntities>
{
public static void InitializeService( DataServiceConfiguration config )
{
config.SetEntitySetAccessRule( "*", EntitySetRights.All );
config.SetServiceOperationAccessRule( "*", ServiceOperationRights.All );
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
Update: I enabled verbose errors and get the following in the XML message:
<innererror>
<message>The underlying provider failed on Open.</message>
<type>System.Data.EntityException</type>
<stacktrace>
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(
...
...
<internalexception>
<message>
Login failed for user 'IIS APPPOOL\DefaultAppPool'.
</message>
<type>System.Data.SqlClient.SqlException</type>
<stacktrace>
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, ...
It looks to me like this is a SQL authentication error, IIS is running its appPool under a user that does not have access to your SQL server, when you ruin in Visual Studio (locally) it will be a different user. Check the user that the IIS on the server is using and make sure it has rights to do what you want in SQL.
Try to change the connection string attribute Integrated security to False
Quick solution with IIS Express
Create a firewall exception to allow HTTP requests through the firewall on the port that IIS Express is using.
Get the IP address of the development computer, if necessary, by running ipconfig.
Find the IIS Express configuration file, applicationhost.config, in the folder %USERPROFILE%\Documents\IISExpress\config. The USERPROFILE environment variable typically has a value of C:\Users\.
Open applicationhost.config with Notepad or another text editor and make the following changes.
Find the site element for the web service, WebServiceForTesting.
If you don’t see the site element for the web service, you have to deploy the service at least one time to create the element.
Within the bindings section of the site element, copy the binding element and paste a copy directly below the existing binding element to create a second binding.
In the new binding element, replace localhost with the computer’s IP address.
Save the changes.
Run Visual Studio as administrator and open the Visual Studio solution.
In the phone app project, remove the service reference to the service if you have previously added it.
Add a new service reference to the reconfigured web service. In the Add Service Reference dialog box, in the Address box, replace localhost with the IP address of your development computer. Click Go.
The second binding for the service in the WCF project is discovered and displayed. Click OK.
A new service reference that uses the IP address of the development computer is added to the Windows Phone project.

"Access Denied" when trying to connect to remote IIS server - C#

I receive an "Access Deined" COMException when I try to connect to a remote IIS 6 server from my C# application that is running under IIS 5.1.
Any ideas? I am experiencing all the same issues with the original questions.
Update - 4/1/09
I found this solution (http://www.codeproject.com/KB/cs/Start_Stop_IIS_Website.aspx) that consists of a window application connecting to an IIS server to start and stop web sites. I am able to run it on my workstation and connect to the IIS server.
Ugh....why can I run this stand alone application but not my ASP.NET application?
Original
I receive an "Access Denied" COMException when I try to connect to IIS from a remote machine using the DirectoryEntry.Exist method to check to see if the IIS server is valid.
string path = string.Format("IIS://{0}/W3SVC", server);
if(DirectoryEntry.Exist(path))
{
//do something is valid....
}
I am a member of an active directory group that has been added to the Administrators groups to the IIS server I am trying to connect to.
Has anyone experience this issue and know how to resolve it?
UPDATE:
#Kev - It is an ASP.NET application. Also, I can connect without an username and password to the remote server through IIS6 Manager.
#Chris - I am trying to connect to the remote server to display the number of virtual directorys and determine the .NET framework version of each directory. See this SO question.
#dautzenb - My ASP.NET application is running under IIS 5.1 trying to connect to an IIS 6 server. I can see fault audits in the security log for my local ASPNET account on the remote server. When I try to debug the application, I am running under my domain account and still get the Access is denied.
UPDATE 2:
#Kev - I was able to establish to create a DirectoryEntry object using the following overload:
public DirectoryEntry
(
string path,
string username,
string password
)
But, all of the properties contain a " threw an exception of type 'System.Runtime.InteropServices.COMException'" while I debug the app.
Also, the AuthenticationType property is set to Secure.
UPDATE 3:
The following two failure audit entries were in the remote IIS server's security event log every time I tried to establish a connection:
First event:
Event Category: Account Logon
Event ID: 680
Log attempt by: MICROSOFT_AUTHENTICATION_PACKAGE_V1_0
Logon account: ASPNET
Source Workstation:
Error Code: 0xC0000234
Second event:
Event Category: Logon/Logoff
Event ID: 529
Logon Failure:
Reason: Unknown user name or bad password
User Name: ASPNET
Domain: (MyDomain)
Logon Type: 3
Logon Process: NtLmSsp
Authentication Package: NTLM
Workstation Name: (MyWorkstationId)
Caller User Name: -
Caller Domain: -
Caller Logon ID: -
Caller Process ID: -
Transited Services: -
Source Network Address: 10.12.13.35
Source Port: 1708
Impersonation is set to true and the username and password are blank. It is using the ASPNET account on the remote IIS server.
If it is an identity problem, you could try setting your IIS 5.1 application to use Integrated Windows Authentication, and then add the following to you web.config on your IIS5.1 web site under system.web to enable impersonation.
<identity impersonate="true"/>
<authentication mode="Windows" />
Since this is an ASP.NET application, it runs in an Application Pool of IIS. This Application Pool runs using a specific user("Local System", "Network Service" or another user).
Does this user have enough rights to connect to a remote server ?
See MSDN for more info.
This looks like it may be a double-hop issue. If you are impersonating the current user of a website using NTLM, that impersonation is only valid on that server (your IIS 5.1 server in this case). If you try to connect to another server using the web site, you are actually going to have issues as it cannot pass the token to another server that was used during impersonation. The same is true if you are debugging your site through your machine, going to another box. Your local machine is authenticating you, but it cannot impersonate you to another server.
All of the solutions I have used in the past require you to hard code the app pool to use an account that has permissions, set the annony. account to a domain account with permissions on the other machine, or use a windows service running on the IIS 5.1 machine, under a domain account, to connect to the other server.
If you are using Kerberos, this wouldn't apply, but AD uses NTLM by default.
Where exactly are you trying to read too? Is it in under the same path as your application?
When I had this problem, I found that simply authenticating my self on a Windows file share solved the problem. From experience, I think that WMI/ADSI/COM doesn't have great support for not-already-authenticated users. I believe this issue occurs when you're not associated with a Windows domain.
If it is indeed a NTLM doublehop issue you could use the SETSPN utility to create service principal named instances for your target IIS servers.
Then you could go into Active Directory, and then allow the computer object (basically the NETWORK SERVICE or LOCAL SERVICE principals) to delegate its credentials to a correctly registered SPN.
Then you could hop-hop-hop all over the place! But, be warned! People can hurt themselves on sharp pointy things when you enable double-hop!
Good KB articles to read:
http://support.microsoft.com/kb/929650
I believe that DirectoryEntry.Exists silently ignores any credentials supplied and uses the creds of the authenticated user. This seems to match the behaviour you've described. For AD work, we never use it for this reason.
I'm sort of stumped at the moment as to why you can't get this working. There is a temporary work around you could try. When instantiating the DirectoryEntry object you could use one of the following constructor overloads:
public DirectoryEntry(
string path,
string username,
string password
)
Documented at: MSDN: DirectoryEntry Constructor (String, String, String)
...or...
public DirectoryEntry(
string path,
string username,
string password,
AuthenticationTypes authenticationType
)
Documented at: MSDN: DirectoryEntry Constructor (String, String, String, AuthenticationTypes)
As it happens I'm building a test AD environment on my virtual server box for a new project to do similar stuff. When I get it up and running I'll have a play around to see if I can reproduce the problem you're encountering. In the meantime let us know what happens if you try these constructor overloads referenced above.
Update (In answer to Michaels comment):
For reasons that evade me just now, we couldn't use DirectoryEntry.Exists() in a particular scenario, there is this snippet of code that gets called now and again in one of our apps:
public static bool MetabasePathExists(string metabasePath)
{
try
{
using(DirectoryEntry site = new DirectoryEntry(metabasePath))
{
if(site.Name != String.Empty)
{
return true;
}
return false;
}
}
catch(COMException ex)
{
if(ex.Message.StartsWith("The system cannot find the path specified"))
{
return false;
}
LogError(ex, String.Format("metabasePath={0}", metabasePath));
throw;
}
catch(Exception ex)
{
LogError(ex, String.Format("metabasePath={0}", metabasePath));
throw;
}
}
You could replace the constructor with one of the ones from above. Admittedly it's a stab in the dark :).

Categories