简体   繁体   中英

C# - Visual Studio - 'object' does not contain a definition for 'ExecuteQuery'

I am trying to add code to an existing project that will check for existence of a device in SCCM and delete it if it does exist. I seem to be missing something, in that particular block of code. I get an error - 'object' does not contain a definition for 'ExecuteQuery' and no extension method 'ExecuteQuery' accepting a first argument of type 'object' could be found.

Here is the C# code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net.NetworkInformation;
using SupportToolkit.Models;
using SupportToolkit.WindowsAutomationServices;
using NLog;
using System.Text;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.Management; 


namespace SupportToolkit.Controllers
{
public class TPOSRecordDeletionController : Controller
{
private static Logger recordDeletionLogger = LogManager.GetCurrentClassLogger();

[Authorize(Roles = @"nor\NST_RIT_Users,nor\NST_STM_Users,nor\NST_Admin_Users,nor\NST_CORP_Users")]

// GET: TPOSRecordDeletion
public ActionResult Index(TPOSRecordDeletionModel model)
{
    if (model.ComputerName != null)
    {

    }

    if (ModelState.IsValid)
    {
        if (!(string.IsNullOrEmpty(model.btnDeleteRecord)))
        {
            InvokeRecordDeletion(model);
        }
    }
    return View(model);
}

[Authorize(Roles = @"nor\NST_RIT_Users,nor\NST_STM_Users,nor\NST_Admin_Users,nor\NST_CORP_Users")]
public string InvokeRecordDeletion(TPOSRecordDeletionModel model)
{
    model.Status = "Running Service";
    var windowsAutomationService = new WindowsAutomationServicesClient();
    string shortServiceOutput;

    var serviceAction = "Remove-TPOSRecords";

    var SCCMServer = "server.nor.net";

    var siteCode = "PO60";

    string[] recordDeletionArguments = new string[1];
    recordDeletionArguments[0] = model.ComputerName;

    model.Status = "Processing" + model.ComputerName;

    Ping pingSender = new Ping();
    PingOptions options = new PingOptions();

    // Use the default Ttl value which is 128,
    // but change the fragmentation behavior.
    options.DontFragment = true;

    // Create a buffer of 32 bytes of data to be transmitted.
    string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    byte[] buffer = Encoding.ASCII.GetBytes(data);
    int timeout = 120;
    PingReply reply = pingSender.Send(model.ComputerName, timeout, buffer, options);

    if (reply.Status == IPStatus.Success)
    {
        model.Status = model.ComputerName + "is currently online and will not be removed!";
    }

    else
    {
        // set up domain context
        using (var ctx = new System.DirectoryServices.AccountManagement.PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain))
        {
            // find a computer
            ComputerPrincipal computer = ComputerPrincipal.FindByIdentity(ctx, model.ComputerName);

            if (computer == null)
            {
                model.Status = model.ComputerName + "does not exist in Active Directory.";    
            }

            else
            {
                computer.Delete();
                model.Status = model.ComputerName + "successfully removed from Active Directory!";
            }

            //insert code here for checking for existence of computer in SCCM and removing from SCCM if exists

SmsNamedValuesDictionary namedValues = new SmsNamedValuesDictionary();

            WqlConnectionManager connection = new WqlConnectionManager(namedValues);
            connection.Connect("s0319p60.nordstrom.net");

            foreach (IResultObject computerobject in connection.QueryProcessor.ExecuteQuery("Select ResourceID From SMS_R_System Where Name ='" + model.ComputerName + "'"))

            {
                if (computerobject == null)
                {
                    model.Status = model.ComputerName + "does not exist in SCCM.";
                }

                else
                {
                    computerobject.Delete();
                    model.Status = model.ComputerName + "successfully removed from SCCM!";
                }
        }
    }

    var userName = User.Identity.Name;

    var serviceOutput = windowsAutomationService.RunAutomationService(serviceAction, userName, recordDeletionArguments);

    recordDeletionLogger.Info(userName + " is attempting to remove the record " + model.ComputerName);

    if (serviceOutput.Length >= 7)
    {
        shortServiceOutput = serviceOutput.Substring(0, 7);
        shortServiceOutput = shortServiceOutput.ToLower();
    }
    else
    {
        shortServiceOutput = serviceOutput;
        shortServiceOutput = shortServiceOutput.ToLower();
    }


    if (shortServiceOutput == "success")
    {
        model.Status = "Successfully removed " + model.ComputerName + " from SCCM and Active Directory";
        recordDeletionLogger.Info(userName + " successfully removed " + model.ComputerName + " from SCCM and Active Directory");
        return "Success";
    }

    else
    {
        model.Status = "Failure removing " + model.ComputerName + " from SCCM and Active Directory. Unknown Error";
        recordDeletionLogger.Info(userName + " failed to remove " + model.ComputerName + " from SCCM and Active Directory");
        return "Failure";

    }

}
}
}

internal interface IResultObject
{
//void Delete();
void Delete();
}

internal class WqlConnectionManager
{
private SmsNamedValuesDictionary namedValues;

public WqlConnectionManager(SmsNamedValuesDictionary namedValues)
{
   this.namedValues = namedValues;
}

public object QueryProcessor { get; internal set; }

internal void Connect(string v)
{
   throw new NotImplementedException();
}

public object ExecuteQuery { get; internal set; }
}

internal class SmsNamedValuesDictionary
{
public SmsNamedValuesDictionary()
{
}
}

Well - after a few days of searching, I FINALLY figured out the issue.

The entire block of code at the end, was not necessary. The issue was that there were missing assembly references and using statements in the code. Specifically:

using Microsoft.ConfigurationManagement.ManagementProvider;
using Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine;

The corresponding DLLs also needed to be added to the project as references.

I hope this helps someone who runs into similar issues and is not versed in C# coding. I myself am only versed in PowerShell, so figuring this out took a lot of work for me. Thanks.

You create a custom "connection" object:

WqlConnectionManager connection = new WqlConnectionManager(namedValues);

Then call a method on one of its properties:

connection.QueryProcessor.ExecuteQuery("...")

But what is that QueryProcessor property?...

public object QueryProcessor { get; internal set; }

It's an object . As the error states, object doesn't have a method called ExecuteQuery . (It doesn't have very many methods or properties at all, really.)

I can't really tell from this code (maybe I'm missing something?) what specific type you're expecting QueryProcessor to be, but it should definitely be something more specific than object . Something analogous to a SQLCommand object, perhaps? Essentially, whatever type would have that ExecuteQuery method.

If there's a compelling reason in the existing codebase for this to be of type object , you'd need to determine what that reason is. There seems to be a lot of use of object here, which smells of some bad design choices from before you got there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM