Get Service Information without WMI - c#

presently I am writing a small piece of code to get the list of web services hosted on IIS in a remote system,
the working code right now is :
string q2 = "select * from Win32_PerfFormattedData_W3SVC_WebService";
ManagementScope scope2 = new ManagementScope(string.Format(#"\\dtp-robaro2\{1}", host, ns), options);
// ns here is string ns = #"root\cimv2";
scope2.Connect();
ManagementObjectSearcher search2 = new ManagementObjectSearcher(scope, new ObjectQuery(q2));
foreach (ManagementObject mo in search2.Get())
{
Console.WriteLine(mo.ClassPath);
Console.WriteLine(mo.GetText(TextFormat.Mof));
}
now I was wondering if WMI is turned off on the remote system that i am querying then is there any alternative way to access the information i get with the above code?

Use tool Service Control - SC.EXE

I have converted this from VB.Net to C# so it may not be exactly correct, but this will do what you need:
public List<string> GetSites(string MachineName)
{
List<string> siteList = new List<string>();
DirectoryEntry iis = new DirectoryEntry(string.Format("IIS://{0}/w3svc/1/root", MachineName));
foreach (DirectoryEntry site in iis.Children) {
if (site.SchemaClassName == "IIsWebServer") {
siteList.Add(site.Properties("ServerComment").Value.ToString());
}
}
return siteList;
}

Related

C# ManagementObjectSearcher object container returns null for printers

I have a strange issue, I hope somebody can help me out. A software was deployed without any problem 2 months ago. Now I got back to it, and it returns an invalid class error for the following code. All what it does, it returns all the printers installed on the computer.
The error is, the searcher.Container = null. In the past it was list of printer objects. Nothing has changed since then, the computer is a 64 bit Windows 7, using Visual Studio 2015.
public static ObservableCollection<PrinterStatusData> GetAvailablePrinterAndStatus()
{
ObservableCollection<PrinterStatusData> printerStatus = new ObservableCollection<PrinterStatusData>();
ManagementScope scope = new ManagementScope(#"\root\cimv2");
scope.Connect();
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer");
foreach (ManagementBaseObject o in searcher.Get())
{
ManagementObject printer = (ManagementObject)o;
if (printer != null)
{
string name = printer["Name"].ToString();
bool available = !printer["WorkOffline"].ToString().ToLower().Equals("true");
printerStatus.Add(new PrinterStatusData(name, available));
}
}
return printerStatus;
}
if (printer["Name"] != null)
{
string name = printer["Name"].ToString();
bool available = !printer["WorkOffline"].ToString().ToLower().Equals("true");
printerStatus.Add(new PrinterStatusData(name, available));
}

Try to read Values in LOcal Group policy

I am trying to read two setting values in Local Group policy (gpedit.msc). The path is :
Local Computer Policy\Windows Settings\Security Settings\Local Policies\User Rights Assignment
The Policy that I want to read are :
1. Perform volume maintainace tasks (Users assigned to it)
2. Lock Pages in memory (Users assigned to it).
I have searched the web (including all stackoverflow threads) and could not find a solution to this but could not get a solution to this. Below is the code I am using currently but it only returns me 7 values.
I am not sure if this is possible. Please suggest. I am using C# .NET as language and would prefer if possible be able to read these setting from a remote machine (so I am preferring WMI approach).
Also I only want to read values. Now editing or writing...
Please suggest..
Girija
Code
private void Test()
{
ManagementScope scope =
new ManagementScope(
"\\\\localhost\\root\\rsop\\Computer");
scope.Connect();
ObjectQuery query = new ObjectQuery(
"SELECT * FROM RSOP_UserPrivilegeRight");
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
List<string> val = new List<string>();
foreach (ManagementObject mgo in queryCollection)
{
var d = mgo["Name"];
val.Add(Convert.ToString(d));
}
}

Why does counting messages on MSMQ returns 0 when using Powershell Method?

I'm developing a WCF service running on IIS and I need to count the messages i = for each private queue in MSMQ. The fastest way seems to be the powershell method.
The benchmark is here:
http://www.codeproject.com/Articles/346575/Message-Queue-Counting-Comparisions)
When debugging on Visual Studio 2012, it works great but when deployed on my local IIS 7.5 server, it returns 0.
Here is the method I'm using:
private int GetPowerShellCount()
{
return GetPowerShellCount(".\\private$\pingpong", Environment.MachineName, "", "");
}
private int GetPowerShellCount(string queuePath, string machine,string username, string password)
{
var path = string.Format(#"\\{0}\root\CIMv2", machine);
ManagementScope scope;
if (string.IsNullOrEmpty(username))
{
scope = new ManagementScope(path);
}
else
{
var options = new ConnectionOptions {Username = username, Password = password};
scope = new ManagementScope(path, options);
}
scope.Connect();
if (queuePath.StartsWith(".\\")) queuePath=queuePath.Replace(".\\",string.Format("{0}\\",machine));
string queryString = String.Format("SELECT * FROM Win32_PerfFormattedData_msmq_MSMQQueue");
var query = new ObjectQuery(queryString);
var searcher = new ManagementObjectSearcher(scope, query);
IEnumerable<int> messageCountEnumerable =
from ManagementObject queue in searcher.Get()
select (int)(UInt64)queue.GetPropertyValue("MessagesInQueue");
//IEnumerable<string> messageCountEnumerable =
// from ManagementObject queue in searcher.Get()
// select (string)queue.GetPropertyValue("Name");
var x = messageCountEnumerable.First();
return x;
}
please note that I'm not using the user/pass params so it's all local (WCF service and MSMQ on the same machine).
Why it's returning 0 when deployed to IIS?
What do you think I should try out?
Your problem might be related to IIS specific behavior.
Have a look at Tom Hollander's blog: MSMQ, WCF and IIS: Getting them to play nice (Part 1)
In general, message queues can be called whatever you want. However
when you are hosting your MSMQ-enabled service in IIS 7 WAS, the queue
name must match the URI of your service's .svc file. In this example
we'll be hosting the service in an application called MsmqService
with an .svc file called MsmqService.svc, so the queue must be
called MsmqService/MsmqService.svc.

Querying if a Windows Service is disabled (without using the Registry)?

Is there a .NET (C#) method or API call that I can use to query if a Windows Service is disabled? The relevant MSDN article is here.
I want to avoid querying the registry directly. Below is some of the code that I am using right now (and it works). However I am looking for something more elegant and less invasive.
const String basepathStr = #"System\CurrentControlSet\services\";
String subKeyStr = basepathStr + servicenameStr;
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(subKeyStr))
{
return (int) key.GetValue("Start");
}
I did find a simliar question but I was hoping for a better answer since the answers are presumably outdated (3 years have passed).
This the most relevant section of the code I decided to use...thanks for the help all!
StartupState state = StartupState.Unknown;
try
{
PermissionSet fullTrust = new PermissionSet(System.Security.Permissions.PermissionState.Unrestricted);
fullTrust.Demand();
string wmiQuery = #"SELECT * FROM Win32_Service WHERE Name='" + servicenameStr + #"'";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery);
ManagementObjectCollection results = searcher.Get();
foreach (ManagementObject service in results)
{
if (service["StartMode"].ToString() == "Disabled")
state = StartupState.Disabled;
else
state = StartupState.Enabled;
}
return state;
}
catch (SecurityException se)
{
return StartupState.Refused;
}
catch (Exception e)
{
return StartupState.Error;
}
Use the ServiceController class to get information about services.
EDIT
Seems one of the things you can't do with the ServiceController is get the startup type. Googling showed the following blog post that has code that uses P/Invoke to get the service startup type: http://peterkellyonline.blogspot.de/2011/04/configuring-windows-service.html
Add a ref to System.Management and the following code will get you the StartMode
string wmiQuery = "SELECT * FROM Win32_Service WHERE Name='YourServiceName'";
var searcher = new ManagementObjectSearcher(wmiQuery);
var results = searcher.Get();
foreach (ManagementObject service in results)
{
Console.WriteLine(service["StartMode"]);
}
ServiceController class doesn't provide this information. You should use WMI. See here for detailed solution
WMI can be another way for querying the status of the windows services
You can use:
using System.ServiceProcess;
And then link the service you want to view the satus by:
// Link by service name
ServiceController TheServiceName = new ServiceController();
TheServiceName.ServiceName = "Spooler";
// Link by display name
ServiceController TheDisplayName = new ServiceController();
TheDisplayName.ServiceName = "Print Spooler";
To check for example the isRunning Status :
if (TheServiceName.Status == ServiceControllerStatus.Running)
MessageBox.Show("The service is running.");

different results for web and desktop applications for same code

I have the following piece of code.
It is returning different results when running on the same machine in case of web and desktop applications.
Here is my code. Please guide me on what to do regarding this???
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
return (from ManagementObject wmiHD in searcher.Get()
select wmiHD["SerialNumber"] == null ? "VM HD" : wmiHD["SerialNumber"].ToString()).ToList();
Here is a LINQ-free version of the same code
var hdCollection = new List<string>();
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
foreach (ManagementObject wmiHD in searcher.Get())
{
// get the hardware serial no.
if (wmiHD["SerialNumber"] == null)
{
hdCollection.Add("VM HD");
}
else
{
hdCollection.Add(wmiHD["SerialNumber"].ToString());
}
}
return hdCollection;
That could possibly be caused by two things:
web server runs with different user account (probably NetworkService)
http://www.bluevisionsoftware.com/WebSite/TipsAndTricksDetails.aspx?Name=AspNetAccount
web server runs code without Fulltrust permissions (probably medium trust)
http://discussion.accuwebhosting.com/iis-web-server/993-how-grant-full-trust-mode-domain-asp-net-2-0-iis-6-0-a.html
Both actions can compromise security, but the first one gives more choices to fix this by setting ACLs.

Categories

Resources