http://www.vckbase.com/index.php/wv/1524
前言:对于分布式组件,在创建组件过程中常因权限问题导致出现“拒绝访问”,无法创建组件对象或使用接口。本人水平有限,只能谈些个人经验和体会,希望能抛砖引玉!
有两种方法能使得DCOM组件顺利创建和使用:
一、使用DCOMCNFG工具在服务器及客户机上对组件进行设置,这在《COM技术内幕》中有详细说明,使用这种方法要在两种情形下使用:
1、服务器与客户机必须在同一个域中且客户机要登录域(这种环境我没试过,因为我的局域网中只用工作组没建域)
2、服务器与客户机处于工作组环境下,则客户机的当前登录用户名及密码在服务器上必须有同样的用户存在!
我不倾向于用以上的方法,但有一点要提一下,就是服务端组件注册后使用DCOMCNFG来设置DCOM组件属性时,有时会只提示“操作成功完成”,而不能正常设置,这是因为注册表登记信息不全造成的,需要手工在HKEY_CLASSES_ROOT\AppID\下手动添加组件的CLSID
二、在客户端程序中设定访问使用组件的用户名及密码
1 CoInitialize(NULL);//初始化COM环境 2 HRESULT hr; 3 IRW* pIRW = NULL ;//定义接口指针 4 COSERVERINFO ServerInfo;//创建服务器信息结构 5 COAUTHINFO athn; 6 ZeroMemory(&athn, sizeof(COAUTHINFO)); 7 COAUTHIDENTITY author_id; 8 ZeroMemory(&author_id, sizeof(COAUTHIDENTITY)); 9 10 char* pszName= new char[255]; 11 char* pszDomain = new char[255]; 12 char* pszPassword = new char[255]; 13 14 pszName = "name";//指定用户名,此用户必须是服务器上有的用户 15 pszDomain= ""; 16 pszPassword = "password";//密码 17 18 author_id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI ; 19 author_id.User = reinterpret_cast(pszName); 20 author_id.UserLength = strlen(pszName); 21 author_id.Domain = reinterpret_cast(pszDomain); 22 author_id.DomainLength = strlen(pszDomain); 23 author_id.Password = reinterpret_cast(pszPassword); 24 author_id.PasswordLength = strlen(pszPassword); 25 26 athn.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CONNECT;//网上很多例子用RPC_C_AUTHN_LEVEL_NONE其实不能用,否则不能指定用户名密码 27 athn.dwAuthnSvc = RPC_C_AUTHN_WINNT; 28 athn.dwAuthzSvc = RPC_C_AUTHZ_NONE; 29 athn.dwCapabilities = EOAC_NONE; 30 athn.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE; 31 athn.pAuthIdentityData = &author_id; 32 athn.pwszServerPrincName = NULL; 33 34 MULTI_QI MultiQI; 35 ZeroMemory(&ServerInfo, sizeof(COSERVERINFO)); 36 ServerInfo.pwszName = L"192.168.0.1";//服务器地址 37 ServerInfo.pAuthInfo = &athn; 38 ServerInfo.dwReserved1 = 0; 39 ServerInfo.dwReserved2 = 0; 40 MultiQI.hr = NOERROR; 41 MultiQI.pItf = NULL; 42 MultiQI.pIID = &IID_IRW; 43 44 hr = CoCreateInstanceEx(CLSID_inirw, 45 NULL, 46 CLSCTX_REMOTE_SERVER, 47 &ServerInfo, 48 1, 49 &MultiQI) ; 50 if (SUCCEEDED(hr)) 51 { 52 pIRW=(IRW*)MultiQI.pItf; 53 hr=CoSetProxyBlanket(pIRW,athn.dwAuthnSvc, 54 athn.dwAuthzSvc, 55 NULL, 56 athn.dwAuthnLevel, 57 athn.dwImpersonationLevel, 58 &author_id, 59 EOAC_NONE);//用于设置接口的访问安全设置,如果不用此函数设置接口则使用接口时又会出现“拒绝访问” 60 hr=pIRW->ReadIni(); 61 62 ((IRW*)MultiQI.pItf)->Release(); 63 } 64 CoUninitialize();
三、结束语
本人水平有限,不能深入讲解,希望对大家有帮助!