简体   繁体   English

如何在没有IDL或后期绑定调用远程处理方法的情况下访问CORBA接口

[英]How to access CORBA interface without IDL or late-bound invoke remoting methods

We have been using an SAP "COM License Bridge" to access their license server and query the hardware key of a system programatically (to reuse with out own licensing). 我们一直在使用SAP“COM许可证桥”来访问其许可证服务器并以编程方式查询系统的硬件密钥(以重用自己的许可证)。 This worked fine on SAP Business one Versions 2007A, 2007B and 8.8, but in 8.81 they seem to have updated their CORBA interface without updating the COM wrapper because we now get memory exceptions when attempting to call the GetHardwareKey function. 这在SAP Business One版本2007A,2007B和8.8上运行良好,但是在8.81中它们似乎更新了它们的CORBA接口而没有更新COM包装器,因为我们现在在尝试调用GetHardwareKey函数时获得了内存异常。

So I downloaded IIOP.NET and started trying to write my own interface. 所以我下载了IIOP.NET并开始尝试编写自己的界面。 I never liked that COM wrapper anyway. 无论如何我从来都不喜欢COM包装器。 But I encountered my old nemesis of .NET remoting -- the inability to invoke a remote method without having a common interface defined in both the server and the client. 但是我遇到了我的旧远程.NET远程控制 - 无法在服务器和客户端都没有定义公共接口的情况下调用远程方法。 I tried using the IDL to CLS compiler included with IIOP.NET, but I continue to get errors about the interface beign incompatible (SAP did not provide an IDL file). 我尝试使用IIOP.NET附带的IDL到CLS编译器,但我继续得到关于接口beign不兼容的错误(SAP没有提供IDL文件)。 I don't know how IIOP and CORBA determine whether an interface is compatible. 我不知道IIOP和CORBA如何确定接口是否兼容。 But I even tried debugging into IIOP.NET code and forcing it to execute the method despite the incompatibility, but received an empty string back instead of the hardware key I wanted. 但我甚至尝试调试IIOP.NET代码并强制它执行该方法,尽管不兼容,但收到一个空字符串而不是我想要的硬件密钥。

My next step is to try to implement a fake license server and examine the requests coming in from the production client in the hopes of identifying what they should look like, but I'm not counting on much success considering the difficulty I've had in peering into the innards of .NET remoting already. 我的下一步是尝试实现虚假的许可证服务器并检查来自生产客户端的请求,以期确定它们应该是什么样子,但考虑到我遇到的困难,我并不指望取得多大的成功。深入了解.NET远程的内容。

My real problem is how to get or generate the SAP Business One hardware key, but questions stemming from that include: 我真正的问题是如何获取或生成SAP Business One硬件密钥,但由此产生的问题包括:

  1. How do I reflect on or query information about a CORBA interface? 如何反思或查询有关CORBA接口的信息? I can use the list method of the NamingContext class to retrieve a list of available objects, but I don't see if there is a way to query available methods on an object. 我可以使用NamingContext类的list方法来检索可用对象的列表,但是我不知道是否有办法查询对象上的可用方法。
  2. Can I dynamically invoke .NET remoting methods without having an interface? 我可以在没有接口的情况下动态调用.NET远程处理方法吗? I see there's something called DII for dynamically invoking CORBA, but I don't see how to use it from IIOP.NET. 我看到有一种叫做DII的东西用于动态调用CORBA,但是我没有看到如何在IIOP.NET中使用它。
  3. Can I invoke .NET remoting methods with just a delegate or incomplete interface? 我可以仅使用委托或不完整的接口来调用.NET远程处理方法吗? I tried using the dynamic keyword, but it was unable to invoke a method on my MarshalByRef remote object... I think it said the method didn't exist on my MarshalByRef instance or something. 我尝试使用dynamic关键字,但它无法在我的MarshalByRef远程对象上调用方法...我认为它说我的MarshalByRef实例上没有这个方法。 I have only tried this via IIOP.NET, though (I wonder if it works for normal .NET remoting). 我只是通过IIOP.NET尝试过这个(我想知道它是否适用于普通的.NET远程处理)。
  4. How do I create or inspect Message instances in the .NET remoting framework? 如何在.NET远程处理框架中创建或检查Message实例?
  5. Can I send or retrieve remoting messages directly, bypassing the underlying proxies? 我可以直接发送或检索远程处理消息,绕过底层代理吗?

Edit: I managed to make IIOP.NET / CORBA believe that I had a compatible interface by applying the RepositoryID attribute: 编辑:我设法通过应用RepositoryID属性使IIOP.NET / CORBA相信我有一个兼容的接口:

[Ch.Elca.Iiop.Idl.InterfaceType(Ch.Elca.Iiop.Idl.IdlTypeInterface.ConcreteInterface)]
[Ch.Elca.Iiop.Idl.RepositoryID("IDL:LicenseInfo:1.0")]
public interface ILicenseInfo : Ch.Elca.Iiop.Idl.IIdlEntity
{
    void GetHardwareKey(out string hwKey);
}

But I am still getting an empty string result. 但我仍然得到一个空字符串结果。

Edit 2: After some more experimentation and debugging, I have found that the response messages do contain the data I'm looking for, but are not being parsed into the client values properly, probably because of my bad interface definition. 编辑2:经过一些实验和调试之后,我发现响应消息确实包含了我正在寻找的数据,但是没有正确地解析成客户端值,可能是因为我的接口定义不好。 Hoping that debugging into the response processing further will help me figure out how to correct my interface. 希望进一步调试响应处理将帮助我弄清楚如何纠正我的界面。 Strangely the first thing it's parsing from the response is a null boxed value, which doesn't seem right for an "out string" parameter. 奇怪的是,它从响应中解析的第一件事是一个空的盒装值,这似乎不适合“out string”参数。

Edit 3: I have found that I need to apply string attributes to the parameters like this to prevent them from being treated as boxed values: 编辑3:我发现我需要将字符串属性应用于这样的参数,以防止它们被视为盒装值:

void GetHardwareKey([StringValue(), WideChar(true)] out string hwKey);

But despite the WideChar attribute, I am getting en error about the CodeSet not supporting WChar or something. 但是,尽管有WideChar属性,我对CodeSet不支持WChar或其他东西的错误。 I'm getting really close to figuring this out. 我已经非常接近搞清楚了。

Edit 4: I am stumped at how to set the codeset for WChar. 编辑4:我对如何为WChar设置代码集感到困惑。 If I do not set it, I receive an error: "WChar Codeset either not specified or not supported." 如果我没有设置它,我收到一个错误:“未指定或不支持WChar代码集。” because the server has returned a unicode string without overriding the default character set. 因为服务器返回了一个unicode字符串而没有覆盖默认字符集。 I can't find any way to override that from the client. 我找不到任何方法来覆盖客户端。 I tried calling: 我试着打电话:

omg.org.CORBA.OrbServices.GetSingleton().OverrideDefaultCharSets(
    CharSet.UTF8, WCharSet.UTF16);

But that does not seem to have any effect on the client end. 但这似乎对客户端没有任何影响。 The example code shows calling that on the server end. 示例代码显示在服务器端调用它。 But I didn't write the server, so I can't control that. 但我没有写服务器,所以我无法控制它。 Is my only option to rewrite the IIOP.NET code for my own purposes forcing a default WChar CodeSet to go into effect? 我唯一的选择是为了我自己的目的重写IIOP.NET代码,强制默认的WChar CodeSet生效?

After 3 days of debugging into IIOP to track down its behavior and inspect the data coming back in the response, I have settled on this solution. 经过3天的IIOP调试以追踪其行为并检查响应中的数据,我已经确定了这个解决方案。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using omg.org.CosNaming;
using Ch.Elca.Iiop;
using Ch.Elca.Iiop.Services;
using System.Runtime.Remoting.Channels;
using Ch.Elca.Iiop.Idl;

[RepositoryID("IDL:LicenseInfo:1.0")]
public interface ILicenseInfo
{
    Int32 GetHardwareKey([IdlSequence(0)] out byte[] hwKey);
    Int32 GetInstallationNumberList([IdlSequence(0)] out byte[] instNum);
}

class Program
{
    static void Main(string[] args)
    {
        IiopClientChannel channel = new IiopClientChannel();
        ChannelServices.RegisterChannel(channel, false);
        CorbaInit init = CorbaInit.GetInit();
        NamingContext context = init.GetNameService("MYLICSRV", 30000);
        NameComponent[] names = new NameComponent[] { new NameComponent("B1LicenseInfo") };
        ILicenseInfo li = (ILicenseInfo)context.resolve(names);
        byte[] hwKey;
        byte[] instNum;
        li.GetHardwareKey(out hwKey);
        li.GetInstallationNumberList(out instNum);
        Encoding encoding = new System.Text.UnicodeEncoding(false, false, true);
        Console.WriteLine(encoding.GetString(hwKey));
        Console.WriteLine(encoding.GetString(instNum));
    }
}

I temporarily was also using this in an attempt to make IIOP give me back the right strings. 我暂时也在使用它,试图让IIOP给我回正确的字符串。 If it had occurred to me that I could simply accept the reply as a byte array and perform the decoding myself, I wouldn't have wasted half the time trying to work out how to get IIOP to understand how I wanted my string back: 如果我发现我可以简单地接受回复作为字节数组并自己执行解码,我不会浪费一半时间试图找出如何让IIOP理解我想要我的字符串:

class MyOrbInitializer : omg.org.PortableInterceptor.ORBInitializer
{
    public void post_init(omg.org.PortableInterceptor.ORBInitInfo info)
    {
        // Nothing to do
    }

    public void pre_init(omg.org.PortableInterceptor.ORBInitInfo info)
    {
        omg.org.IOP.Codec codec = info.codec_factory.create_codec(
            new omg.org.IOP.Encoding(omg.org.IOP.ENCODING_CDR_ENCAPS.ConstVal, 1, 2));
        Program.m_codec = codec;
    }
}


class Program
{
    public static omg.org.IOP.Codec m_codec;

    static void Main(string[] args)
    {
        IOrbServices orb = OrbServices.GetSingleton();
        orb.OverrideDefaultCharSets(CharSet.UTF8, WCharSet.UTF16);
        orb.RegisterPortableInterceptorInitalizer(new MyOrbInitializer());
        orb.CompleteInterceptorRegistration();
...
        MarshalByRefObject objRef = context.resolve(names);
        string origObjData = orb.object_to_string(objRef);
        Ch.Elca.Iiop.CorbaObjRef.Ior iorObj = new Ch.Elca.Iiop.CorbaObjRef.Ior(origObjData);
        CodeSetComponentData cscd = new CodeSetComponentData(
            (int)Ch.Elca.Iiop.Services.CharSet.UTF8,
            new int[] { (int)Ch.Elca.Iiop.Services.CharSet.UTF8 },
            (int)Ch.Elca.Iiop.Services.WCharSet.UTF16,
            new int[] { (int)Ch.Elca.Iiop.Services.WCharSet.UTF16 });
        omg.org.IOP.TaggedComponent codesetcomp = new omg.org.IOP.TaggedComponent(
            omg.org.IOP.TAG_CODE_SETS.ConstVal, m_codec.encode_value(cscd));
        iorObj.Profiles[0].TaggedComponents.AddComponent(codesetcomp);
        string newObjData = iorObj.ToString();
        MarshalByRefObject newObj = (MarshalByRefObject)orb.string_to_object(newObjData);
        ILicenseInfo li = (ILicenseInfo)newObj;
...
    }

After that much code ran, I had an object that would define the WChar CodeSet so it would parse the return strings properly, avoiding the "WChar CodeSet either not specified or not supported" error. 在运行了很多代码之后,我有了一个定义WChar CodeSet的对象,因此它会正确解析返回字符串,避免“未指定或不支持WChar CodeSet”错误。 But after all that, the Unicode byte ordering was backwards too! 但毕竟,Unicode字节顺序也是倒退的! And the only way to fix that, as far as I could tell, was to re-parse the string into bytes and then back into a Unicode string. 据我所知,解决这个问题的唯一方法是将字符串重新解析为字节,然后再重新解析为Unicode字符串。 But that's when it occurred to me, why even ask for the result as a string!? 但是,当我遇到这种情况时,为什么甚至要求将结果作为字符串!? I could just take the bytes directly and avoid so much of this complication. 我可以直接获取字节并避免这种复杂化。 I wish I had thought of that earlier. 我希望我早点想到这一点。

SAP BO 882 //LicenseInterface.idl SAP BO 882 //LicenseInterface.idl

typedef sequence<octet> LicenseFileData;

interface LicenseInfo
{
  boolean IsUserLicensed(in wstring wstrUser, in wstring wstrModule, in wstring wstrInstallNo);
  long GetHardwareKey(out wstring pbstrHK);
  long GetInstallationNumberList(out wstring wbstrInstNum);
  long GetSystemNumber(out wstring wbstrSysNum, in wstring wstrInstallNo);
  long GetLicenseInfo(in wstring wstrModule, out long lNum, out long lAvailable, out long lStart, out long lEnd, in wstring wstrInstallNo);
  long GetLoggedInUsers(out wstring wbstrLogUsers);
  long StartLogging();
  long StopLogging();
  long GetLicenseNum(in wstring wstrKey, in wstring wstrInstallNo);
  long GetLogFileName(out wstring wstrLogFileName);
  boolean GetIsLogging();
  long LoadLicenseFile (in LicenseFileData arg_licenseFileData);
  boolean IsLicenseFileExist();
  long ResetAllLicenses();
  long GetVersion(out wstring sVersion);
  //long DeleteLicenseFile (in wstring wstrInstallNo);
};

SBOLicense.idl SBOLicense.idl

typedef sequence<octet> usBuffer;

enum LicenseClientUTFType {LIC_UTF16 , LIC_UTF32};

exception NotAuthenticated {};
exception UserNotConnected {};

interface LicenseServer
{
    long SBOConnect (in usBuffer User, in usBuffer Company, in usBuffer PCName, out usBuffer SessionE, in long lDate, in usBuffer sInstallNo) raises(NotAuthenticated);
    long AddOnGetLicense (in usBuffer Identifier, in usBuffer User, in usBuffer Company, in usBuffer PCName, out long plSessionID, out usBuffer SessionE, in long lDate, in usBuffer sInstallNo) raises(NotAuthenticated);
    long PollSession (in usBuffer User, in usBuffer SIDs, out usBuffer RetE) raises(NotAuthenticated);
    long SessionsInfo (in usBuffer User, in usBuffer SessionsInfo, out usBuffer SessionsInfoE, in long lDate) raises(NotAuthenticated);
    long SessionVerify (in usBuffer User, in long lSessionID, out usBuffer pSessionIdE) raises(NotAuthenticated);
    long CloseSession (in usBuffer User, in long lSessionId) raises(NotAuthenticated);
    long LockServer (in usBuffer User, in long lSessionID) raises(NotAuthenticated);
    long UnLockServer (in usBuffer User, in long lSessionID) raises(NotAuthenticated);
    long GetUserLicenseInfo (in usBuffer User, out usBuffer pModules, out boolean pbIsConnected) raises(NotAuthenticated);
    long GetAllModulesStatus (out usBuffer pModulesInfo) raises(NotAuthenticated);
    long LoadLicenseFile (in usBuffer NewLicenseFile) raises(NotAuthenticated);
    long GetHardwareKey (out usBuffer pHK) raises(NotAuthenticated);
    long CreateIdentifier (in usBuffer Addon, out usBuffer pIdentifier, in usBuffer sInstallNo) raises(NotAuthenticated);
    long GetAllUsersLicenseInfo(out usBuffer pUsersLicInfo) raises(NotAuthenticated);
    long SetAllUsersLicenseInfo(in usBuffer User, in usBuffer UsersLicInfo, out usBuffer pConnectedUser) raises(NotAuthenticated,UserNotConnected);
    long IsDevExist (in usBuffer sInstallNo);
    long GetInstallationNumberList(out usBuffer pInstNum);
    long GetSystemNumber (out usBuffer pSysNum, in usBuffer sInstallNo);
    long GetFutureExpired(in long lFutureDate, out usBuffer pModules, in usBuffer sInstallNo);
    long GetUserSessionsInfo(in usBuffer UserName,out usBuffer pRsltSessionsInfo);
    long GetBIGSLicense (in usBuffer User, in usBuffer Company, in usBuffer PCName, in long lNum, out usBuffer pSessionsE, in long lDate, in usBuffer sInstallNo) raises(NotAuthenticated);
    boolean IsLicenseFileExist();
    long GetVersion(out usBuffer sVersion);
    long ClearUserLicenses (in usBuffer User) raises(NotAuthenticated);
    long UpdateUserLicenses (in usBuffer User, out usBuffer ModulesE, in long lDate, in long lSessionID, in usBuffer sCmpLocalization, in usBuffer sCmpVersion) raises(NotAuthenticated);
    long RequestNamedLicenses (in usBuffer User, out usBuffer ModulesE, in long lDate, in long lSessionID, in usBuffer sCmpLocalization, in usBuffer sCmpVersion) raises(NotAuthenticated);
    long IsLicenseConcurrent () raises(NotAuthenticated);
    long GetLicenseFileGenInfo(in usBuffer sInstallNo, out usBuffer sLicGenInfo);
    //long DeleteLicenseFile (in usBuffer sInstallNo) raises(NotAuthenticated);

    long HandShake(in long algorithm, in usBuffer publicKey, out usBuffer sessionKey) raises(NotAuthenticated);
    long GetCompanyDBCredentials(in long dbType, in usBuffer server, in usBuffer company, in usBuffer user, in usBuffer password, out usBuffer dbUser, out usBuffer dbPassword, out boolean useTrusted) raises(NotAuthenticated);
    long GetDBCredentials(in long dbType, in usBuffer server, in usBuffer siteUser, in usBuffer password, out usBuffer dbUser, out usBuffer dbPassword, out boolean useTrusted) raises(NotAuthenticated);
    long GetCompanyReadOnlyDBCredentials(in long dbType, in usBuffer server, in usBuffer company, in usBuffer user, in usBuffer password, out usBuffer dbUser, out usBuffer dbPassword) raises(NotAuthenticated);
    long GetReadOnlyDBCredentials(in long dbType, in usBuffer server, in usBuffer siteUser, in usBuffer password, out usBuffer dbUser, out usBuffer dbPassword) raises(NotAuthenticated);
    long GetListOfCompanies(in long dbType, in usBuffer server, in boolean refresh, out usBuffer listOfCompanies);
    long GetCompanyEncryptionConfig(in long dbType, in usBuffer server, in usBuffer company, in usBuffer user, in usBuffer password, out long algorithm, out usBuffer keyId, out usBuffer key) raises(NotAuthenticated);
    long GetEncryptionConfig(in usBuffer siteUser, in usBuffer password, out long algorithm,  out usBuffer keyId, out usBuffer key) raises(NotAuthenticated);
    long SetDBCredentials(in long dbType, in usBuffer server, in usBuffer siteUser, in usBuffer password, in usBuffer dbUser, in usBuffer dbPassword, in boolean useTrusted) raises(NotAuthenticated);
    long RemoveDBCredentials(in long dbType, in usBuffer server, in usBuffer siteUser, in usBuffer password) raises(NotAuthenticated);
    long GetServerVersion(in long dbType, in usBuffer server, out usBuffer version, in usBuffer commonDBName);
    long SetReadOnlyDBCredentials(in long dbType, in usBuffer server, in usBuffer siteUser, in usBuffer password, in usBuffer dbUser, in usBuffer dbPassword) raises(NotAuthenticated);
    long SetEncryptionAlghorithm(in usBuffer siteUser, in usBuffer password, in long algorithm) raises(NotAuthenticated);
    long GenerateEncryptionKey(in usBuffer siteUser, in usBuffer password) raises(NotAuthenticated);
    long GetServicesUserCredentials(in usBuffer siteUser, in usBuffer password, out usBuffer servicesUser, out usBuffer servicesPassword) raises(NotAuthenticated);
    long ExportSecuritySettings(in usBuffer siteUser, in usBuffer password, out usBuffer xmlSettings) raises(NotAuthenticated);
    long ImportSecuritySettings(in usBuffer siteUser, in usBuffer password, in usBuffer xmlSettings) raises(NotAuthenticated);
    long GetListOfConfiguredServers(out usBuffer listOfServers);
    long GetSiteUserName(out usBuffer siteUser);
    long AuthenticateSiteUser(in usBuffer siteUser, in usBuffer password, out boolean result) raises(NotAuthenticated);
    long AuthenticateServicesUser(in usBuffer siteUser, in usBuffer password, out boolean result) raises(NotAuthenticated);
    long ChangeSiteUserPassword(in usBuffer siteUser, in usBuffer oldPassword, in usBuffer password) raises(NotAuthenticated);
    long ChangeSiteUserPasswordByDB(in long dbType, in usBuffer server, in usBuffer dbUser, in usBuffer dbPassword, in usBuffer password) raises(NotAuthenticated);
    long GetCompanyStaticKey(in long dbType, in usBuffer server, in usBuffer company, in usBuffer user, in usBuffer password, out usBuffer key) raises(NotAuthenticated);
    long GetStaticKey(in usBuffer siteUser, in usBuffer password, out usBuffer key) raises(NotAuthenticated);
    long GetEncryptionAlgorithm(out long algorithm);
    long IsNTTrusted(in long dbType, in usBuffer server, out boolean isNTTrusted);
    long IsDKeyUsed(out boolean result);
    long ExportDKeys(in usBuffer siteUser, in usBuffer password, out usBuffer xmlDKeys) raises(NotAuthenticated);
    long ImportDKeys(in usBuffer siteUser, in usBuffer password, in usBuffer xmlDKeys) raises(NotAuthenticated);
    long GenerateDKey(in usBuffer siteUser, in usBuffer password, out usBuffer xmlDKeys) raises(NotAuthenticated);
    long EnableDKey(in usBuffer siteUser, in usBuffer password, out usBuffer xmlDKeys) raises(NotAuthenticated);
    long GetCompanyKeyAndKeyState(in long dbType, in usBuffer server, in usBuffer company, in usBuffer user, in usBuffer password, in usBuffer compKeyId, out long keyState, out usBuffer compKey)raises(NotAuthenticated);
    long GetKeyAndKeyState(in usBuffer siteUser, in usBuffer password, in usBuffer compKeyId, out long keyState, out usBuffer compKey)raises(NotAuthenticated);

};

interface LicenseServerFactory
{
  LicenseServer GetLicenseServer(in LicenseClientUTFType ClientUTFType);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 “对目标对象的后期绑定访问”是什么意思? - What does "late-bound access to the destination object" mean? 在C#中释放后期绑定对象 - Release Late-Bound Object in C# Unity中RegisterInstance的后期版本 - Late-bound version of RegisterInstance in Unity 是否可以在没有 SDK 的情况下调用 Dynamics CRM 2011 后期绑定 WCF 组织服务 - 直接自定义绑定? - Is it possible to call Dynamics CRM 2011 late-bound WCF Organization service without the SDK - straight customized binding? Entity Framework执行后期绑定存储过程 - late-bound stored procedure execution with Entity Framework 私有成员的后期绑定调用会引发MethodAccessException - Late-bound invocation of private member throws a MethodAccessException MVC 4后期绑定的DataContext实体LINQ引用 - MVC 4 late-bound DataContext entity LINQ reference 了解COM / WSH行为-后期绑定IDispatch _Default和Item? - Understanding COM/WSH Behavior - Late-bound IDispatch _Default and Item? 使用动态关键字将后期绑定信息添加到C#中的对象? - Adding late-bound information to an object in C#, using dynamic keyword? 如何从后期绑定的COM对象获取方法列表 - How to get a list of Methods from a late bound COM object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM