Visual Studio 2010 SP1 breaks things? - c#

I'm using this little code snippet to catch Java processes with certain parameters:
string query = "Select * From Win32_Process Where Name = 'javaw.exe'";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection processList = searcher.Get();
foreach (ManagementObject obj in processList)
{
string cmdLine = obj.GetPropertyValue("CommandLine").ToString();
if (cmdLine.IndexOf("someapplication") != -1)
{
// ...
}
}
This code worked like a charm just a couple of days ago when I didn't have SP1 for VS2010. Now it throws a null pointer exception on line 7. I'm trying to compile for .NET Framework 2.0.
Help!? :/

if (cmdLine != null && cmdLine.IndexOf("someapplication") != -1)

It probably has less to do with SP1 and more to do with a Java update. Just check for null:
string query = "Select * From Win32_Process Where Name = 'javaw.exe'";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection processList = searcher.Get();
foreach (ManagementObject obj in processList)
{
object cmdLineValue = obj.GetPropertyValue("CommandLine");
if(cmdLineValue != null) {
string cmdLine = cmdLineValue.ToString();
if (cmdLine.IndexOf("someapplication") != -1)
{
// ...
}
}
}

Related

Getting MSFT_Partition from MSFT_Disk using Associators

I am trying to get a list of MSFT_Partitions from a MSFT_Disk object and loop over them.
This is the code I have been using so far but it always outputs an System.Management.ManagementException: 'Invalid query ' exception.
This is the code I am using at the moment:
public static void GetDiskInfo() {
var rawDiskInfos = new ManagementObjectSearcher("root\\Microsoft\\Windows\\Storage", "SELECT * FROM MSFT_Disk");
foreach(var rawDiskInfo in rawDiskInfos.Get()) {
Console.WriteLine(rawDiskInfo["FriendlyName"]);
GetPartitionInfo(rawDiskInfo["ObjectId"]);
}
}
public static void GetPartitionInfo(object objectId) {
ManagementScope scope = new ManagementScope("\\\\.\\ROOT\\Microsoft\\Windows\\Storage");
var query = new ObjectQuery("ASSOCIATORS OF {MSFT_Disk.ObjectId=\"" + objectId + "\"} WHERE AssocClass = MSFT_DiskToPartition");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach(var partiton in queryCollection) {
Console.WriteLine(partiton["Guid"]);
}
}
I already tried a lot of solutions I found online and all of them resulted in the same exception.
Thank you very much for your help!
Most queries you'll find on the internet don't do it, but in the general case, you must escape raw strings you pass to WQL queries (in your case objectId contains special characters), using the backslash character, with a method like this:
public static string EscapeWql(string text)
{
if (text == null)
return null;
var sb = new StringBuilder(text.Length);
foreach (var c in text)
{
if (c == '\\' || c == '\'' || c == '"')
{
sb.Append('\\');
}
sb.Append(c);
}
return sb.ToString();
}
So your method should now look like this:
public static void GetPartitionInfo(object objectId)
{
var scope = new ManagementScope(#"root\Microsoft\Windows\Storage");
var query = new ObjectQuery("ASSOCIATORS OF {MSFT_Disk.ObjectId=\"" + EscapeWql((string)objectId) + "\"} WHERE AssocClass = MSFT_DiskToPartition");
using (var searcher = new ManagementObjectSearcher(scope, query))
{
using (var queryCollection = searcher.Get())
{
foreach (var partition in queryCollection)
{
Console.WriteLine(partition["Guid"]);
}
}
}
}
PS: don't forget using statements on IDisposable classes.

Retrieving properties from a complex SQL query in C#

I am querying an SCCM database for package and application properties. What it seems like is that if I use a simple query, I can view and access the properties. On a more complex query where I am assigning variable names to keep the properties separate I cannot.
In the example code below, the query for packages will print out those properties as expected. In the query for applications, all it seems to know about is either AL or DT for the name and the value comes back as a ManagementBaseObject. In fact, the code as posted will crash every time on printing out those property values.
Very confusing, appreciate any input to get this working.
using System;
using System.Management;
namespace Application
{
public class MainApplication
{
static void Main(string[] args)
{
ManagementObjectCollection packages = GetPackages();
ManagementObjectCollection applications = GetApplications();
// * Works! *
foreach (var package in packages)
{
Console.WriteLine("Package Name: {0} ", package.Properties["PackageName"].Value.ToString());
Console.WriteLine("Package ID: {0} ", package.Properties["PackageID"].Value.ToString());
Console.WriteLine("Setup Command: {0} ", package.Properties["CommandLine"].Value.ToString());
}
// * Does not work! *
foreach (var application in applications)
{
Console.WriteLine("Package Name: {0} ", application.Properties["AL.LocalizedDisplayName"].Value.ToString());
Console.WriteLine("Package ID: {0} ", application.Properties["DT.ContentID"].Value.ToString());
Console.WriteLine("Setup Command: {0} ", application.Properties["DT.LocalizedDescription"].Value.ToString());
}
}
private static ManagementObjectCollection GetPackages()
{
String queryString = "SELECT PackageName,PackageID,CommandLine,Comment FROM SMS_Program WHERE Comment LIKE '%LISTMANUAL%' ORDER BY PackageName";
ObjectQuery query = new ObjectQuery(queryString);
ManagementScope scope = new ManagementScope("\\\\somebox.somedomain.com\\root\\sms\\site_DC1");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection objectCollection = searcher.Get();
Console.WriteLine(objectCollection.Count);
return objectCollection;
}
private static ManagementObjectCollection GetApplications()
{
String queryString = "SELECT DT.LocalizedDisplayName,DT.LocalizedDescription,DT.AppModelName,DT.ContentID,AL.LocalizedDisplayName,AL.ModelName FROM SMS_DeploymentType AS DT JOIN SMS_ApplicationLatest AS AL on AL.ModelName=DT.AppModelName JOIN SMS_PackageToContent AS PTC on PTC.ContentUniqueID = DT.ContentID WHERE DT.IsLatest='TRUE' AND DT.LocalizedDescription LIKE '%LISTMANUAL%' ORDER BY AL.LocalizedDisplayName";
ObjectQuery query = new ObjectQuery(queryString);
ManagementScope scope = new ManagementScope("\\\\somebox.somedomain.com\\root\\sms\\site_DC1");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection objectCollection = searcher.Get();
Console.WriteLine(objectCollection.Count);
return objectCollection;
}
}
}

WMI to retrieve website physical path in c#

I've created this VBScript WMI script:
On Error Resume Next
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
Set objWMIService = GetObject("winmgmts:\\localhost\root\MicrosoftIISv2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM IIsWebVirtualDirSetting", _
"WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
WScript.Echo "Path: " & objItem.Path
WScript.Echo
Next
Which returns the physical path (C:\inetpub\wwwroot\webapplication1) to all the applications in IIS.
Now I'm trying to use C# to populate a combobox with those values:
public static ArrayList Test2()
{
ArrayList WebSiteListArray = new ArrayList();
ConnectionOptions connection = new ConnectionOptions();
ManagementScope scope =
new ManagementScope(#"\\" + "localhost" + #"\root\MicrosoftIISV2",
connection);
scope.Connect();
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope,
new ObjectQuery("SELECT * FROM IIsWebVirtualDirSetting"), null);
ManagementObjectCollection webSites = searcher.Get();
foreach (ManagementObject webSite in webSites)
{
WebSiteListArray.Add(webSite.Path);
}
return WebSiteListArray;
}
But the output is the virtual path:
(`IIsWebVirtualDirSetting.Name="W3SVC/1/ROOT/webapplication1"`)
What needs to be changed in my query?
Note: I need to support IIS6 and .NET 4.0
Finally got it...
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\MicrosoftIISv2",
"SELECT * FROM IIsWebVirtualDirSetting");
foreach (ManagementObject queryObj in searcher.Get())
{
result.Add(queryObj["Path"]);
}
I prefer like this:
Connect at my local network server SOMEREMOTESERVER:
ConnectionOptions connection = new ConnectionOptions();
connection.Authentication = System.Management.AuthenticationLevel.PacketPrivacy;
ManagementScope scope =
new ManagementScope(#"\\SOMEREMOTESERVER\root\MicrosoftIISV2",
connection);
scope.Connect();
ObjectQuery query = new ObjectQuery("SELECT * FROM IISWebServerSetting");
var collection = new ManagementObjectSearcher(scope, query).Get();
foreach (ManagementObject item in collection)
{
var value = item.Properties["ServerBindings"].Value;
if (value is Array)
{
foreach (ManagementBaseObject a in value as Array)
{
Console.WriteLine(a["Hostname"]);
}
}
ManagementObject maObjPath = new ManagementObject(item.Scope,
new ManagementPath(
string.Format("IISWebVirtualDirSetting='{0}/root'", item["Name"])),
null);
PropertyDataCollection properties = maObjPath.Properties;
Console.WriteLine(properties["path"].Value);
Console.WriteLine(item["ServerComment"]);
Console.WriteLine(item["Name"]);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine();
}

Trying to access battery level, c#

I'm trying to create an app for windows 8 using c# to display my current battery level. I'm trying to query the win32_battery class for its relevant properties,but I'm getting an unusual result. Here's my code:
private void btn1_Click(object sender, EventArgs e)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Battery");
ManagementObjectCollection collection = searcher.Get();
foreach (ManagementObject obj in collection)
{
txtBox.AppendText(obj.ToString() + "\r\n");
};
}
My only result in the txtBox is
\\MIKESLAPTOP\root\cimv2:Win32_Battery.DeviceID=" ASUSTeKX401-44"
Any ideas why I am only reading theDevideID property? All guidance is greatly appreciated.
This is the expected output. You forgot to enumerate the properties of the query. Make it look similar to this:
foreach (ManagementObject obj in searcher.Get()) {
foreach (var prop in obj.Properties) {
if (prop.Value != null) {
txtBox.AppendText(string.Format("{0} = {1}", prop.Name, prop.Value));
}
}
}

Control Microsoft NLB with WMI c#

I try to control NLB with WMI.
WqlObjectQuery wql = new WqlObjectQuery (#"SELECT * FROM MicrosoftNLB_Node");
ManagementObjectSearcher search = new ManagementObjectSearcher(wql);
foreach (var obj in search.Get())
{
MessageBox.Show(obj.ToString());
}
I get a error message "Invalid class"
Try this:
ManagementObjectSearcher search = new ManagementObjectSearcher(
#"root\MicrosoftNLB",
#"SELECT * FROM MicrosoftNLB_Node");
foreach (var obj in search.Get())
{
MessageBox.Show(obj.ToString());
}
The MicrosoftNLB_Node class it's part of the Root\MicrosoftNLB namespace, So it seems which you are not setting the namespace before to connect to the WMi service.
try this
ManagementObjectSearcher search = new ManagementObjectSearcher(#"root\MicrosoftNLB",wql);

Categories