?
Solved

WMI... Remote execution

Posted on 2005-03-25
14
Medium Priority
?
2,700 Views
Last Modified: 2012-06-27
HI, I want to execute an application on the remote machine using WMI in VC++ 6.0 !

can anybody help me please..
0
Comment
Question by:Dcom4CIT
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 6
14 Comments
 
LVL 22

Expert Comment

by:grg99
ID: 13629559
Hmmm,  kinda hard I think.

WMI is yet another layer of glop layered onto the OS.  Glop would rather be called by other glop, so most of the interfaces to WMI are from gloppy languages like VB and ASP.     A 5-minute scan of the net shows lots of VB and ASP examples, one C# example, but not a single C or C++ example.


Here's how to do it in VB:
http://www.freevbcode.com/ShowCode.asp?ID=1861

0
 
LVL 14

Expert Comment

by:wayside
ID: 13631660
What sort of application?

Programs started on remote machines through WMI are not allowed to open Windows.

I know I've got some code lying around somewhere do to this, let me dig it up...
0
 
LVL 14

Expert Comment

by:wayside
ID: 13631829
Ok, I found my code. It is based on some sample code I found on the internet a long time ago.

It is a pain to do this in c++, you basically have to

- get a wbem locator
- connect to the other machine
- get a win32_process object
- get an object for the parameters of the create function
- fill in the parameters
- execute the create method

All this takes 100+ lines of c++ code to accomplish, where you can to this in VB in like 3 lines.

Rather than post my code, which I can't really do anyway since it is owned by my company, here is the link to the sample code I learned from. It includes a nice little MFC dialog app to demonstrate its use.

http://www.developer.com/net/cplus/article.php/640511

It might be easier to have your program write out a small vb script, and use CreateProcess to run cscript with it. :)

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Dcom4CIT
ID: 13632016
i think the 100+ lines is too much as its too close to my project deadline - is it possible to give me sample vb script that will perform the same task..
0
 
LVL 14

Expert Comment

by:wayside
ID: 13632272
I'm not much on VB, but it would be something like this. Subsitute in the appropriate strings for strComputer, strUser, and strPassword, and strProgram.

Set objWMILocator = CreateObject("WbemScripting.SWbemLocator")

Set objWMIService = objWMILocator.ConnectServer( strComputer, "\\root\\cimv2:Win32_Process",  strUser , strPassword  )

Set objProcess = objWMIService.Get("Win32_Process")

err = objProcess.Create(strProgram, null, null, intProcessID)
 

The link I posted has sample code which wraps all the gory details in a class. All you'd have to do is add the class to your project, and add one line of code to create the process.
0
 

Author Comment

by:Dcom4CIT
ID: 13633197
Is there any chance of giving me sample code to create the process using the class in the link you posted...

Thanks in advance.
0
 
LVL 14

Accepted Solution

by:
wayside earned 2000 total points
ID: 13633419
Sure, it's pretty easy.

#include "cprocess.h"

// create an object to run a process
CProcess      process;

// set up the arguments
CString            szMachineName = "mymachine";    // name of computer where to run
CString            szCommandLine = "cmd /C dir > out.txt";  // put your command here
CString            szUserID = "user"; // user to login to the remote computer
CString            szPassword "password";  // password for the remote computer

if(FAILED(process.CreateNewProcess(szMachineName.AllocSysString(),
                                                      szUserID.AllocSysString(),
                                                      szPassword.AllocSysString(),
                                                      szCommandLine.AllocSysString())))
{
  AfxMessageBox("Failed to create new process!");
}


Add these files into your project, these are from the link:

/******  cprocess.h ******/
#include "wbemcli.h"
#include "comdef.h"

class CProcess
{

private:
      
      IWbemLocator                  *pLocator;
      IWbemServices                  *pService;
      IWbemClassObject            *pInParameters;
      IWbemClassObject            *pMethodObject;
      STDMETHODIMP                  ConnectToWbem(_bstr_t bstrMachine, _bstr_t bstrUserID, _bstr_t bstrPassword);

public:

      CProcess();
      ~CProcess();
      STDMETHODIMP CreateNewProcess(_bstr_t bstrMachine, _bstr_t bstrUserID, _bstr_t bstrPassword, _variant_t      vCommandLine);

};
/****** end of cprocess.h ******/

/****** cprocess.cpp ******/
#include "cprocess.h"

CProcess::CProcess()
{
      pInParameters = NULL;
      pMethodObject = NULL;
      pLocator = NULL;
      pService = NULL;
      CoInitialize(NULL);
}

CProcess::~CProcess()
{
      if (pInParameters) pInParameters->Release();
      if (pMethodObject) pMethodObject->Release();
      if (pLocator) pLocator->Release();
      if (pService) pService->Release();
      CoUninitialize();
}

STDMETHODIMP CProcess::CreateNewProcess(_bstr_t bstrMachine, _bstr_t bstrUserID, _bstr_t bstrPassword, _variant_t vCommandLine)
{
HRESULT                        hRes = 0;
IWbemClassObject      *pProcess = NULL;
IWbemClassObject      *pOutInst = NULL;
      
      if(FAILED(ConnectToWbem(bstrMachine, bstrUserID, bstrPassword)))
      {
            return E_FAIL;
      }

      hRes = pService->GetObject(_bstr_t(L"Win32_Process"), 0, NULL, &pProcess, NULL);
      if(FAILED(hRes))
      {
            return E_FAIL; // Program has failed.
      }

      hRes = pProcess->GetMethod(_bstr_t("Create"), 0, &pInParameters, NULL);
      if(FAILED(hRes))
      {
            return E_FAIL;
      }

      hRes = pInParameters->SpawnInstance(0, &pMethodObject);
      if(FAILED(hRes))
      {
            return E_FAIL;
      }

      hRes = pMethodObject->Put(_bstr_t(L"CommandLine"), 0, &vCommandLine, NULL);
      if(FAILED(hRes))
      {
            return E_FAIL;
      }

      hRes = pService->ExecMethod(_bstr_t(L"Win32_Process"), _bstr_t(L"Create"), 0, NULL, pMethodObject, &pOutInst, NULL);
      if(FAILED(hRes))
      {
            return E_FAIL;
      }      

pProcess->Release();
pOutInst->Release();
return S_OK;

}

STDMETHODIMP CProcess::ConnectToWbem(_bstr_t bstrMachine, _bstr_t bstrUserID, _bstr_t bstrPassword)
{
HRESULT            hRes = 0;
_bstr_t            szConnectionPath;

      hRes = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLocator);
 
      if (FAILED(hRes))
      {
            return E_FAIL; // Program has failed.
      }

      if(SysStringLen(bstrMachine) == 0)
      {
            szConnectionPath += "root\\cimv2"; //connect to local machine
      }
      else
      {
            szConnectionPath += "\\\\";//set up connection string for remote machine
            szConnectionPath += bstrMachine;
            szConnectionPath += "\\root\\cimv2";
      }

      //if no UserName and PassWord supplied use NTLM to grab users access token
      if((SysStringLen(bstrUserID) == 0) && (SysStringLen(bstrPassword) == 0))
      {
            hRes = pLocator->ConnectServer(      szConnectionPath, NULL, NULL, 0, NULL,      0, 0, &pService);
            if FAILED(hRes)
            {
                  return E_FAIL;         // Program has failed.
            }

      }
      else
      {
            // Connect to the Root\Default namespace with the current user.
            hRes = pLocator->ConnectServer(      szConnectionPath, bstrUserID, bstrPassword, 0, NULL, 0, 0, &pService);
            if FAILED(hRes)
            {
                  return E_FAIL;         // Program has failed.
            }
      }
      // Set the proxy so that impersonation of the client occurs.

      hRes = CoSetProxyBlanket(pService, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
      if(FAILED(hRes))
      {
            //user impersonation has failed!
            return E_FAIL;         // Program has failed.
      }
      return S_OK;

}

/****** end of cprocess.cpp ******/
0
 

Author Comment

by:Dcom4CIT
ID: 13639128
hi, thanks for the code.  it works perfect when i execute a program on the localhost
when i try to execute a program on a remote machine it  comes back with the following error - "failed to get GetObject"

thank in advance..

 hRes = pService->GetObject(_bstr_t(L"Win32_Process"),
                            0,
                            NULL,
                            &pProcess,
                            NULL);
 if(FAILED(hRes))
 {
       cout << "failed to get GetObject" << endl;
  return E_FAIL; // Program has failed
 }
0
 
LVL 14

Expert Comment

by:wayside
ID: 13641326
What is the value of hRes after the call? This contains the error code for the call.

The GetObject call can return one of the following errors (according to MSDN):

WBEM_E_ACCESS_DENIED The current user does not have permission to access the object.
WBEM_E_FAILED This indicates other unspecified errors.
WBEM_E_INVALID_CLASS The specified class does not exist.
WBEM_E_INVALID_PARAMETER An invalid parameter was specified.
WBEM_E_INVALID_OBJECT_PATH The specified path was invalid.
WBEM_E_NOT_FOUND The requested object could not be found.
WBEM_E_OUT_OF_MEMORY There was not enough memory to complete the operation.
WBEM_E_SHUTTING_DOWN Windows Management service was probably stopped and restarted. A new call to ConnectServer is needed.
WBEM_E_TRANSPORT_FAILURE This indicates the failure of the remote procedure call (RPC) link between the current process and Windows Management.
WBEM_S_NO_ERROR The call succeeded.

Or you can get some other COM error.

These error codes are defined in WbemCli.h in the Include directory of the platform SDK. Here are the ones listed above:

      WBEM_E_ACCESS_DENIED      = 0x80041003,
      WBEM_E_FAILED      = 0x80041001,
      WBEM_E_INVALID_CLASS      = 0x80041010,
      WBEM_E_INVALID_PARAMETER      = 0x80041008,
      WBEM_E_INVALID_OBJECT_PATH      = 0x8004103a,
      WBEM_E_NOT_FOUND      = 0x80041002,
      WBEM_E_OUT_OF_MEMORY      = 0x80041006,
      WBEM_E_SHUTTING_DOWN      = 0x80041033,
      WBEM_E_TRANSPORT_FAILURE      = 0x80041015,
      WBEM_S_NO_ERROR      = 0,



0
 

Author Comment

by:Dcom4CIT
ID: 13646879
It's returning the following error code   0x80041003 (access denied)
but i'm logging in as an administrator.. what do you think might be the problem

thanks.

0
 
LVL 14

Expert Comment

by:wayside
ID: 13647272
Are the user name and password for the local machine this code is running on, or for the remote machine where you are are trying to start a process?
0
 

Author Comment

by:Dcom4CIT
ID: 13647485
the username and password is correct for the remote machine that i'm trying to start the process..
0
 
LVL 14

Expert Comment

by:wayside
ID: 13649459
This kind of thing can be really tough to debug. There can be domain issues, account issues, impersonation issues, security privilege issues, registry issues, dcom issues...

Maybe this link will help you:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_troubleshooting.asp

Microsoft also has newsgroups devoted to WMI, where there are MVP's hanging out that really know this stuff. For example, here is something that may be relevant:

http://www.tech-archive.net/Archive/WinXP/microsoft.public.windowsxp.wmi/2004-12/0033.html

I'm not too versed with this level of system administration, I don't know what else to tell you.
0
 

Author Comment

by:Dcom4CIT
ID: 13650819
cheers thanks for your help..
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question