Я открыл инструмент OleView , часть Windows SDK, и я вижу, что COM-интерфейс для WinFax.SDKPhoneBook отсутствует на объекте.Хм, это сюрприз.Интерфейс описывается библиотекой типов, и tlbimport.exe создает для нее оболочку.Также интерфейс документирован в PDF-документе WinFax Pro SDK.Но я не смог найти ни одного примера того, кто бы успешно использовал интерфейс с ранней привязкой для WinFax.SDKPhoneBook.
Когда я попробовал это с вызовом javascript в 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());
}
Это привело меня к выводу, что интерфейсы WinFax Pro COM не являются двойными интерфейсами - они только IDispatch (с поздним связыванием) и доступны естественным образом из VB6, VBScript, Javascript, Perl, Python идругие языки с поздним связыванием, но не напрямую из языков .NET, таких как C # или VB.NET.
Поддерживает ли C # .NET позднюю привязку IDispatch? рассказывает, как подключиться к интерфейсам IDispatch из C #.Используя это, я могу сделать что-то вроде этого:
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.Я написал один метод-обертку для каждого метода и свойства в typelib.Я думаю, это то, что .NET 4.0 сделает для меня автоматически.В любом случае, это хорошо сработало для меня.
Я публикую здесь эти вопросы и ответы только для того, чтобы другие люди, имеющие дело с WinFax Pro, могли иметь информацию.Я искал по всем трубкам и не смог найти никакой хорошей информации, поэтому выкладываю это туда.
EDIT - этот код .NET теперь выполняется в приложении ASPNET MVC, позволяя пользователям искать записи и отправлять факсы с веб-страницы или клиента REST.