如何在C语言中使用WMI获取Windows中所有正在运行的进程的命令行参数?
最佳答案
您必须使用 Win32_Process WMI 类并检查 CommandLine 属性的值,另请参阅本文 How do I get the command line of another process这解释了字符串是 ...只是“预初始化变量”,一个进程原则上可以(许多人在实践中这样做,尽管通常是无意中)写入保存命令行的内存
更新
#define _WIN32_WINNT 0x0400
#define _WIN32_DCOM
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <wbemidl.h>
void _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = 0;
IWbemLocator *WbemLocator = NULL;
IWbemServices *WbemServices = NULL;
IEnumWbemClassObject *EnumWbem = NULL;
//initializate the Windows security
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
hr = CoCreateInstance(&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (LPVOID *) &WbemLocator);
//connect to the WMI
hr = WbemLocator->lpVtbl->ConnectServer(WbemLocator, L"ROOT\\CIMV2", NULL, NULL, NULL, 0, NULL, NULL, &WbemServices);
//Run the WQL Query
hr = WbemServices->lpVtbl->ExecQuery(WbemServices, L"WQL", L"SELECT ProcessId,CommandLine FROM Win32_Process", WBEM_FLAG_FORWARD_ONLY, NULL, &EnumWbem);
// Iterate over the enumerator
if (EnumWbem != NULL) {
IWbemClassObject *result = NULL;
ULONG returnedCount = 0;
while((hr = EnumWbem->lpVtbl->Next(EnumWbem, WBEM_INFINITE, 1, &result, &returnedCount)) == S_OK) {
VARIANT ProcessId;
VARIANT CommandLine;
// access the properties
hr = result->lpVtbl->Get(result, L"ProcessId", 0, &ProcessId, 0, 0);
hr = result->lpVtbl->Get(result, L"CommandLine", 0, &CommandLine, 0, 0);
if (!(CommandLine.vt==VT_NULL))
wprintf(L"%u %s \r\n", ProcessId.uintVal, CommandLine.bstrVal);
result->lpVtbl->Release(result);
}
}
// Release the resources
EnumWbem->lpVtbl->Release(EnumWbem);
WbemServices->lpVtbl->Release(WbemServices);
WbemLocator->lpVtbl->Release(WbemLocator);
CoUninitialize();
getchar();
}
#pragma hdrstop
#include <iostream>
using namespace std;
#include <wbemcli.h>
#include <comdef.h>
//CREDENTIAL structure
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788%28v=vs.85%29.aspx
#define CRED_MAX_USERNAME_LENGTH 513
#define CRED_MAX_CREDENTIAL_BLOB_SIZE 512
#define CREDUI_MAX_USERNAME_LENGTH CRED_MAX_USERNAME_LENGTH
#define CREDUI_MAX_PASSWORD_LENGTH (CRED_MAX_CREDENTIAL_BLOB_SIZE / 2)
// The Win32_Process class represents a sequence of events on a Win32 system. Any sequence consisting of the interaction of one or more processors or interpreters, some executable code, and a set of inputs, is a descendent (or member) of this class.
// Example: A client application running on a Win32 system.
#pragma argsused
int main(int argc, char* argv[])
{
wchar_t pszName[CREDUI_MAX_USERNAME_LENGTH+1] = L"user";
wchar_t pszPwd[CREDUI_MAX_PASSWORD_LENGTH+1] = L"password";
BSTR strNetworkResource;
//To use a WMI remote connection set localconn to false and configure the values of the pszName, pszPwd and the name of the remote machine in strNetworkResource
bool localconn = true;
strNetworkResource = localconn ? L"\\\\.\\root\\CIMV2" : L"\\\\remote--machine\\root\\CIMV2";
COAUTHIDENTITY *userAcct = NULL ;
COAUTHIDENTITY authIdent;
// Initialize COM. ------------------------------------------
HRESULT hres;
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Set general COM security levels --------------------------
if (localconn)
hres = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
else
hres = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IDENTIFY, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
if (FAILED(hres))
{
cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Obtain the initial locator to WMI -------------------------
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hres))
{
cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices *pSvc = NULL;
if (localconn)
hres = pLoc->ConnectServer(
strNetworkResource, // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (e.g. Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
else
hres = pLoc->ConnectServer(
strNetworkResource, // Object path of WMI namespace
pszName, // User name
pszPwd, // User password
NULL, // Locale
NULL, // Security flags
NULL, // Authority
NULL, // Context object
&pSvc // IWbemServices proxy
);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
cout << "Connected to root\\CIMV2 WMI namespace" << endl;
// Set security levels on the proxy -------------------------
if (localconn)
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
else
{
// Create COAUTHIDENTITY that can be used for setting security on proxy
memset(&authIdent, 0, sizeof(COAUTHIDENTITY));
authIdent.PasswordLength = wcslen (pszPwd);
authIdent.Password = (USHORT*)pszPwd;
authIdent.User = (USHORT*)pszName;
authIdent.UserLength = wcslen(pszName);
authIdent.Domain = 0;
authIdent.DomainLength = 0;
authIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
userAcct = &authIdent;
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_DEFAULT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_DEFAULT, // RPC_C_AUTHZ_xxx
COLE_DEFAULT_PRINCIPAL, // Server principal name
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
userAcct, // client identity
EOAC_NONE // proxy capabilities
);
}
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Use the IWbemServices pointer to make requests of WMI ----
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery( L"WQL", L"SELECT CommandLine,ProcessId FROM Win32_Process",
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
if (FAILED(hres))
{
cout << "ExecQuery failed" << " Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Secure the enumerator proxy
if (!localconn)
{
hres = CoSetProxyBlanket(
pEnumerator, // Indicates the proxy to set
RPC_C_AUTHN_DEFAULT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_DEFAULT, // RPC_C_AUTHZ_xxx
COLE_DEFAULT_PRINCIPAL, // Server principal name
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
userAcct, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
cout << "Could not set proxy blanket on enumerator. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
}
// Get the data from the WQL sentence
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if(0 == uReturn || FAILED(hr))
break;
VARIANT vtProp;
hr = pclsObj->Get(L"CommandLine", 0, &vtProp, 0, 0);// String
if (!FAILED(hr))
{
if ((vtProp.vt==VT_NULL) || (vtProp.vt==VT_EMPTY))
wcout << "CommandLine : " << ((vtProp.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
else
if ((vtProp.vt & VT_ARRAY))
wcout << "CommandLine : " << "Array types not supported (yet)" << endl;
else
wcout << "CommandLine : " << vtProp.bstrVal << endl;
}
VariantClear(&vtProp);
hr = pclsObj->Get(L"ProcessId", 0, &vtProp, 0, 0);// Uint32
if (!FAILED(hr))
{
if ((vtProp.vt==VT_NULL) || (vtProp.vt==VT_EMPTY))
wcout << "ProcessId : " << ((vtProp.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
else
if ((vtProp.vt & VT_ARRAY))
wcout << "ProcessId : " << "Array types not supported (yet)" << endl;
else
wcout << "ProcessId : " << vtProp.uintVal << endl;
}
VariantClear(&vtProp);
pclsObj->Release();
pclsObj=NULL;
}
// Cleanup
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
if (pclsObj!=NULL)
pclsObj->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 0; // Program successfully completed.
}
关于c - 在 Windows 中获取另一个进程的命令行参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25889425/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"