指定server地址获取Opc server 点击:2731 | 回复:16



hopefullin

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:33帖 | 27回
  • 年度积分:0
  • 历史总积分:137
  • 注册:2004年12月09日
发表于:2008-01-24 12:35:00
楼主
请问有谁通过指定一个具体的Ip地址连接到opc server上
这部分代码涉及到网络节点的枚举,我不是很明白
哪位高人做过,指教一下,多谢了!(vc编写)



三脚猫

  • 精华:0帖
  • 求助:0帖
  • 帖子:180帖 | 1598回
  • 年度积分:0
  • 历史总积分:1097
  • 注册:2004年7月08日
发表于:2008-01-24 12:44:00
1楼
这称远程访问OPC SERVER,我搞过数采项目(这项目
弄得我下岗,才改行仪表自控),通过IP地址远程访问,
DCOM服务器的远程支持用WINDOWS2000较好.
网络节点用不着枚举,让用户自已指定地址.

hopefullin

  • 精华:0帖
  • 求助:0帖
  • 帖子:33帖 | 27回
  • 年度积分:0
  • 历史总积分:137
  • 注册:2004年12月09日
发表于:2008-01-24 12:51:00
2楼
我现在就想通过下拉列表框让用户指定地址,然后连接到具体的opc server上,但是这之间的实现不大会弄,高手指点一下!

三脚猫

  • 精华:0帖
  • 求助:0帖
  • 帖子:180帖 | 1598回
  • 年度积分:0
  • 历史总积分:1097
  • 注册:2004年7月08日
发表于:2008-01-24 12:54:00
3楼
一般工控的人知道OPC的用途/方法,但怎样编程没几个人懂,
很烦锁,这是OPC的失败之处.
我会C++BUILDER编程在客户端同步访问OPC SERVER会,
但不会异步访问(实在太费事);

三脚猫

  • 精华:0帖
  • 求助:0帖
  • 帖子:180帖 | 1598回
  • 年度积分:0
  • 历史总积分:1097
  • 注册:2004年7月08日
发表于:2008-01-24 12:56:00
4楼
下拉列表框让用户指定地址,这与OPC无关了,

hopefullin

  • 精华:0帖
  • 求助:0帖
  • 帖子:33帖 | 27回
  • 年度积分:0
  • 历史总积分:137
  • 注册:2004年12月09日
发表于:2008-01-24 12:58:00
5楼
不知道你有没有用过ICatInformation?

三脚猫

  • 精华:0帖
  • 求助:0帖
  • 帖子:180帖 | 1598回
  • 年度积分:0
  • 历史总积分:1097
  • 注册:2004年7月08日
发表于:2008-01-24 12:58:00
6楼
客户端与服务端在同一网段才能枚举,否则,无穷的IP地址如何枚举;

三脚猫

  • 精华:0帖
  • 求助:0帖
  • 帖子:180帖 | 1598回
  • 年度积分:0
  • 历史总积分:1097
  • 注册:2004年7月08日
发表于:2008-01-24 13:02:00
7楼
其实用不着枚举OPC服务端的地址(用的机有两个
不同网段IP地址);
一般,一个项目的OPC服务器地址都是死的,预先设好的,
用不着枚举;
我所见到的OPC客户端软件,没有枚举IP地址的

三脚猫

  • 精华:0帖
  • 求助:0帖
  • 帖子:180帖 | 1598回
  • 年度积分:0
  • 历史总积分:1097
  • 注册:2004年7月08日
发表于:2008-01-24 13:04:00
8楼
ICatInformation是接口了,没用过;
OPC的东西太多,我只对用到的部分感兴趣,
昨天,对S7-200的OPC Server :PC Access1.0,
试了一下,很简单.

三脚猫

  • 精华:0帖
  • 求助:0帖
  • 帖子:180帖 | 1598回
  • 年度积分:0
  • 历史总积分:1097
  • 注册:2004年7月08日
发表于:2008-01-24 13:10:00
9楼
你是想枚举IP地址,还是枚举指定地址的N个OPC Server?

hopefullin

  • 精华:0帖
  • 求助:0帖
  • 帖子:33帖 | 27回
  • 年度积分:0
  • 历史总积分:137
  • 注册:2004年12月09日
发表于:2008-01-24 13:26:00
10楼
枚举指定地址的N个opc server
用ICatInformation,不知道该怎么用

yu2018

  • 精华:0帖
  • 求助:0帖
  • 帖子:2帖 | 40回
  • 年度积分:0
  • 历史总积分:82
  • 注册:2002年7月25日
发表于:2008-01-24 13:45:00
11楼
枚举计算机,主要用到这三个函数,实现比较简单,网上应该可以查到
1、WNetOpenEnum
2、WNetEnumResource
3、WNetCloseEnum

枚举远程OPC服务器也有两种办法:
1 枚举注册表
 // search the registry for OPC entries
   HKEY hk = HKEY_CLASSES_ROOT;
   if( node )
   {
      DWORD dwR = RegConnectRegistry ((LPTSTR)node, HKEY_CLASSES_ROOT, &hk);
      if( dwR != ERROR_SUCCESS )
         return FALSE;
   }

   TCHAR key[MAX_KEYLEN];
   for( int index=0; RegEnumKey(hk, index, key, MAX_KEYLEN)==ERROR_SUCCESS; index++)
   {
      HKEY hProgID;
      TCHAR dummy[MAX_KEYLEN];
      if(RegOpenKey(hk, key, &hProgID )==ERROR_SUCCESS )
      {
         LONG size=MAX_KEYLEN;
         if(RegQueryValue(hProgID, _T("OPC"), dummy, &size)==ERROR_SUCCESS )
         {
            TCHAR desc[MAX_KEYLEN];
            size=MAX_KEYLEN;
            RegQueryValue(hk, key, desc, &size);
            //得到key;
         }
         RegCloseKey( hProgID );
      }
   }

2、通过OPCNUM
IOPCServerList *gpOPC;
HRESULT hr, hr2;
IEnumGUID *pEnumGUID;
CLSID catid, clsid;
unsigned long c;
LPOLESTR pszProgID, pszUserType;

// create the enumerator object
gpOPC = CreateServerEnumerator(pathname);
if (gpOPC == NULL)
{
DoErrorMsg ( 0, "Failed to Execute OPCENUM");
// revert to search of Registry if OPCENUM fails to execute
return (GetServerListFromRegistry());
}

// use category id's to enumerate server list
catid = CATID_OPCDAServer20;
gpOPC->EnumClassesOfCategories(1, &catid, 
1, &catid, &pEnumGUID); 

if (pEnumGUID != NULL)
{
while (SUCCEEDED(hr = pEnumGUID->Next(1, &clsid, &c)))
{
if (!ValidCLSID(clsid))
break;
// add server name to list
//得到 clsid;
hr2 = gpOPC->GetClassDetails(clsid, &pszProgID, &pszUserType);
if (FAILED(hr2))
//错误处理
else
{
//得到pszProgID;
CoTaskMemFree(pszProgID);
CoTaskMemFree(pszUserType);
}

}
pEnumGUID->Release();
}
gpOPC->Release();

以上仅供参考

hopefullin

  • 精华:0帖
  • 求助:0帖
  • 帖子:33帖 | 27回
  • 年度积分:0
  • 历史总积分:137
  • 注册:2004年12月09日
发表于:2008-01-24 14:15:00
12楼
请问你程序里的pathname是什么路径名?谢谢

yu2018

  • 精华:0帖
  • 求助:0帖
  • 帖子:2帖 | 40回
  • 年度积分:0
  • 历史总积分:82
  • 注册:2002年7月25日
发表于:2008-01-24 14:21:00
13楼
IP或主机名

kking

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 116回
  • 年度积分:0
  • 历史总积分:134
  • 注册:2002年7月09日
发表于:2008-01-24 15:30:00
14楼
这是OPC客户程序开发的一部分,确实有必要做的话建议静下心来去看看OPC DA规范,了解COM编程。在这里问效果恐怕一般。另外网上好像有OPC客户程序的例程。

三脚猫

  • 精华:0帖
  • 求助:0帖
  • 帖子:180帖 | 1598回
  • 年度积分:0
  • 历史总积分:1097
  • 注册:2004年7月08日
发表于:2008-01-24 22:43:00
15楼
这是我用C++BUILDER展开IP地址显示N个OPC SERVERS的片段:

void __fastcall TFrame1::TreeView1Expanding(TObject *Sender,
      TTreeNode *Node, bool &AllowExpansion)
{
      int level=Node->Level;
       Node->DeleteChildren();    //展开前先清除所有子节点
       switch(level)
         {
           case 0:               // 展开0层
                  {
                     DataType *data=(DataType *)Node->Data;
                     WideString ip=*data->Ref;
                     TCOMIOPCAutoServer opc=CoOPCServer::Create();
                     OleVariant sv=(OleVariant)opc->GetOPCServers((OleVariant)ip.c_bstr());
                     int i0=sv.ArrayLowBound();
                     int i1=sv.ArrayHighBound();
                     for (int i=i0;i<=i1;i++)
                      {
                        WideString opc1=(BSTR)sv.GetElement(i);
                        TTreeNode *node=TreeView1->Items->AddChild(Node,String(opc1));
                        node->Data=NULL;   // 指向实例
                        node->HasChildren=true;
                      }
                     opc.Release();
                  }
                  break;

三脚猫

  • 精华:0帖
  • 求助:0帖
  • 帖子:180帖 | 1598回
  • 年度积分:0
  • 历史总积分:1097
  • 注册:2004年7月08日
发表于:2008-01-25 14:31:00
16楼
TCOMIOPCAutoServer opc=CoOPCServer::Create();
                     OleVariant sv=(OleVariant)opc->GetOPCServers((OleVariant)ip.c_bstr());
                     int i0=sv.ArrayLowBound();
                     int i1=sv.ArrayHighBound();

热门招聘
相关主题

官方公众号

智造工程师