2011-01-25 8 views
3

私は知っている、WinFax Proはそうです。1998年。.NETアプリケーションからWinFax Pro COMオブジェクトを使用するにはどうすればよいですか?

(注:これはWinFax.dllとは明らかにWindowsの一部です。これは元々Delrinaの独立した商用アドオンアプリですSymantecによって買収された)。

私はまだWinFax Proを運用システムとして使用しているオフィスで働いています。彼らはWinFax Pro "PhoneBook"に保存されている顧客のファックス番号を持っており、それを利用して顧客にサービス訪問を通知します。今動作する方法は、Macカレンダーから生成された(印刷された)スケジュールを見てから、WinFax電話帳の該当するすべてのエントリをクリックして通知ファックスを送信することです。

これは「スイベルチェア」の統合と呼ばれていましたが、これは2つの画面を参照していました。これは2つの画面でもなく、1枚の紙と1枚の画面です。

とにかく私はそれを自動化して問題を起こそうとしています。

良いニュース:
- WinFax Proは、その機能をCOMオブジェクトとして公開しています。FAX送信エンジンのWinFax.SDKSend。アドレス帳のWinFax.SDKPhoneBookなど。
- WinFax Proには、これらのさまざまなCOMオブジェクトを記述するタイプライブラリwfxctl32.tlbが付属しています。 - .NET(C#)のWinFax.SDKSendオブジェクトを、tlbimportから生成されたラッパーを使用して正常に使用できるようになりました。 (私は.NET 3.5を使用していますが、.NET 4.0は使用できません)。

悪いニュース:
WinFax.SDKSend以外のWinFax COMオブジェクトのメソッドを呼び出すことができませんでした。署名はWinFax.SDKSendのものよりも複雑には見えませんが、例外を受けています。

C#コード:

public void Run() 
{ 
    var pb = new wfxctl32.CSDKPhoneBook(); 
    string id = pb.GetFolderListFirst(1, ""); 
} 

例外:

Exception: System.InvalidCastException: Unable to cast COM object of type 'wfxctl32.CSDKPhoneBookClass' to interface type 'wfxctl32.ISDKPhoneBook'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{A67FCC81-9949-11D0-961E-444553540000}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at wfxctl32.CSDKPhoneBookClass.GetFolderListFirst(Int16 standardFolder, String folderID)

答えて

1

Windows SDKの一部であるthe OleView toolを開いたところ、WinFax.SDKPhoneBookのCOMインターフェイスがオブジェクトに存在しないことがわかりました。うーん、それは驚きです。インタフェースはタイプライブラリによって記述され、tlbimport.exeはラッパを生成します。また、インターフェイスは、WinFax Pro SDKのPDFドキュメントに記載されています。しかし、WinFax.SDKPhoneBookの初期バインドインターフェイスを使用している人の例はひとつも見つかりませんでした。

私はCOMオブジェクトに呼び出すjavascriptでこれを試してみましたが、うまくいきました。彼らはのIDispatch(遅延バインディング)のみであり、VB6、VBScriptのは、JavaScript、PerlやPython、および後期の他から自然にアクセス可能です - のWinFaxプロCOMインターフェイスはデュアルインターフェイスではないという結論に私を導い

function say(x){ WScript.Echo(x); } 

var Folder = function(id) { 
    this.Id = id; 
    this.DisplayName = null; 
    this.Parent = null; 
}; 

Folder.prototype.GetFolderName = function() { 
    if (this.DisplayName === null) { 
     this.DisplayName = comObject.GetFolderDisplayName(this.Id); 
    } 
    return (this.Parent === null) ? this.DisplayName 
     : this.Parent.GetFolderName() + "/" + this.DisplayName; 
}; 

var comObject = new ActiveXObject("WinFax.SDKPhoneBook"); 

var GetPbFoldersForId = function(firstId) { 
    // stage 1 - do searches for folders 
    var list = []; 
    var id = firstId; 
    do { 
     list.push(new Folder(id)); 
     id = comObject.GetFolderListNext(); 
    } while (id != ""); 

    // stage 2 - get subfolders, if any, for each folder 
    var subs =[]; 
    for (var i=0; i<list.length; i++) { 
     id = comObject.GetFolderListFirst(0,list[i].Id); 
     if (id != "") { 
      var a = GetPbFoldersForId(id); // recurse 
      for (var j=0; j < a.length; j++) { 
       if (a[j].Parent === null) {a[j].Parent = list[i];} 
       subs.push(a[j]); 
      } 
     } 
    } 

    for (var k=0; k<subs.length; k++) { 
     list.push(subs[k]); 
    } 

    return list; // a list of folders 
}; 

var id = comObject.GetFolderListFirst(1, ""); 
Folders = GetPbFoldersForId(id); 

for (var k=0; k<Folders.length; k++) { 
    say(Folders[k].GetFolderName()); 
} 

C#やVB.NETなどの.NET言語からは直接アクセスできません。


Does C# .NET support IDispatch late binding?は、C#のIDispatchインターフェイスとの接続方法を教えてくれます。それを使用して、私はこのような何かを行うことができます:

public sealed class PhoneBook // a singleton 
{ 
    Object comObject; 
    Type type; 

    private readonly static PhoneBook _instance = new PhoneBook(); 
    public static PhoneBook Instance { get { return _instance; } } 

    private PhoneBook() 
    { 
     var t = Type.GetTypeFromProgID("WinFax.SDKPhoneBook"); 
     if (t == null) 
      throw new ArgumentException("WinFax Pro is not installed."); 
     comObject = Activator.CreateInstance(t); 
     type = comObject.GetType(); 
    } 

    public string GetUserGroupFirst(int flavor, string id) 
    { 
     var parameters = new Object[2]; 
     parameters[0] = flavor; 
     parameters[1] = id; 
     string s = type.InvokeMember("GetUserGroupFirst", 
            BindingFlags.InvokeMethod, 
            null, 
            comObject, 
            parameters) as String; 
     return s; 
    } 
.... 

電話帳クラスは、IDispatchインタフェース上のラッパーです。私は、typelibの各メソッドとプロパティのための1つのラッパーメソッドを書きました。私はこれが.NET 4.0が自動的に私にとって何をするのかと思う。いずれにせよ、これは私のためにうまくいった。

私はこのQ &をここに掲載していますので、WinFax Proを扱う他の人にこの情報があるかもしれません。私はintertubes全体を検索し、良い情報を見つけることができなかったので、私はこれをそこに置いています。


EDIT - この.NETコードは今、ユーザーがエントリを検索し、WebページやRESTクライアントからFAXを送信できるように、ASPNET MVCアプリケーションで実行されています。

+0

あなたはおそらくこれまでにそれにうんざりしていますが、これは本当の原因ではありません。 Tlbimpはタイプライブラリのデュアルインタフェースを見つけるのに問題はなく、サーバが実際に実装していないことは知られていません。このような事故の最も一般的な原因は、インストールされているバージョンと一致しないバージョン管理の問題です。一般的には、アップデートには新しいガイドが必要です。 –

+0

@ハンス - あなたは正しいかもしれません。私はCOMの専門家ではありません。しかし、私が問題のProgId( 'WinFax.SDKPhoneBook')でOleViewを使用すると、IDispatch、IUnknown、ITypeInfo、その他いくつかのものが表示されますが、WinFax Proで定義されたアプリケーションインターフェイスではありません。 .tlbにそれがあれば、COMオブジェクトは初期バインドされたインタフェースとしてそれを公開するだろうと思ったので、私は困惑させました。私はバージョンとGUIDを調べました - それは問題ではないようです。シマンテックが初期のインターフェースを実装したことはないようです。それは不可能だと思いますか? (深刻なQ) – Cheeso

+0

ああ、シマンテック。私は突然、もはやそれほど興味がありません。あなたは何かがある、あなたのために働くべきである。がんばろう。 –

0

私は最悪のソリューションとして、それを参照してくださいね、しかし、あなたは常にでWINFAX COMオブジェクトのための独自のラッパーを書くことができますC++(あるいはVB6でも可能です)、そのコードに実際の作業を行い、.NETコードからこれらのラッパーを呼び出します。そうすれば、COMインターフェースタイプを.Net互換タイプなどに変換する方法を理解することについてあまり心配する必要がないので、かなり簡単になるかもしれません。

0

私はあなたの特定の問題をお手伝いすることはできませんが、COM相互運用機能は同じ「ビット数」のcom dllでのみ動作し、.NETは実行中のコンピュータに固有のアプリケーション(つまり、64ビットコンピュータで64ビットのアプリケーションを生成します)。

ほとんどすべてのCOM dllは32ビットですが、特に商用のものであるため、プロジェクト設定のCPUタイプを「任意」から「32ビット」に設定することで、アプリケーションを常に32ビットビルドする必要があります。

関連する問題