How to ping URL from code behind - c#

I have one issue that i want to ping URL from code behind (EXE project) by which i can know environment of Azure application on which my EXE is running.
string dep = RoleEnvironment.DeploymentId.ToString();
WebRequest req = WebRequest.Create("http://" + dep + ".cloudapp.net");
HttpWebResponse rep= null;
try
{
rep = (HttpWebResponse)req.GetResponse();
}
catch (Exception)
{
//if environment is production then this URL will not work
//do some functionality
}
So by above code i would like to do some functionality when it will production environment
,above logic is works well but would like to get some perfect solution like ping command that if URL exist then return true otherwise false.
Please suggest me some good logic here
Thanks in advance.

No, I don't think that will work - if you have production code running then the check will always be successful, even if you call it from staging.
Check the answer to this:
Azure Detect Staging vs Production
which provides a more robust answer to your real question.

How about initiating a socket that tries to connect to the server over port 80 (HTTP)?
that'll be a good indication whether the site is up or not.

The only way to "ping" a resource is to get an error code. just make sure it's just a get operation so that no change occurs on the server.

You know when you deploy whether the app is deployed to live or test/staging so why don't you just set something on the web.config. Then you can just do
If (ConfigurationManager.AppSettings["Envirmonment"] == "Live")
{
//do live stuff
}
else
{
//do testing stuff.
}

Related

Can't access ServiceController (InvalidOperationException) when trying to read on remote/another computer

I have a local service running on my computer and trying to get other computers to be able to read the status of my service (whether it's running, stopped, etc.) However, I am unable to as I get an InvalidOperationException error, saying that I am unable to open Service Control Manager. Locally, I am able to, but on another remote computer I am unable to. The ServiceController (cs) object just returns an object with properties that all have the InvalidOperationException error.
I've tried closing down all the firewalls on the other computers, tried running Visual Studio on Administrator privileges, but nothing seems to be working. I've noticed that others suggested hard coding your admin credentials and using WindowsIdentity and Impersonation but that wouldn't work for my project (as it wouldn't be a viable solution at my workplace - wouldn't make sense with the business logic as don't want to give clients any in-house credentials).
Here's my snippet of code:
public bool CheckServiceStatus()
{
try
{
string machineName = pubSubConfig.MachineName;
string serviceName = pubSubConfig.ServiceName;
System.ServiceProcess.ServiceController cs = new System.ServiceProcess.ServiceController(serviceName, machineName);
if (cs != null && cs.ServiceName == serviceName && cs.Status == System.ServiceProcess.ServiceControllerStatus.Running)
{
return true;
}
}
catch(Exception ex)
{
Trace.TraceError("Unable to check service status: /r/n {0}", ex.Message);
}
return false;
}
The error is this:
System.InvalidOperationException: Cannot open Service Control Manager on computer '___'.
This operation might require other privileges. ---> System.ComponentModel.Win32Exception: Access is denied
Does anyone know any workarounds as to how I can get other computers running my C# program to be able to read the ServiceController object?
Thanks!
So as I said in the comments, I was not able to get around the SCM (Service Control Manager) due to admin privileges when accessing another remote computer (makes sense if you think about security). However, I did find another solution that was more or less a workaround. I'll post the solution here in case anyone finds it helpful.
So to check the status of the Windows Service (like if it's running or not), I added an additional WCF service that is hosted in the Windows Service. So now the service can expose a method that literally just returns true.
Essentially the thought-process around it was that if the WCF service is accessible then that means the Window Service is running, and thus will always return true. If the Windows service is down, the WCF service will also be down and thus making that method not available. You wouldn't get anything to return, so you would know that the service is down and not running.
Hope that helps someone! I know it's not really a direct solution to the problem I had originally asked, but it was a workaround, indirect solution.

Detect if app is running on localhost when there are no requests

I have a worker class in my web app and I'd like to know if the code is running on my laptop's dev server or on the production server. NOTE: there is no request processing when the code is running so HttpContext.Current.Request.IsLocal will not work.
How can I detect where the code is running?
A debug flag could be one option:
#if (!DEBUG)
// code that shouldn't run while debugging
#endif
I often personally find those a little unintuitive, though can't really quantify why in any objective sense. Though if it's possible that you'd ever run the app in Release (perhaps as a kind of smoke test) without wanting that code to run, that could be an issue.
Going with the general notion that the only difference between environments should be the configuration (that is, after all, what Web.config is for) then you can manually achieve the same result with a config flag. Something as simple as:
<add key="runBackgroundWorker" value="true" />
And in the code you would set some flag based on that (could be a direct reference to the configuration, could be a statically loaded config object, however you normally handle your configs) and use basically the same condition as above:
// for example...
var runBackgroundWorker = bool.Parse(ConfigurationManager.AppSettings["runBackgroundWorker"]);
// though perhaps put in more error checking, etc.
// later...
if (runBackgroundWorker)
{
// code that shouldn't run while debugging
}
This gives you the added flexibility of turning that feature on and off in any environment, regardless of Debug or Release builds. (QA, UAT, demo environment, etc.)
If your local server is not changing, nor is the production server you could run a compare against Environment.MachineName in the worker class.
Something like:
var devServer = "myMachineName";
var currentServer = Environment.MachineName;
if(devServer == currentServer)
{
/// local dev machine
}
Environment.MachineName

"System.Web.HttpException: Response is not available in this context" only in IIS

i have used the Http.Current.Response in my global.asax.cs Application Start. It is working fine without any issue when i execute in my PC. How ever when i try to put it in IIS with Windows Server 2008 R2, i find that it is giving the following error.
the code for it is
public static void SetCookie(string key, string value, int dayExpires)
{
HttpCookie encodedCookie = HttpSecureCookie.Encode(new HttpCookie(key, value));
encodedCookie.Expires = DateTime.Now.AddDays(dayExpires);
HttpContext.Current.Response.Cookies.Remove(key);
HttpContext.Current.Response.Cookies.Add(encodedCookie);
}
I wanted to trace out why it is getting executed in my system, but not in IIS.
Thanks
I would not do request/response oriented things in Application_Start. Try doing it in BeginRequest.
The request context is not available in application start when running in integrated mode in IIS7.
Please see my question and the accepted answer here for details:
Global ASAX - get the server name
Would also note that there seems to be a logical bug in your code - this will set the cookie only for the person that hits the site when the application starts - this will not run for every request, or every session.

How to Programatically Start IIS 6.0 SMTP Virtual Server?

I would like to know how to programatically restart IIS 6.0 SMTP server.
The SMTP server I have setup crashes every now and then. I don't notice it for a couple days, but that is by far way too late to do anything about it.
I want to set up a scheduled task every 30 minutes or so to test if the SMTP server is running, and if its not, the Scheduled task with automatically start it back up.
I have found a way to check if the SMTP server is up and running, but I have not figured out how to restart the process if it crashes.
That way is posted here: Testing SMTP server is running via C#
Any help would be brilliant!
Thank you.
Im developing the Console application in C# to check if its running or not, so any code examples would be great too.
A ServiceController can help you, as it has start and stop methods. Look at the sample in the msdn page.
Another sample is taken from the ServiceControllerStatus Enumeration is nearly what you need (just replace the service name).
ServiceController sc = new ServiceController("Telnet");
Console.WriteLine("The Telnet service status is currently set to {0}",
sc.Status.ToString());
if ((sc.Status.Equals(ServiceControllerStatus.Stopped)) ||
(sc.Status.Equals(ServiceControllerStatus.StopPending)))
{
// Start the service if the current status is stopped.
Console.WriteLine("Starting the Telnet service...");
sc.Start();
}
else
{
// Stop the service if its status is not set to "Stopped".
Console.WriteLine("Stopping the Telnet service...");
sc.Stop();
}
// Refresh and display the current service status.
sc.Refresh();
Console.WriteLine("The Telnet service status is now set to {0}.",
sc.Status.ToString());
Maybe I'm missing something, or something changed, but when you install SMTP service on Windows 2012R2, there is no dedicated service for it. So, for recent version of Windows the advice above won't work.
Luckily there's a way to do it much easier. Powershell:
([ADSI]'IIS://LOCALHOST/SMTPSVC/1').Start() #to start
([ADSI]'IIS://LOCALHOST/SMTPSVC/1').Stop() #to ... you guess
The weirdest thing is that you control smtp service through AD, but it works.
And of course this should be run elevated.
If you have several virtual SMTP servers, you may need to identify your server by index or by some property (e.g. .ConnectionTimeout) first.
in c# you can write:
enum StatusVirtualServerSMTP
{
Started = 2,
Stopped = 4
}
DirectoryEntry dir = new DirectoryEntry("IIS://localhost/SMTPSVC/1");
if (Convert.ToInt32(dir.Properties["SERVERSTATE"].Value) == (int)StatusVirtualServerSMTP.Stopped)
{
dir.Properties["SERVERSTATE"].Value = (int)StatusVirtualServerSMTP.Started;
dir.CommitChanges();
}

How to determine whether a web application is currently running

I have a ASP.NET web application running under IIS 6, and another process that is responsible to monitor and report status.
I'd like to sample the web application by the monitoring process in order to check its status by accessing a dedicated handler on the web application, BUT i don't want to "wake up" the web application in case it is not running.
Is there an option to determine whether a specific web application is currently running? if there is such an option, i would be able to first check if the application is running, and only then to access the handler to check its status.
Thanks.
I had to do something similar earlier this year for IIS7, not sure if this would work for IIS6 but here's what I did.
var iis = new DirectoryEntry("IIS://" + Environment.MachineName + "/w3svc");
foreach (DirectoryEntry site in iis.Children)
{
if (site.SchemaClassName.ToLower() == "iiswebserver")
{
Console.WriteLine("Name: " + site.Name);
Console.WriteLine("State: " + site.Properties["ServerState"].Value);
}
}
ServerState returns 2 for started and 4 for stopped.
You can use the HTTP HEAD request to check if the site is up or not. Here is an example to do the same.
http://www.eggheadcafe.com/tutorials/aspnet/2c13cafc-be1c-4dd8-9129-f82f59991517/the-lowly-http-head-reque.aspx
I would include in the ASP.NET website an asmx file, a web service with a simple Ping function, but it will still wake up the application pool of the website.
You could analyse the IIS log file, to see if there are recent entries.
If your application is not used much, it is possible the latest "entry" still needs to be flushed.
Or you could update a file/database to indicate "still active".
If you really do not want a delay, in the Application_Start and Application_End, create and destroy a system mutex.
This is my solution:
try
{
WebRequest request = WebRequest.Create("http://localhost/");
WebResponse response = request.GetResponse();
}
catch (WebException ex)
{
// ex.Status will be WebExceptionStatus.ConnectFailure
// if the site is not currently running
}
We used to use Nagios to monitor our site and it would target the favicon of our website. If it could pull back the icon, we knew the site was up.

Categories