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

后端 未结 2 491
心在旅途
心在旅途 2020-12-31 15:15

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). Thi

2条回答
  •  再見小時候
    2020-12-31 15:40

    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.

    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. 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:

    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. But after all that, the Unicode byte ordering was backwards too! 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. 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.

提交回复
热议问题