发表于:2005-11-24 10:12:00
32楼
第一种方法试用成功,真不容易。
源码如下:
//main.cpp
//************************************************************************************************
//浏览本地OPC服务器
//************************************************************************************************
#define _WIN32_DCOM // Needed in order to call CoInitializeEx()
#include <iostream>
#include <objbase.h>
#include <comdef.h>
#import "C:\WINNT\system32\OpcEnum.exe" no_namespace //根据OpcEnum.exe更改
#include "opcda.h"
#include "opcenum_i.c"
//--------------------------------------------------------------------------------------------------------------
//版本号----可以从规范中查到
static const CLSID CATID_OPCDAServer10 =
{ 0x63d5f430, 0xcfe4, 0x11d1, { 0xb2, 0xc8, 0x0, 0x60, 0x8, 0x3b, 0xa1, 0xfb } };
// {63D5F430-CFE4-11d1-B2C8-0060083BA1FB}
static const CLSID CATID_OPCDAServer20 =
{ 0x63d5f432, 0xcfe4, 0x11d1, { 0xb2, 0xc8, 0x0, 0x60, 0x8, 0x3b, 0xa1, 0xfb } };
// {63D5F432-CFE4-11d1-B2C8-0060083BA1FB}
//[uuid(CC603642-66D7-48f1-B69A-B625E73652D7)] interface CATID_OPCDAServer30
//--------------------------------------------------------------------------------------------------------------
void OPCServerList();
int main(int argc, char* argv[])
{
HRESULT hr;
int n_return = 0;
try
{
// Initialize COM
if(
FAILED( hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) )
)
_com_issue_error(hr);
}
catch(_com_error e)
{
std::cout << "ERROR(" << e.Error() << "): ";
if( e.Description().length() > 0)
std::cout << (TCHAR*)e.Description() << std::endl;
else
std::cout << e.ErrorMessage() << std::endl;
n_return = 1;
}
OPCServerList();
// Uninitialize COM
CoUninitialize();
return 0;
}
//使用CoCreateInstance
void OPCServerList()
{
CLSID clsid;
clsid = CLSID_OpcServerList; //在opcenum_i.c中定义
IOPCServerList *gpOPC = NULL;
DWORD clsctx;
clsctx = CLSCTX_LOCAL_SERVER; //本地服务
IID IIDOPCServerList=IID_IOPCServerList; //在opcenum_i.c中定义
// 创建OPC服务器的浏览器对象-----
HRESULT hr = CoCreateInstance(clsid, NULL, clsctx,IIDOPCServerList ,(void**)&gpOPC);
// 查询OPC DA 2.0 组件目录接口指针
CLSID catid;
catid=CATID_OPCDAServer20; //= CATID_OPCDAServer20; //OPC数据访问服务器2.0组件目录
IOPCEnumGUID *pEnumGUID;
hr = gpOPC->EnumClassesOfCategories( 1, &catid, 1, &catid, (IEnumGUID**)&pEnumGUID);
if(S_OK!=hr)
return;
//获得支持OPC DA2.0数据服务器的CLSID
unsigned long c;
while (S_OK == pEnumGUID->Next(1, &clsid, &c))
{
LPOLESTR pszProgID;
LPOLESTR pszUserType;
hr = gpOPC->GetClassDetails(&clsid, &pszProgID, &pszUserType);
//打印OPC数据服务器的有关信息
printf("ProgID = %ls, UserType = %ls\n", pszProgID, pszUserType);
CoTaskMemFree(pszProgID);
CoTaskMemFree(pszUserType);
}
//释放接口
if(gpOPC)
gpOPC->Release();
}
//opcenum_i.c
#ifdef __cplusplus
extern "C"{
#endif
#ifndef __IID_DEFINED__
#define __IID_DEFINED__
typedef struct _IID
{
unsigned long x;
unsigned short s1;
unsigned short s2;
unsigned char c[8];
} IID;
#endif // __IID_DEFINED__
#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif // CLSID_DEFINED
const IID LIBID_OpcEnumLib = {0x13486D43,0x4821,0x11D2,{0xA4,0x94,0x3C,0xB3,0x06,0xC1,0x00,0x00}};
const IID IID_IOPCServerList2 = {0x9DD0B56C,0xAD9E,0x43EE,{0x83,0x05,0x48,0x7F,0x31,0x88,0xBF,0x7A}};
const IID IID_IOPCEnumGUID = {0x55C382C8,0x21C7,0x4E88,{0x96,0xC1,0xBE,0xCF,0xB1,0xE3,0xF4,0x83}};
const IID IID_IOPCServerList = {0x13486D50,0x4821,0x11D2,{0xA4,0x94,0x3C,0xB3,0x06,0xC1,0x00,0x00}};
const IID IID_IEnumGUID = {0x0002E000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
const CLSID CLSID_OpcServerList = {0x13486D51,0x4821,0x11D2,{0xA4,0x94,0x3C,0xB3,0x06,0xC1,0x00,0x00}};
#ifdef __cplusplus
}
#endif