首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用来自WinFax应用程序的.NET Pro COM对象?

如何使用来自WinFax应用程序的.NET Pro COM对象?
EN

Stack Overflow用户
提问于 2011-01-25 15:25:30
回答 3查看 880关注 0票数 3

我知道,WinFax专业是如此的1998年。

(注意:这不是WinFax.dll,它显然是Windows的一部分。这是WinFax Pro,这是一个独立的商业附加应用,最初来自Delrina,后来被赛门铁克收购)。

我在一个仍然使用WinFax Pro作为操作系统的办公室工作。他们将客户传真号码存储在WinFax Pro "PhoneBook“中,并使用它通知客户服务访问。现在的工作方式是,有人查看从Mac生成的(打印)计划,然后单击WinFax电话簿中的所有适当条目发送传真。

这就像我们以前称之为“转椅”集成的东西,但它指的是两个屏幕。这甚至不是两个屏幕-它是一张纸和一个屏幕。

不管怎么说,我正试图使它自动化,并且遇到了麻烦。

好消息是:

  • WinFax Pro将其函数公开为COM对象: WinFax.SDKSend用于传真发送引擎;WinFax.SDKPhoneBook用于通讯录,等等。
  • WinFax Pro提供了一个类型库wfxctl32.tlb,它描述了这些不同的COM对象。-我能够通过从tlbimport生成的包装器成功地使用来自.NET的.NET对象(C#)。(我使用的是.NET 3.5,不能使用.NET 4.0)。

坏消息是:

我无法在WinFax COM对象上调用除WinFax.SDKSend之外的任何方法。签名看起来并不比WinFax.SDKSend中的签名更复杂,但我总是遇到异常。

C#代码:

代码语言:javascript
复制
public void Run()
{
    var pb = new wfxctl32.CSDKPhoneBook();
    string id = pb.GetFolderListFirst(1, "");
}

例外情况:

异常: System.InvalidCastException:无法将'wfxctl32.CSDKPhoneBookClass‘类型的COM对象转换为接口类型'wfxctl32.ISDKPhoneBook’。此操作失败,因为QueryInterface调用与IID '{A67FCC81-9949-11D0-961E-444553540000}‘接口的COM组件失败:不支持此类接口( HRESULT: 0x80004002 (E_NOINTERFACE)例外)。 at System.RuntimeType.InvokeDispMethod(字符串名称、BindingFlags invokeAttr、对象目标、Object[] args、Boolean[] byrefModifiers、Int32区域性、String[] namedParameters) at System.RuntimeType.InvokeMember(字符串名称、bindingFlags BindingFlags、绑定器、对象目标、Object[] providedArgs、ParameterModifier[]修饰符、CultureInfo文化、String[] namedParams) 在System.RuntimeType.ForwardCallToInvokeMember(String memberName,BindingFlags标志,对象目标,Int32[] aWrapperTypes,MessageData& msgData) 在wfxctl32.CSDKPhoneBookClass.GetFolderListFirst(Int16 standardFolder,String folderID)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-25 15:36:30

我打开了Windows的一部分OleView工具,我可以看到对象上没有WinFax.SDKPhoneBook的COM接口。嗯,这是个惊喜。接口由类型库描述,tlbimport.exe为它生成一个包装器。此外,接口记录在WinFax Pro中。但是,我找不到一个成功使用WinFax.SDKPhoneBook早期绑定接口的例子。

当我尝试使用javascript调用COM对象时,它运行得很好。

代码语言:javascript
复制
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());
}

这使我得出结论,WinFax Pro COM接口不是双重接口--它们仅限于IDispatch (后期绑定),可以从VB6、VBScript、Javascript、Perl、Python和其他晚绑定语言自然访问,但不能直接从.NET语言(如C#或VB.NET )访问。

C# .NET支持IDispatch后期绑定吗?告诉我如何从C#连接IDispatch接口。用它,我可以做这样的事情:

代码语言:javascript
复制
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;
    }
....

PhoneBook类是IDispatch接口上的包装器。我在类型库中为每个方法和属性编写了一个包装器方法。我认为这是.NET 4.0会自动为我做的事情。在任何情况下,这对我来说都很好。

我在这里张贴这个问答,只是为了让其他与WinFax专业人士打交道的人可能有这些信息。我搜遍了所有的内线,找不到任何好的信息,所以我把这个放出来了。

编辑--这段.NET代码现在运行在ASPNET应用程序中,允许用户查找条目并从网页或REST客户端发送传真。

票数 1
EN

Stack Overflow用户

发布于 2011-01-25 15:35:30

我认为它是最坏的解决方案,但是您可以在C++ (甚至VB6)中为Winfax对象编写自己的包装器,让该代码完成实际工作,然后从.Net代码中调用包装器。这样,您就不必太担心如何将COM接口类型转换为.Net兼容类型等等,因此这可能会使它变得更容易一些。

票数 0
EN

Stack Overflow用户

发布于 2011-01-25 15:41:02

我无法帮助您解决您的特殊问题,但请注意,COM互操作仅适用于具有相同"bitness“的com dll,而.NET将默认使用它正在运行的计算机上的本地应用程序(即。它将在64位计算机上生成一个64位应用程序)。

几乎所有的COM dll都是32位,尤其是商业的,所以您必须强制应用程序始终构建32位,方法是将项目设置中的CPU类型从"Any“设置为"32位”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4795287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档