Почему этот класс C # COM можно использовать из VBScript, но не из JScript?

Рассмотрим автоматизированную COM-библиотеку в C #, приведенную ниже. Он следует общепринятому шаблону COM с наличием видимого фабричного класса FooFactory, реализующего ICreateFoos, который создает объект типа IFoo. FooFactory являетсятолько Coclass в библиотеке типов. (Заводской шаблон особенно полезен для COM, поскольку он не допускает параметризованных конструкторов).

В приведенном ниже коде я обнаружил, что не могу получить доступ к возвращенному интерфейсу IFoo изJScript если я не сделаю класс FooImpl ComVisible (закомментировав закомментированные строки; это заставляет его появляться как кокласс в библиотеке типов).Там нет такой проблемы доступа к этому из VBscript.

То есть я могу запустить этот VBScript:

set ff = CreateObject("jstest.FooFactory")
set foo = ff.CreateFoo(0)
foo.Foo

Но этофункционально идентичный Сбой JScript с ошибкой «C: \ temp \ jstest \ jstest.js (4, 1) Ошибка времени выполнения Microsoft JScript:« foo »является нулевым или не является объектом»:

var ff = new ActiveXObject("jstest.FooFactory");
var foo = ff.CreateFoo(0)
//WScript.Stdout.WriteLine(null==foo)
foo.Foo();

Если я раскомментирую строку, я вижу, что null == foo равно false.

Почему это происходит? Это ошибка? Обратите внимание, что я думаю, что это проблема - комбинация JScript и специфичной для C # /. Net реализации (возможно, IDispatch), потому что у меня есть другие подобные COM-серверы - реализованные на C ++ - которые не демонстрируют эту проблему из JScript.

Проблема исчезнет, ​​если я раскомментирую закомментированные строки в приведенном ниже коде, делая FooImpl видимым как кокласс - но я специально не хочу этого делать, так как не хочу раскрывать детали реализации. Обходным путем кажется сделать FooImpl ComVisible, но пометить его конструктор как внутренний, что не позволяет клиентам создавать его, но это вряд ли элегантно.

Я работаю на WinXP SP3 с Visual Studio 2005, .net 2 и смог воспроизвести проблему при полностью новой установке TinyXP на VirtualBox (оба с Windows Script Host 5.7), а также на Windows 7 Ultimate, используя .net SDK 2.0, 3.0, 3.5 и 4.0 (WSH 5.8). Все ОС были 32-битными.

Код библиотеки:

using System;
using System.Runtime.InteropServices;

[assembly: ComVisible(false)]

namespace jstest
{
    [ComVisible(true)]
    public interface ICreateFoos
    {
        IFoo CreateFoo(int importantNumber);
    }

    [ComVisible(true)]
    public interface IFoo
    {
        void Foo();
    }

    [ComVisible(true)]
    public class FooFactory : ICreateFoos
    {
        public IFoo CreateFoo(int importantNumber)
        {   // in *this* version, we don't use importantNumber yet
            return new FooImpl();
        }
    }

    //[ComVisible(true)]
    public class FooImpl : IFoo
    {
        public void Foo()
        {
            Console.WriteLine("Foo");
        }
    }
}

Вы можете скомпилировать и зарегистрировать (вам может потребоваться запустить от имени администратора, чтобы regasm) это с

csc /target:library jstest.cs
regasm /codebase jstest.dll

Ответы на вопрос(1)

Ваш ответ на вопрос