Hi, I'm hoping someone can make sense of this...

I'm trying to use WMI to get file information from a specific directory on a remote machine using CIM_DataFile. I can get all of the files on the on the remote machine using:
System.Management.ObjectQuery oq1 = new System.Management.ObjectQuery("SELECT * FROM CIM_DataFile");

But when I try to narrow it down to the specific directory, I get an Invalid Query error (pasted at the end of this post). I'm using this query for the specific directory:
System.Management.ObjectQuery oq1 = new System.Management.ObjectQuery("SELECT * FROM CIM_DataFile WHERE Name = 'c:\\pats\\bin'");

I've also tried:
System.Management.ObjectQuery oq1 = new System.Management.ObjectQuery(@"SELECT * FROM CIM_DataFile WHERE Name = 'c:\pats\bin'");

And I've tried both of the above, ending the WHERE Name = path with a \. No difference.

The method I've written:

public void TryWMIConnect(string machdomain, string machname, string username, string passwd)
{
ConnectionOptions options = new ConnectionOptions();
options.Username = machdomain + "\\" + username;
options.Password = passwd;
options.Impersonation = ImpersonationLevel.Impersonate;
options.Authentication = AuthenticationLevel.Packet;
options.Timeout = new TimeSpan(0, 0, 0, 5);

string RemoteMachine = "\\\\" + machname + "\\root\\cimv2";
ManagementScope scope = new ManagementScope(RemoteMachine, options);
bool wmiSuccess = false;
try
{
scope.Connect();
wmiSuccess = true;
}
catch (System.Runtime.InteropServices.COMException e)
{
Trace.WriteLine(e.Message);
Trace.WriteLine(machname, " WMI Failure");
}
if (wmiSuccess)
{
System.Management.ObjectQuery oq1 = new System.Management.ObjectQuery("SELECT * FROM CIM_DataFile WHERE Name = 'c:\\pats\\bin'");
ManagementObjectSearcher query1 = new ManagementObjectSearcher(scope, oq1);
ManagementObjectCollection queryCollection1 = query1.Get();
try
{
Trace.WriteLine(queryCollection1.Count); //This is where the error occurrs - or, at least, it reports after this line execution
}
catch (Exception e)
{
Trace.WriteLine(e);
}
}
}

Error thrown:
System.Management.ManagementException: Invalid query
at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
at System.Management.ManagementObjectCollection.get_Count()
at PatsUpdateDev.Config.TryWMIConnect(String machdomain, String machname, String username, String passwd) in C:\Users\maxmel\Documents\Visual Studio 2008\Projects\PatsUpdateDev\PatsUpdateDev\Config.cs:line 156
System.Management.ManagementException: Invalid query
at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
at PatsUpdateDev.Config.TryWMIConnect(String machdomain, String machname, String username, String passwd) in C:\Users\maxmel\Documents\Visual Studio 2008\Projects\PatsUpdateDev\PatsUpdateDev\Config.cs:line 165

Thanks in advance for any advice you may be able to provide...

Use Drive and Path property.

ObjectQuery qry = new ObjectQuery(@"select * from CIM_DATAFILE Where Drive='C:' AND Path='\\windows\\'");
   ManagementObjectSearcher search=new ManagementObjectSearcher(scope,qry);
  scope.Connect();
 ....

Use Drive and Path property.

ObjectQuery qry = new ObjectQuery(@"select * from CIM_DATAFILE Where Drive='C:' AND Path='\\windows\\'");
   ManagementObjectSearcher search=new ManagementObjectSearcher(scope,qry);
  scope.Connect();
 ....

Hi adatapost,
Thanks! This worked... but, I'd tried it before (Driver and Path) with the @ in front of the quoted string. The only difference was I used only as single '\' in the path. I was my understanding that when you started the string with @, the additional '\' would not be necessary. Am I misunderstanding that concept, or why is it different here?
I'm just trying to understand... Thanks again!

The problem here is that the '\' character is the escape symbol for both C# and WQL. Using '@' tells C# not to escape the '\' but you need to tell WQL the same thing.
Heres an example to try and clear it up:
You enter "WHERE Drive = 'C:' AND Path = '\\\\testpath'" with no @.
C# reads the first '\' as an escape so it reads the next '\' as a character and not a control symbol. So '\\' becomes '\'. This happens twice and WQL receives "WHERE Drive = 'C:' AND Path = '\\testpath'". At this point WQL does the same thing; it reads the first '\' as an escape char and reads the next '\' as a literal character and ends up with WHERE Drive = 'C:' AND Path = '\testpath'". In other words, each time the string is parsed it strips out a '\' from each pair. The query is parsed first as C# and then again as a WMI query string.

In C# you can use @ to escape the whole string. It tells the compiler to treat ANY special characters in the string as literals. This means you don't need to escape the '\' symbol for C#, but you still need to include an extra '\' as an escape char for the WQL parser.

Hopefully this has helped and not confused you more. If anyone else wants to chime in feel free...maybe you can explain it more clearly.

Edited 6 Years Ago by Geekitygeek: n/a

This article has been dead for over six months. Start a new discussion instead.