I am trying to see the status of multiple services in my string array.
The service may not always exist on the machines I will be using it on hence the try
Code:
public string[] service = { "MSSQL$AMTECHFASTTEST", "SQLBrowser" };
public void stopService()
{
int i = 0;
ServiceController[] scServices;
scServices = ServiceController.GetServices(service[i]);
try
{
foreach (ServiceController services in scServices)
{
MessageBox.Show(service[i]+" " + services.Status.ToString(), "Service Status");
i++;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error");
}
}
I think it is the ServiceController.GetServices(service[i]) line that is causing the errors, but I cannot work it out.
Thanks,
The ServiceController.GetServices(string machineName) method retrieves the services running at the host machineName.
If you want to get the services that are running on the same machine as your program, use ServiceController.GetServices() without a parameter.
So I think what you want to do is something like this:
public string[] wantedServices = { "MSSQL$AMTECHFASTTEST", "SQLBrowser" };
public void stopService()
{
ServiceController[] services = ServiceController.GetServices()
.Where(svc => wantedServices.Contains(svc.ServiceName))
.ToArray();
try
{
foreach (ServiceController svc in services)
{
MessageBox.Show($"{svc.ServiceName} {svc.Status}", "Service Status");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error");
}
}
This gets all the services on the current machine that have names contained in your wantedServices array (I changed some variable names for clarity).
Related
I am using SignalR to send a message to my client. The way I am doing this is in a static function inside my hub file:
public static void CallTestFunction(int UserID, short TestParam)
{
try
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<TestHub>();
hubContext.Clients.User(UserID.ToString()).TestFunction(TestParam);
}
catch (Exception ex)
{
Logger.LogError(ex);
}
}
This works prefectly fine. However, this does not throw error if I pass a random userID to this function like "123456789". What I want to do is something like:
public static void CallTestFunction(int UserID, short TestParam)
{
try
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<TestHub>();
if(// Some sort of check like hubContext.Clients.User.Exists(UserID.ToString())
hubContext.Clients.User(UserID.ToString()).TestFunction(TestParam);
else
//Throw exception saying that user does not exist.
}
catch (Exception ex)
{
Logger.LogError(ex);
}
}
What do I do in the second code's if statement to make that code work?
I am using lightDB as a local database in my iOS and android app implemented in Xamarin Forms. I am trying to store my local liteDB in the cloud using Azure. We have implemented a REST api which can receive a byte[] but I am having problem getting the liteDB documents to a byte[]. If I try to read the file using File.ReadAllBytes(LiteDbPath) where we have stored the liteDB i get a System.IO.IOException: Sharing violation on path. I assume this is not the way to do this, but I am unable to figure out how to do this. Anyone have any suggestions on how to do this?
It is possible I am using this the wrong way, I am quite unexperienced in this area.
Update: More details to make it clearer what I have done and what I want to do.
This is our DataStore class (where we use LiteDB):
[assembly: Dependency(typeof(DataStore<Zystem>))]
namespace AirGlow_App.Services {
class DataStore<T> {
public void Close()
{
var db = new LiteRepository(LiteDbPath);
db.Dispose();
}
public LiteQueryable<T> Get()
{
using (var db = new LiteRepository(LiteDbPath))
{
try
{
return db.Query<T>();
}
catch (Exception ex)
{
Debug.WriteLine($"Exception when doing Get. Exception = {ex.Message}.", TypeDescriptor.GetClassName(this));
//TODO : General Error Handling
return null;
}
}
}
public T Get(BsonValue id)
{
using (var db = new LiteRepository(LiteDbPath))
{
try
{
return db.Query<T>().SingleById(id);
}
catch (Exception ex)
{
Debug.WriteLine($"Exception when doing Get. Exception = {ex.Message}.", TypeDescriptor.GetClassName(this));
//TODO : General Error Handling
return default(T);
}
}
}
public void Add(T obj)
{
using (var db = new LiteRepository(LiteDbPath))
{
try
{
db.Insert<T>(obj);
}
catch (Exception ex)
{
Debug.WriteLine($"Exception when doing Add. Exception = {ex.Message}.", TypeDescriptor.GetClassName(this));
//TODO : General Error Handling
}
}
}
public void Delete(Guid Id)
{
using (var db = new LiteRepository(LiteDbPath))
{
try
{
var o = new BsonValue(Id);
db.Delete<T>(o);
}
catch (Exception ex)
{
Debug.WriteLine($"Exception when doing Delete. Exception = {ex.Message}.", TypeDescriptor.GetClassName(this));
//TODO : General Error Handling
}
}
}
public void Save(T obj)
{
using (var db = new LiteRepository(LiteDbPath))
{
try
{
db.Update<T>(obj);
}
catch (Exception ex)
{
Debug.WriteLine($"Exception when doing Save. Exception = {ex.Message}.", TypeDescriptor.GetClassName(this));
//TODO : General Error Handling
}
}
}
}
}
Then we are using it like this:
public class ZystemsViewModel : ObservableObject
{
private DataStore<Zystem> DB = DependencyService.Get<DataStore<Zystem>>();
public ZystemsViewModel()
{
MessagingCenter.Subscribe<ZystemAddViewModel, Zystem>(this, "Add", (obj, item) =>
{
var newItem = item as Zystem;
Debug.WriteLine($"Will add {newItem.Name} to local database.", TypeDescriptor.GetClassName(this));
DB.Add(newItem);
});
}
}
It was a colleague who is not working here anymore who did these parts. I think the reasoning for using it as a DependencyService was to be able to access it in all classes, pretty much as a singleton. This should probably be changed to a singleton class instead?
Using the database works fine the app. But I want to upload the entire database (file) to Azure and I am unable to get it to a byte[]. When I do
byte[] liteDbFile = File.ReadAllBytes(LiteDbPath);
I get a System.IO.IOException: Sharing violation on path. As some are suggesting it is probably due to the file is being locked, any suggestions on how to solve this?
LiteDB is plain file database and has no running service to access data. If you create a REST API, you should locate you datafile in same machine (local disk) that are running your IIS.
Azure blob storage is another service and deliver file as request.
Think LiteDB as a simple FileStream class (that works with local file) with "super-powers" :)
I'm currently writing test automation for a web based application for my company. I am utilising C#, Visual Studio test suite, and Selenium to perform testing.
Today I asked the question to my colleague of 'Is there any time where there is too many Try Catch blocks in code?'. His reply was to not work as I am at the minute (see example 1), but to just get the lower level try-catch to throw to the upper level try-catch so that the exception can be written there and the test failed (see example 2).
Example 1:
TestCase.cs
[TestMethod]
public void TestLogin()
{
Assert.IsTrue(FW_Shared.Perform_Login(FW_Shared.OrgCode, FW_Shared.Username, FW_Shared.Password));
Console.WriteLine(#"Login Successful");
}
FW_Shared.cs
public static class FW_Shared
{
public static string OrgCode = "Test123";
public static string Username = "Tester";
public static string Password = "Password";
public static void Perform_Login(string OrgCode, string Username, string Password)
{
try
{
Driver.Url = "http://test.app.com/";
Driver.FindElement(By.Id("org_code")).SendKeys(OrgCode);
Driver.FindElement(By.Id("username")).SendKeys(Username);
Driver.FindElement(By.Id("password")).SendKeys(Password);
Driver.FindElemenet(By.Id("btnsubmit)).Click();
}
catch (Exception ex)
{
Console.WriteLine(#"Error occurred logging on: " + ex.ToString());
return false;
}
return true;
}
}
Example 2
TestCase.cs
[TestMethod]
public void TestLogin()
{
try
{
Assert.IsTrue(FW_Shared.Perform_Login(FW_Shared.OrgCode, FW_Shared.Username, FW_Shared.Password));
Console.WriteLine(#"Login Successful");
}
catch (Exception ex)
{
Console.WriteLine(#"Exception caught, test failed: " + ex.ToString());
Assert.Fail();
}
}
FW_Shared.cs
public static class FW_Shared
{
public static string OrgCode = "Test123";
public static string Username = "Tester";
public static string Password = "Password";
public static void Perform_Login(string OrgCode, string Username, string Password)
{
try
{
Driver.Url = "http://test.app.com/";
Driver.FindElement(By.Id("org_code")).SendKeys(OrgCode);
Driver.FindElement(By.Id("username")).SendKeys(Username);
Driver.FindElement(By.Id("password")).SendKeys(Password);
Driver.FindElemenet(By.Id("btnsubmit)).Click();
}
catch (Exception)
{
throw;
}
return true;
}
}
Now I know that throwing the Exception to be caught is generally useless in typical coding as you want to handle specific exceptions that are returned, but I want to be able to catch any general web page or element issues so the test can fail on a general issue with the web application. For instance:
If the web page returns 503 or 404 issues
If an element is not present on the current web page
If an elements name has changed.
There is points in testing other, more complicated parts of the application that I handle unaccessible parts/elements with true/false bool returns and assert that, but since I am referencing multiple function across different classes would sticking with what I have be best, moving to top-level catching of all lower exceptions, or should I be doing something else?
I normally like to create a test helper method in its own class called "TestRunner.cs" which has a method in I use for all the tests which might throw an exception and I want to test the results of e.g.
public static Exception RunCodeThatMayThrowException(Action action)
{
try
{
action.Invoke();
return null;
}
catch (Exception ex)
{
return ex;
}
}
I can then just use the method like:
// Act
var actualException = TestRunner.RunCodeThatMayThrowExeption(() => {//some code});
// Assert
//Do some asserts
Your original Perform_Login method states no return parameter (‘void’) and always returns ‘true’ (unless there’s a crash) – these both hint that the method needs some re-factoring.
I would re-factor as follows, which isolates the calling code from the exception, makes the caller agnostic to any errors in the called method, and avoids a series of try-catches passing up the call stack (if your test had a try-catch in it then the production code that calls the method may well require the same):
Public Static Class FW_Shared
{
public static string OrgCode = "Test123";
public static string Username = "Tester";
public static string Password = "Password";
public static bool Perform_Login(string OrgCode, string Username, string Password)
{
Try
{
Driver.Url = "http://test.app.com/";
Driver.FindElement(By.Id("org_code")).SendKeys(OrgCode);
Driver.FindElement(By.Id("username")).SendKeys(Username);
Driver.FindElement(By.Id("password")).SendKeys(Password);
Driver.FindElemenet(By.Id("btnsubmit)).Click();
}
Catch (Exception ex)
{
Console.WriteLine(#"Error occurred logging on: " + ex.ToString());
return false;
}
return true;
}
}
[TestMethod]
Public Void TestLoginSuccess()
{
Assert.IsTrue(FW_Shared.Perform_Login(FW_Shared.OrgCode, FW_Shared.Username, FW_Shared.Password));
Console.WriteLine(#"Login Successful");
}
[TestMethod]
Public Void TestLoginFailure()
{
Assert.IsFalse(FW_Shared.Perform_Login(FW_Shared.OrgCode, “foo”, “bar”));
Console.WriteLine(#"Login Failed");
}
I use wsDualHttpBinding in a wcf service, and i use the following code to store client channels:
public static void Subscribe()
{
try
{
// Subscribe the guest to the beer inventory
var guest = OperationContext.Current.GetCallbackChannel<ILoggingServiceCallBack>();
if (!CallbackList.Contains(guest))
{
CallbackList.Add(guest);
}
}
catch (Exception ex)
{
//do stuff
}
finally
{
//do stuff
}
}
and i call back clients like that:
public static void LoggingCallBack(Action<ILoggingServiceCallBack> callbackNotification)
{
try
{
if (OperationContext.Current != null)
{
var guest = OperationContext.Current.GetCallbackChannel<ILoggingServiceCallBack>();
if (!CallbackList.Contains(guest))
{
CallbackList.Add(guest);
}
}
foreach (var LoggingCallBack in CallbackList)
{
var temp = LoggingCallBack;
try
{
new Thread(() =>
{
try
{
callbackNotification(temp);
}
catch (Exception ex)
{
//do something
}
}).Start();
}
catch (Exception ex)
{
//do somethin
}
}
}
catch (Exception ex)
{
//doing something
}
finally
{
//doing something
}
}
im running through some troubles:
i have no way to tell if the client is online or not before i call
it back.
i need to be able to remove the client after no activity from the
list i guess i would be able to do that if i achieved number 1.
what is the best way to identify clients, in other words what is
the best unique identifier i can identify the client with?
if a connection with the client faulted i don't know how to detect
that and start new one from the client as if i tried to do that it refuse to and it throw exception that the connection is faulted.
sorry if i have asked more than one question, please give your opinion about the code i posted and any answer to any question of the above.
How can I restart a windows service programmatically in .NET?
Also, I need to do an operation when the service restart is completed.
This article uses the ServiceController class to write methods for Starting, Stopping, and Restarting Windows services; it might be worth taking a look at.
Snippet from the article (the "Restart Service" method):
public static void RestartService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
int millisec1 = Environment.TickCount;
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
// count the rest of the timeout
int millisec2 = Environment.TickCount;
timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2-millisec1));
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
catch
{
// ...
}
}
Take a look at the ServiceController class.
To perform the operation that needs to be done when the service is restarted, I guess you should do that in the Service yourself (if it is your own service).
If you do not have access to the source of the service, then perhaps you can use the WaitForStatus method of the ServiceController.
An example using by ServiceController Class
private void RestartWindowsService(string serviceName)
{
ServiceController serviceController = new ServiceController(serviceName);
try
{
if ((serviceController.Status.Equals(ServiceControllerStatus.Running)) || (serviceController.Status.Equals(ServiceControllerStatus.StartPending)))
{
serviceController.Stop();
}
serviceController.WaitForStatus(ServiceControllerStatus.Stopped);
serviceController.Start();
serviceController.WaitForStatus(ServiceControllerStatus.Running);
}
catch
{
ShowMsg(AppTexts.Information, AppTexts.SystematicError, MessageBox.Icon.WARNING);
}
}
You could also call the net command to do this. Example:
System.Diagnostics.Process.Start("net", "stop IISAdmin");
System.Diagnostics.Process.Start("net", "start IISAdmin");
This answer is based on #Donut Answer (the most up-voted answer of this question), but with some modifications.
Disposing of ServiceController class after each use, because it implements IDisposable interface.
Reduce the parameters of the method: there is no need to the serviceName parameter being passed for each method, we can set it in the constructor, and each other method will use that service name.
This is also more OOP-friendly.
Handle the catch exception in a way that this class could be used as a component.
Remove the timeoutMilliseconds parameter from each method.
Add two new methods StartOrRestart and StopServiceIfRunning, which could be considered as a wrapper for other basic methods, The purpose of those methods are only to avoid exceptions, as described in the comment.
Here is the class
public class WindowsServiceController
{
private readonly string serviceName;
public WindowsServiceController(string serviceName)
{
this.serviceName = serviceName;
}
// this method will throw an exception if the service is NOT in Running status.
public void RestartService()
{
using (ServiceController service = new ServiceController(serviceName))
{
try
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped);
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running);
}
catch (Exception ex)
{
throw new Exception($"Can not restart the Windows Service {serviceName}", ex);
}
}
}
// this method will throw an exception if the service is NOT in Running status.
public void StopService()
{
using (ServiceController service = new ServiceController(serviceName))
{
try
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped);
}
catch (Exception ex)
{
throw new Exception($"Can not Stop the Windows Service [{serviceName}]", ex);
}
}
}
// this method will throw an exception if the service is NOT in Stopped status.
public void StartService()
{
using (ServiceController service = new ServiceController(serviceName))
{
try
{
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running);
}
catch (Exception ex)
{
throw new Exception($"Can not Start the Windows Service [{serviceName}]", ex);
}
}
}
// if service running then restart the service if the service is stopped then start it.
// this method will not throw an exception.
public void StartOrRestart()
{
if (IsRunningStatus)
RestartService();
else if (IsStoppedStatus)
StartService();
}
// stop the service if it is running. if it is already stopped then do nothing.
// this method will not throw an exception if the service is in Stopped status.
public void StopServiceIfRunning()
{
using (ServiceController service = new ServiceController(serviceName))
{
try
{
if (!IsRunningStatus)
return;
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped);
}
catch (Exception ex)
{
throw new Exception($"Can not Stop the Windows Service [{serviceName}]", ex);
}
}
}
public bool IsRunningStatus => Status == ServiceControllerStatus.Running;
public bool IsStoppedStatus => Status == ServiceControllerStatus.Stopped;
public ServiceControllerStatus Status
{
get
{
using (ServiceController service = new ServiceController(serviceName))
{
return service.Status;
}
}
}
}
If you are using .NET Core you have to download System.ServiceProcess package
And this will work only on WINDOWS
How about
var theController = new System.ServiceProcess.ServiceController("IISAdmin");
theController.Stop();
theController.Start();
Don't forget to add the System.ServiceProcess.dll to your project for this to work.
See this article.
Here is a snippet from the article.
//[QUICK CODE] FOR THE IMPATIENT
using System;
using System.Collections.Generic;
using System.Text;
// ADD "using System.ServiceProcess;" after you add the
// Reference to the System.ServiceProcess in the solution Explorer
using System.ServiceProcess;
namespace Using_ServiceController{
class Program{
static void Main(string[] args){
ServiceController myService = new ServiceController();
myService.ServiceName = "ImapiService";
string svcStatus = myService.Status.ToString();
if (svcStatus == "Running"){
myService.Stop();
}else if(svcStatus == "Stopped"){
myService.Start();
}else{
myService.Stop();
}
}
}
}
I needed somethin more complex, because sometimes services with depencies couldnt be restarted and just throw exception or service could be set to "disabled" and so on.
So this is what i did:
(It checks if service does exist, if its "Disabled" it will set service to "Auto" and when it couldnt restart service it will use taskkill command to kill service through PID and then start it again (You need to be carefull with dependent services with this cause you will need to start/restart them too).
And it just returns true/false if restart was sucessfull
Tested on WIN10 only.
PS: working on version which detect dependent services when using taskkill and restart them too
//Get windows service status
public static string GetServiceStatus(string NameOfService)
{
ServiceController sc = new ServiceController(NameOfService);
switch (sc.Status)
{
case ServiceControllerStatus.Running:
return "Running";
case ServiceControllerStatus.Stopped:
return "Stopped";
case ServiceControllerStatus.Paused:
return "Paused";
case ServiceControllerStatus.StopPending:
return "Stopping";
case ServiceControllerStatus.StartPending:
return "Starting";
default:
return "Status Changing";
}
}
//finds if service exists in OS
public static bool DoesServiceExist(string serviceName)
{
return ServiceController.GetServices().Any(serviceController => serviceController.ServiceName.Equals(serviceName));
}
//finds startup type of service
public static string GetStartupType(string serviceName)
{
ManagementObject objManage = new ManagementObject("Win32_Service.Name='"+serviceName+"'");
objManage.Get();
string status1 = objManage["StartMode"].ToString();
return status1;
}
//restart service through PID
public static bool RestartServiceByPID(string NameOfService)
{
LogWriter log = new LogWriter("TaskKilling: " + NameOfService);
string strCmdText = "/C taskkill /f /fi \"SERVICES eq " + NameOfService + "\"";
Process.Start("CMD.exe", strCmdText);
using(ServiceController ScvController = new ServiceController(NameOfService))
{
ScvController.WaitForStatus(ServiceControllerStatus.Stopped);
if (GetServiceStatus(NameOfService) == "Stopped")
{
ScvController.Start();
ScvController.WaitForStatus(ServiceControllerStatus.Running);
if (GetServiceStatus(NameOfService) == "Running")
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
}
//Restart windows service
public static bool RestartWindowsService(string NameOfService)
{
try
{
//check if service exists
if(DoesServiceExist(NameOfService) == false)
{
MessageBox.Show("Service " + NameOfService + " was not found.");
return false;
}
else
{
//if it does it check startup type and if it is disabled it will set it to "Auto"
if (GetStartupType(NameOfService) == "Disabled")
{
using (var svc = new ServiceController(NameOfService))
{
ServiceHelper.ChangeStartMode(svc, ServiceStartMode.Automatic);
if (svc.Status != ServiceControllerStatus.Running)
{
svc.Start();
svc.WaitForStatus(ServiceControllerStatus.Running);
if(GetServiceStatus(NameOfService) == "Running")
{
return true;
}
else
{
return false;
}
}
else
{
svc.Stop();
svc.WaitForStatus(ServiceControllerStatus.Stopped);
if(GetServiceStatus(NameOfService) == "Stopped")
{
svc.Start();
svc.WaitForStatus(ServiceControllerStatus.Running);
if(GetServiceStatus(NameOfService) == "Running")
{
return true;
}
else
{
return false;
}
}
//restart through PID
else
{
return RestartServiceByPID(NameOfService);
}
}
}
}
//If service is not disabled it will restart it
else
{
using(ServiceController ScvController = new ServiceController(NameOfService))
{
if(GetServiceStatus(NameOfService) == "Running")
{
ScvController.Stop();
ScvController.WaitForStatus(ServiceControllerStatus.Stopped);
if(GetServiceStatus(NameOfService) == "Stopped")
{
ScvController.Start();
ScvController.WaitForStatus(ServiceControllerStatus.Running);
if(GetServiceStatus(NameOfService) == "Running")
{
return true;
}
else
{
return false;
}
}
//if stopping service fails, it uses taskkill
else
{
return RestartServiceByPID(NameOfService);
}
}
else
{
ScvController.Start();
ScvController.WaitForStatus(ServiceControllerStatus.Running);
if(GetServiceStatus(NameOfService) == "Running")
{
return true;
}
else
{
return false;
}
}
}
}
}
}
catch(Exception ex)
{
return RestartServiceByPID(NameOfService);
}
}
You can set a service to restart after failure. So a restart can be forced by throwing an exception.
Use recovery tab on service properties.
Be sure to use reset fail count property to prevent service stopping altogether.
Call Environment.Exit with an error code greater than 0, which seems appropriate, then on install we configure the service to restart on error.
Environment.Exit(1);
I have done same thing in my Service. It is working fine.