wmi读取硬盘物理序列号 exe中正常 dll中无法读出

qq_25029325 2016-05-20 10:40:36
下面的代码在exe中执行,能正确的用wmi读取到硬件信息,但是放到dll中就不行了,请高手们指点,如果分数不够,还可以加。

//--------------------------------------------------------------------------
#include <comdef.h>
#include <wbemidl.h>

#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;

char *AllWmiClasses[] =
{
"Win32_1394Controller" ,
"Win32_BaseBoard" ,
"Win32_Battery" ,
"Win32_BIOS" ,
"Win32_Bus" ,
"Win32_CacheMemory" ,
"Win32_CDROMDrive" ,
"Win32_CurrentProbe" ,
"Win32_DesktopMonitor" ,
"Win32_DeviceMemoryAddress" ,
"Win32_DiskDrive" ,
"Win32_DisplayConfiguration" ,
"Win32_DisplayControllerConfiguration",
"Win32_DMAChannel" ,
"Win32_Fan" ,
"Win32_FloppyController" ,
"Win32_FloppyDrive" ,
"Win32_HeatPipe" ,
"Win32_IDEController" ,
"Win32_InfraredDevice" ,
"Win32_IRQResource" ,
"Win32_Keyboard" ,
"Win32_MemoryArray" ,
"Win32_MemoryDevice" ,
"Win32_MotherboardDevice" ,
"Win32_NetworkAdapter" ,
"Win32_NetworkAdapterConfiguration" ,
"Win32_OnBoardDevice" ,
"Win32_ParallelPort" ,
"Win32_PCMCIAController" ,
"Win32_PhysicalMemory" ,
"Win32_PhysicalMemoryArray" ,
"Win32_PnPEntity" ,
"Win32_PointingDevice" ,
"Win32_PortableBattery" ,
"Win32_PortConnector" ,
"Win32_PortResource" ,
"Win32_POTSModem" ,
"Win32_PowerManagementEvent" ,
"Win32_Printer" ,
"Win32_PrinterConfiguration" ,
"Win32_PrintJob" ,
"Win32_Processor" ,
"Win32_Refrigeration" ,
"Win32_SerialPort" ,
"Win32_SerialPortConfiguration" ,
"Win32_SMBIOSMemory" ,
"Win32_SoundDevice" ,
"Win32_SystemEnclosure" ,
"Win32_SystemMemoryResource" ,
"Win32_SystemSlot" ,
"Win32_TapeDrive" ,
"Win32_TemperatureProbe" ,
"Win32_UninterruptiblePowerSupply" ,
"Win32_USBController" ,
"Win32_VideoConfiguration" ,
"Win32_VideoController" ,
"Win32_VoltageProbe" ,
NULL
};

void GetWmiInfo(TStrings *lpList, WideString wsClass)
{
IWbemLocator *pWbemLocator = NULL;
if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
{
IWbemServices *pWbemServices = NULL;
UnicodeString wsNamespace = (L"root\\cimv2");
if(pWbemLocator->ConnectServer(wsNamespace.c_str(), NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
{
IEnumWbemClassObject *pEnumClassObject = NULL;
UnicodeString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
if(pWbemServices->ExecQuery(wsWQL.c_str(), wsQuery.c_str(), WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
{
IWbemClassObject *pClassObject = NULL;
ULONG uCount = 1, uReturned;
if(pEnumClassObject->Reset() == S_OK)
{ //MessageBox(NULL,L"enter1",L"aabb",MB_OK);
int iEnumIdx = 0;
while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
{
lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
//MessageBox(NULL,L"enter2",L"aab",MB_OK);
SAFEARRAY *pvNames = NULL;
if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
{
long vbl, vbu;
SafeArrayGetLBound(pvNames, 1, &vbl);
SafeArrayGetUBound(pvNames, 1, &vbu);
for(long idx=vbl; idx<=vbu; idx++)
{
long aidx = idx;
wchar_t *wsName = 0;
VARIANT vValue;
VariantInit(&vValue);
SafeArrayGetElement(pvNames, &aidx, &wsName);

BSTR bs = SysAllocString(wsName);
HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
SysFreeString(bs);

if(hRes == S_OK)
{
AnsiString s;
Variant v = *(Variant*)&vValue;
if(v.IsArray())
{
for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)
{
Variant a = v.GetElement(i);
if(!s.IsEmpty())
s+=", ";
s+=VarToStr(a);
}
}
else
{
s = VarToStr(v);
}
lpList->Add(AnsiString(wsName)+"="+s);
}

VariantClear(&vValue);
SysFreeString(wsName);
}
}
if(pvNames)SafeArrayDestroy(pvNames);
iEnumIdx++;
}
} else MessageBox(NULL,L"err4",L"aa",MB_OK);
if(pClassObject)pClassObject->Release();
} else MessageBox(NULL,L"err3",L"aa",MB_OK);
if(pEnumClassObject)pEnumClassObject->Release();
} else MessageBox(NULL,L"err2",L"aa",MB_OK);
if(pWbemServices)pWbemServices->Release();
}else MessageBox(NULL,L"err1",L"aa",MB_OK);
if(pWbemLocator)pWbemLocator->Release();
}

UnicodeString __fastcall Pub_getHD0(String id,bool toMD5) {
CoInitialize(NULL);
HRESULT hr=CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
if (hr!= S_OK && hr!=RPC_E_TOO_LATE) {
//ShowMessage("无法获取权限!"); Application->Terminate();
//gPermission=1;//只能读取1次,否则会出错
CoUninitialize(); return "NoPermission";
}

TStringList*st1=new TStringList;
GetWmiInfo(st1, "Win32_DiskDrive"); //"Win32_PhysicalMedia");//
CoUninitialize();

str=st1->Text; MessageBox(NULL,String(str).c_str(),L"aa",MB_OK);
return str;
}
...全文
3047 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
o330820350 2016-09-07
  • 打赏
  • 举报
回复
CoInitialize(NULL);//初始化COM套件 CoUninitialize();//释放COM套件 使用com组件前后需要调用com组件初始化和释放;尝试在动态库中加入这两个函数试试
  • 打赏
  • 举报
回复
“是在外汇软件的指标脚本中调用的”有可能是用户权限的问题,运行脚本的用户很可能是一个内置的低权限帐户,你自己写个exe调用此dll看是否成功。
FASM_FASM 2016-05-26
  • 打赏
  • 举报
回复
引用 15 楼 qq_25029325 的回复:
您好,代码是没问题的,因为在.exe中执行这段代码是正确的; 问题就在于,为什么在dll中不行,是不是dll中不支持wmi?
我没说你的代码有问题啊,问题是程序运行存在各种各样的环境。所以有兼容性之说,你的代码在DLL环境下不返回预期值,必定是某一步或多步调用失败了。你不调试怎莫能知道那?
qq_25029325 2016-05-26
  • 打赏
  • 举报
回复
您好,代码是没问题的,因为在.exe中执行这段代码是正确的; 问题就在于,为什么在dll中不行,是不是dll中不支持wmi?
FASM_FASM 2016-05-25
  • 打赏
  • 举报
回复
哦,抱歉我没看到下面的,确实调用了CoInitialize和CoInitializeSecurity并判断了返回状态。 这个估计你要单步或log输出一下,上面GetWmiInfo中每步调用的返回信息才能判断哪里出现问题了。
ccrun.com 2016-05-24
  • 打赏
  • 举报
回复
myGetHD 函数中不要直接返回 UnicodeString 对象的 .c_str() 数据,自己定义一个WCHAR的数组,将结果复制到这个缓冲里,再返回试试。
qq_25029325 2016-05-24
  • 打赏
  • 举报
回复
您好,和这个没关系,我MessageBox(NULL,String(str).c_str(),L"aa",MB_OK); 的值都是空的,根本没取到值。
qq_25029325 2016-05-24
  • 打赏
  • 举报
回复
您好,上面的代码中有用到CoInitialize(NULL);,不知道您所说的“CoInitInstance”是不是一回事,请指教,谢谢了; 感觉用wmi的通用性多好,直接访问设备,好像有些硬盘会读不出来,或者需要管理员权限。
FASM_FASM 2016-05-22
  • 打赏
  • 举报
回复
其实感觉用Wmi又费事又磨叽,还不如直接自己去访问磁盘设备来的简洁、方便。
FASM_FASM 2016-05-22
  • 打赏
  • 举报
回复
你既然用到了CoCreateInstance,但没看你在DLL初始化时调用CoInitInstance来初始化COM环境啊,当然这个动作放在主调的exe程序中也行。
qq_25029325 2016-05-21
  • 打赏
  • 举报
回复
不能沉了,我顶
qq_25029325 2016-05-20
  • 打赏
  • 举报
回复
这有关系吗? 代码在exe中执行,能正确的用wmi读取到硬件信息,只是放到dll中就不行了
xiaoxue1999 2016-05-20
  • 打赏
  • 举报
回复
看看你的操作系统是不是64位的,如果是,改用64位平台试试
qq_25029325 2016-05-20
  • 打赏
  • 举报
回复
调用是成功的,可以得到dll中的弹窗,只是弹窗是空的。
qq_25029325 2016-05-20
  • 打赏
  • 举报
回复
您好,请越过基本语法,谢谢
xiaoxue1999 2016-05-20
  • 打赏
  • 举报
回复
首先str这个字符串没有声明,看能不能通过
qq_25029325 2016-05-20
  • 打赏
  • 举报
回复
您好,是在外汇软件的指标脚本中调用的; 这个dll的封装接口如下: #include <vcl.h> //#include "Descrypt.h" //#include <windows.h> #pragma hdrstop #pragma argsused #define MT4_EXPFUNC __declspec(dllexport) extern "C" MT4_EXPFUNC wchar_t* __stdcall myGetHD(); int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { return 1; } String mHD=""; MT4_EXPFUNC wchar_t* __stdcall myGetHD() { mHD=Pub_getHD0("",false); return mHD.c_str(); }
xiaoxue1999 2016-05-20
  • 打赏
  • 举报
回复
请问怎么调用的?

703

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder ActiveX/COM/DCOM
社区管理员
  • ActiveX/COM/DCOM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧