2

I am trying to get the size of this dsa file present in c:\windows\ntds\ directory.

I am getting error here, and I don’t know why. The error is “Invalid Query”.

I seems to get this error quite often when I work with different WMI classes.

I don’t know why this error occur and how to resolve this?

Is there any error in below code, How to resolve this?

Why we will get this Invalid Query error, whats the source of it? Its inner exception will always be null?

private int getDatabaseFileSize(string DSADatabaseFile, string machineName)
        {
            string scope = @"\\" + machineName + @"\root\CIMV2";
            string query = string.Format("Select FileSize from CIM_DataFile WHERE Name = '{0}'", DSADatabaseFile);
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
            ManagementObjectCollection collection = searcher.Get();
            foreach (ManagementObject mobj in searcher.Get())
            {
                Console.WriteLine("File Size : " + mobj["FileSize"]);
            }
            return 0;
        }

Thanks

sunder
  • 1,803
  • 4
  • 29
  • 50
  • can you tell what was the value if `DSADatabaseFile` in the query? – PresleyDias May 02 '12 at 05:43
  • I have all right, I am running this application under admin account. Value for DSADatabaseFile is C:\Windows\NTDS\ntds.dit and its size is 16MB. I am getting exception as it will reach in keyword in foreach loop. – sunder May 02 '12 at 05:44
  • try this `C:\\Windows\\NTDS\\ntds.dit` or from the link http://stackoverflow.com/a/972232/1051198 – PresleyDias May 02 '12 at 05:51
  • Download WMI Code Creator from Microsoft downloads center: [http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=8572][1]. Generate the code from the WMI Code creator to be executed on the remote machine and then try. – Prashant May 02 '12 at 05:54
  • I had read that post long time back before asking question and used same only. But no luck. – sunder May 02 '12 at 05:55
  • when i run below wql code in wmi code creator. strComputer = "machineName" Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") Set colItems = objWMIService.ExecQuery( _ "Select FileSize from CIM_DataFile WHERE Name = 'C:\Windows\NTDS\ntds.dit'",,48) For Each objItem in colItems Wscript.Echo "-----------------------------------" Wscript.Echo "CIM_DataFile instance" Wscript.Echo "-----------------------------------" Wscript.Echo "FileSize: " & objItem.FileSize Next It will return 0x80041017 which is error. – sunder May 02 '12 at 06:08

1 Answers1

3

I'm guessing, but since your query is syntactically correct and uses the correct field and object names, I assume it is because you pass the string "C:\Windows\NTDS\ntds.dit" as DSADatabaseFile. That would by correct for "typical" use inside C#, like when using the Path class, or such, but not here.

You need to pass the filename with two backslashes to WMI. Since, however, C# requires to already, you need to effectively pass four:

 getDatabaseFileSize("C:\\\\Windows\\\\NTDS\\\\ntds.dit", machine)

or using a verbatim string literal:

 getDatabaseFileSize(@"C:\\Windows\\NTDS\\ntds.dit", machine);

Update Here is a complete example:

// Compile with: csc foo.cs /r:System.Management.dll

using System;
using System.Management;

namespace Foo
{
    public class Program
    {
        private int getDatabaseFileSize(string DSADatabaseFile, string machineName)
        {
            string scope = @"\\" + machineName + @"\root\CIMV2";
            string query = string.Format("Select FileSize from CIM_DataFile WHERE Name = '{0}'", DSADatabaseFile);
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
            ManagementObjectCollection collection = searcher.Get();
            foreach (ManagementObject mobj in searcher.Get())
            {
                Console.WriteLine("File Size : " + mobj["FileSize"]);
            }
            return 0;
        }

        public static void Main(string[] args)
        {
            var p = new Program();

            // These work
            p.getDatabaseFileSize("C:/boot.ini", ".");
            p.getDatabaseFileSize(@"C:\\boot.ini", ".");
            p.getDatabaseFileSize("C:\\\\boot.ini", ".");

            // These fail
            try {
                p.getDatabaseFileSize("C:\\boot.ini", ".");
            } catch (ManagementException ex) { 
                Console.WriteLine("Failed: {0}", ex.ErrorCode);
            }
            try {
                p.getDatabaseFileSize(@"C:\boot.ini", ".");
            } catch (ManagementException ex) { 
                Console.WriteLine("Failed: {0}", ex.ErrorCode);
            }
        }
    }
}

Compile with:

The (expected) output is:

File Size : 313
File Size : 313
Failed: InvalidQuery.
Failed: InvalidQuery.

Update There seems to be a related question already (mentioning the need for \\\\ instead of \\).

Community
  • 1
  • 1
Christian.K
  • 47,778
  • 10
  • 99
  • 143
  • No luck, I have tried all. C:\\Windows\\NTDS\\ntds.dit and C:\\\\Windows\\\\NTDS\\\\ntds.dit also. Same error. – sunder May 02 '12 at 05:56
  • Well, it worked for me when using your code (both the error and then the fix using the doubled double-backslashes). You may also want to try using a single (forward) slash instead of (any) backslashes as directory separator. E.g. `C:/Windows/ntds/ntds.dit` works for me as well. – Christian.K May 02 '12 at 05:58
  • I am surprised that it work for you, but I tried all kind of slash, its not working for me. I get this error often working with different wmi classes. – sunder May 02 '12 at 06:05
  • Well "invalid query", just means that an invalid query was passed. Could be a couple of things. I typically get that, when referencing unknown properties or classes, or messing up the syntax (missing spaces between keywords, unclosed quotes, whatever). – Christian.K May 02 '12 at 06:12
  • thanks for information i run the test for different files getDatabaseFileSize("C:/Windows/bootstat.dat", machineName); getDatabaseFileSize(@"C:\Windows\bootstat.dat", machineName); getDatabaseFileSize(@"C:\\Windows\\bootstat.dat", machineName); getDatabaseFileSize("C:\\\\Windows\\\\bootstat.dat", machineName); same error. – sunder May 02 '12 at 06:25
  • hey thanks christian, it worked. I was changing variable value at runtime from quickwatch. But that did not reflected somehow. But when i replace it and use it worked. Thanks – sunder May 02 '12 at 06:32