Борьба за создание COM-объекта с Visual Studio 2010, который виден из VBScript, запускается из командной строки - PullRequest
0 голосов
/ 19 октября 2011

Я пытаюсь создать COM-объект в Visual Studio (2010) в VB.NET , который может быть вызван из VBScript программы, запускаемой из командной строки.Я хочу, чтобы скрипт мог делать что-то вроде ...

Option Explicit
Dim trips
Dim results

Set trips = CreateObject("Hartley.Trips")
Set results = trips.selecttrips(57,now())
wscript.echo results.count

Однако, что бы я ни делал, этот скрипт завершается неудачно с:

ActiveX компонент не может создать объект:'Hartley.Trips

Ядром определения объекта COM является ...

<ComClass(Trips.ClassId, Trips.InterfaceId, Trips.EventsId)> _
Public Class Trips

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class
    ' and its COM interfaces. If you change them, existing
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "75184b72-31e3-4d62-add6-438230d17bc3"
    Public Const InterfaceId As String = "c020fef9-0425-4200-a2b4-77931c0a6011"
    Public Const EventsId As String = "4cf93b6e-f554-491b-94bd-5b02c3c6c586"
#End Region
    Private Const connStr As String = "redacted"
    Private dbConnection As SqlClient.SqlConnection
    Private connectionInitialised As Boolean = False

    ' A creatable COM class must have a Public Sub New()
    ' with no parameters, otherwise, the class will not be
    ' registered in the COM registry and cannot be created
    ' via CreateObject.

    Public Sub New()
        MyBase.New()
    End Sub

    Public Class Trip
        Private myTripID As Integer
        Private myIsComplete As Boolean
        Private myStart As DateTime
        Private myEnd As DateTime
        Private myHasStarted As Boolean
        Public Sub New(ByVal iTripID As Integer, ByVal bIsComplete As Boolean, _
                       ByVal dStart As DateTime, ByVal dEnd As DateTime, _
                       ByVal bHasStarted As Boolean)
            myTripID = iTripID
            myIsComplete = bIsComplete
            myStart = dStart
            myEnd = dEnd
            myHasStarted = bHasStarted
        End Sub

        Public ReadOnly Property TripID() As Integer
            Get
                Return myTripID
            End Get
        End Property

        Public ReadOnly Property Iscomplete() As Boolean
            Get
                Return myIsComplete
            End Get
        End Property

        Public ReadOnly Property StartDate() As DateTime
            Get
                Return myStart
            End Get
        End Property

        Public ReadOnly Property EndDate() As DateTime
            Get
                Return myEnd
            End Get

        End Property

        Public ReadOnly Property hasStarted() As Boolean
            Get
                Return myHasStarted
            End Get
        End Property

    End Class

    Public Class Results
        Private mySelectID As Integer
        Private myTripDay As Date
        Private myIsDriver As Boolean
        Private myTripArray As List(Of Trip)
        Public Sub New(ByVal iSelectID As Integer, dTripDay As Date, _
                       bIsDriver As Boolean, iCount As Integer)
            myTripArray = New List(Of Trip)
            mySelectID = iSelectID
            myTripDay = dTripDay
            myIsDriver = bIsDriver
        End Sub

        Public ReadOnly Property numTrip() As Integer
            Get
                Return myTripArray.Count
            End Get
        End Property

        Public ReadOnly Property SelectID() As Integer
             Get
                Return mySelectID
            End Get
        End Property

        Public ReadOnly Property ReportDate() As Date
            Get
                Return myTripDay
            End Get
        End Property

        Public ReadOnly Property isDriver() As Boolean
            Get
                 Return myIsDriver
            End Get
        End Property

        Public ReadOnly Property TripArray() As Array
            Get
                Return myTripArray.ToArray
            End Get

        End Property

        Public Sub Add(aTrip As Trip)
            myTripArray.Add(aTrip)
        End Sub
    End Class

    Public Function SelectTrips(SelectID As Integer, TripDay As Date, _
                                Optional isDriver As Boolean = False) As Results
        Dim myTrip As Trip
        Dim myEndDate As DateTime
        Dim cmd As SqlClient.SqlCommand
        Dim rs As SqlClient.SqlDataReader

        If Not connectionInitialised Then 'If this is first attempt
            dbConnection = New SqlClient.SqlConnection(connStr)
            dbConnection.Open()
            connectionInitialised = True
        End If

        'Test Only
        cmd = New SqlClient.SqlCommand("SELECT * FROM xxx", dbConnection)
        rs = cmd.ExecuteReader
        Dim myTrips As New Results(SelectID, TripDay, isDriver, rs.FieldCount - 1)
        While rs.Read
            If IsDBNull(rs("Completed")) Then
                myEndDate = Now()
            Else
                myEndDate = rs("completed")
            End If
             myTrip = New Trip(rs("runID"), _
                               IsDBNull(rs("completed")), _
                               rs("runDate"), _
                               myEndDate, _
                               rs("started"))
            myTrips.Add(myTrip)
        End While
        Return (MyTrips)
    End Function

End Class

В Visual Studio параметры проекта определяют это как находящееся в корневом пространстве имен "Hartley ", и информация о сборке имеет флажок" Сделать сборку COM видимой ".Я также сгенерировал ключ и добавил его в проект.

Когда я "строю решение", я должен делать это с Visual Studio, работающей от имени администратора, потому что он хочет записать в реестр.Просматривая реестр, я вижу, что есть записи в реестре для "Hartley.Trips".

Для поиска в Интернете существует множество инструкций, чтобы сделать это - и я, кажется, следовал им всем, ЗА ИСКЛЮЧЕНИЕМ запускаинструменты командной строки.Что сбивает с толку, так это то, что Visual Studio 2010, кажется, запустил их для меня - и, учитывая все инструкции, которые я могу найти, применимы к более ранним версиям Visual Studio - похоже, они этого не сделали.Я пытался запустить эти программы вручную из командной строки Visual Studio, но, похоже, это ничего не изменило.

Так что я застрял.Это не работает, сценарий очень неприятен из-за того, что он не может создать объект, и я не знаю, как двигаться дальше.Поэтому я обращаюсь к советам относительно того, что я могу делать неправильно, как я могу узнать больше о том, что не работает, и т.является частью проблемы, и сейчас я пытаюсь создать сборку, которая разделяет классы на отдельные определения классов верхнего уровня, каждый из которых является собственным COM-объектом.Классы, которые в настоящее время имеют функцию New с параметрами, должны иметь функцию New без них и некоторую форму функции Friend для их инициализации (я не хочу, чтобы функция инициализации была видимой, так как другие классы читаютсятолько результаты).

1 Ответ

2 голосов
/ 19 октября 2011

Напишите некоторый код VB.NET для проверки вашего COM-компонента.CLR генерирует гораздо лучшие сообщения об ошибках.

У вас могут возникнуть такие проблемы в 64-битной операционной системе.Среда IDE регистрирует компонент COM только для 32-разрядных приложений.Вам придется использовать 32-разрядный интерпретатор сценариев (c: \ windows \ syswow64 \ wscript.exe) или запустить 64-разрядную версию Regasm.exe, чтобы зарегистрировать компонент для 64-разрядных приложений с параметром / codebase.

Избегайте вложенных классов, COM не имеет эквивалента для этого.Наиболее естественный способ объявить видимое объявление COM - это ключевое слово Interface .Именно то, что вам нужно здесь для класса Results.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...