9

SAP の「COM ライセンス ブリッジ」を使用して、ライセンス サーバーにアクセスし、システムのハードウェア キーをプログラムで照会しています (独自のライセンスなしで再利用するため)。これは、SAP Business one バージョン 2007A、2007B、および 8.8 では正常に機能しましたが、8.81 では、GetHardwareKey 関数を呼び出そうとするとメモリ例外が発生するため、COM ラッパーを更新せずに CORBA インターフェイスを更新したようです。

そこで、IIOP.NET をダウンロードして、独自のインターフェイスを作成する試みを開始しました。とにかく、私はそのCOMラッパーが好きではありませんでした。しかし、私は .NET リモート処理の宿敵に遭遇しました。つまり、サーバーとクライアントの両方で共通のインターフェイスを定義しないと、リモート メソッドを呼び出せないということです。IIOP.NET に含まれている IDL から CLS へのコンパイラを使用してみましたが、互換性のないインターフェイスに関するエラーが引き続き発生します (SAP は IDL ファイルを提供していません)。インターフェイスに互換性があるかどうかを IIOP と CORBA がどのように判断するのかわかりません。しかし、IIOP.NET コードをデバッグして、互換性がないにもかかわらず強制的にメソッドを実行しようとしたところ、必要なハードウェア キーの代わりに空の文字列が返されました。

私の次のステップは、偽のライセンス サーバーを実装し、実稼働クライアントからの要求を調べて、それらがどのように見えるかを特定することですが、私が経験した困難を考えると、あまり成功を期待してません。すでに .NET リモート処理の内部を覗いています。

私の本当の問題は、SAP Business One ハードウェア キーを取得または生成する方法ですが、そこから生じる疑問には次のようなものがあります。

  1. CORBA インターフェイスに関する情報を反映または照会するにはどうすればよいですか? NamingContext クラスの list メソッドを使用して、使用可能なオブジェクトのリストを取得できますが、オブジェクトで使用可能なメソッドを照会する方法があるかどうかわかりません。
  2. インターフェイスなしで .NET リモート処理メソッドを動的に呼び出すことはできますか? CORBA を動的に呼び出すための DII というものがあるようですが、IIOP.NET からの使用方法がわかりません。
  3. デリゲートまたは不完全なインターフェイスだけで .NET リモート処理メソッドを呼び出すことはできますか? dynamic キーワードを使用してみましたが、MarshalByRef リモート オブジェクトでメソッドを呼び出すことができませんでした... MarshalByRef インスタンスまたは何かにメソッドが存在しないと言ったと思います。ただし、これはIIOP.NET経由でのみ試しました(通常の.NETリモートで機能するかどうか疑問に思います)。
  4. .NET リモート処理フレームワークで Message インスタンスを作成または検査するにはどうすればよいですか?
  5. 基になるプロキシをバイパスして、リモート メッセージを直接送信または取得できますか?

編集: 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);
}

しかし、私はまだ空の文字列の結果を得ています。

編集 2:さらに実験とデバッグを行った後、応答メッセージには探しているデータが含まれていることがわかりましたが、おそらくインターフェイス定義が不適切なため、クライアント値に適切に解析されていません。応答処理をさらにデバッグすることが、インターフェースを修正する方法を理解するのに役立つことを願っています。不思議なことに、応答から最初に解析するのは null のボックス化された値であり、これは「出力文字列」パラメーターには適切ではないようです。

編集 3:ボックス化された値として扱われないようにするには、次のようなパラメーターに文字列属性を適用する必要があることがわかりました。

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

しかし、WideChar 属性にもかかわらず、CodeSet が WChar などをサポートしていないというエラーが表示されます。私はこれを理解することに本当に近づいています。

編集 4: WChar のコードセットを設定する方法に困惑しています。設定しないと、「WChar コードセットが指定されていないか、サポートされていません」というエラーが表示されます。これは、サーバーがデフォルトの文字セットをオーバーライドせずに Unicode 文字列を返したためです。クライアントからそれをオーバーライドする方法が見つかりません。私は電話してみました:

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

しかし、それはクライアント側には何の影響もないようです。コード例は、サーバー側でそれを呼び出すことを示しています。しかし、私はサーバーを書いていないので、それを制御することはできません. デフォルトの WChar CodeSet を強制的に有効にする目的で IIOP.NET コードを書き直す唯一のオプションはありますか?

4

2 に答える 2

8

IIOP の動作を追跡し、応答で返されるデータを検査するために 3 日間デバッグした後、私はこの解決策に落ち着きました。

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));
    }
}

私は一時的にこれを使用して、IIOP が正しい文字列を返すようにしました。単純に応答をバイト配列として受け取り、自分でデコードを実行できることに気がついたなら、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;
...
    }

それだけ多くのコードを実行した後、WChar CodeSet を定義するオブジェクトを作成して、返された文字列を適切に解析し、「WChar CodeSet が指定されていないか、サポートされていません」というエラーを回避しました。しかし、結局のところ、Unicode のバイト順も逆でした! 私が知る限り、それを修正する唯一の方法は、文字列をバイトに再解析してから、Unicode 文字列に戻すことでした。しかし、それが私が思いついたときです。なぜ結果を文字列として要求するのでしょうか!? バイトを直接取得するだけで、この複雑さを大幅に回避できます。それを先に考えておけばよかった。

于 2011-05-18T16:44:05.973 に答える
3

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

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);
};
于 2012-06-21T04:18:40.327 に答える