使用从VBScript可见的Visual Studio 2010创建COM对象从命令行运行 [英] Struggling creating a COM object with Visual Studio 2010 which is visible from VBScript run from the command line

查看:199
本文介绍了使用从VBScript可见的Visual Studio 2010创建COM对象从命令行运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试在Visual Studio(2010)中创建一个COM对象,在 VB.NET ,它可以从命令行运行的 VBScript 程序中调用。我希望脚本能够做像... ...

I am struggling trying to build a COM object in Visual Studio (2010) in VB.NET which can be called from a VBScript program run from the command line. I want the script to be able to do something like ...

Option Explicit
Dim trips
Dim results

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

但是无论我做什么,这个脚本都会失败:

However whatever I do, this script fails with:

ActiveX组件无法创建对象:'Hartley.Trips

ActiveX component can't create object:'Hartley.Trips

COM对象的核心定义是...

The core of the COM object definition is ...

<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可见选中。我也生成了一个键,并添加到项目。

In Visual Studio, the project parameters specify this as sitting within a root namespace of "Hartley" and the assembly information has the "Make Assembly COM visible" checked. I have also generated a key and added that to the project.

当我构建解决方案,我必须这样做Visual Studio以管理员身份运行,因为它想写入注册表。查看注册表,我可以看到Hartley.Trips有注册表项。

When I "build the solution", I have to do so with Visual Studio running as Administrator because it wants to write to the registry. Looking at the registry, I can see that there are registry entries for "Hartley.Trips".

在互联网上搜索,有很多说明,我似乎已经跟着他们所有EXCEPT运行命令行工具。这里令人困惑的是,Visual Studio 2010似乎已经为我运行它们 - 并且给出了我可以找到的所有说明适用于早期版本的Visual Studio - 它似乎没有。我试图从Visual Studio命令行手动运行这些程序,但它似乎没有改变的事情。

Searching around the Internet, there are plenty of instructions to do this - and I appear to have followed them all EXCEPT running the command line tools. What is confusing here is that Visual Studio 2010 appears to have run them for me - and given all the instructions that I can find apply to earlier versions of Visual Studio - it appears they didn't. I have tried running these programs manually from Visual Studio Command Line, but it didn't seem to change things.

现在我被卡住了。它不工作,脚本非常不确定为什么它不能创建对象,我不知道如何前进。所以我正在寻找关于我可能做错了什么,我怎么可以找出更多的什么是不工作等建议。

So now I am stuck. It doesn't work, the script is very unforthcoming about why it can't create the object, and I don't know how to move forward. So I am looking to advice as to what I might be doing wrong, how I can find out more about what is not working ,etc.

正如一个后记,我我想知道一个类中的嵌入式类是否是问题的一部分,我现在正在尝试构建一个集合,将类分离成独立的顶级类定义,每个作为自己的COM对象。当前具有带参数的 New 函数的类必须有一个 New 函数, code> Friend 函数来初始化它们(我不想让初始化函数可见,因为其他类都是只读结果)。

Just as a postscript, I am wondering if the embedded class within a class is part of the problem and am now trying to build an assembly which separates the classes into separate top level class definitions each as their own COM object. The classes which currently have a New function with parameters will have to have a New function without them and some form of Friend function to initialise them (I don't want the initialize function visible as the other classes are read only results).

推荐答案

编写一些VB.NET代码来测试你的COM组件。 CLR生成更好的错误消息。

Write some VB.NET code to test your COM component. The CLR generates much better error messages.

在64位操作系统上,你会遇到这样的问题。 IDE仅注册32位应用程序的COM组件。您将必须使用32位脚本解释器(c:\windows\syswow64\wscript.exe)或运行64位版本的Regasm.exe来注册组件的64位应用程序与/ codebase选项。

You will have trouble like this on a 64-bit operating system. The IDE only registers the COM component for 32-bit apps. You'll have to use the 32-bit script interpreter (c:\windows\syswow64\wscript.exe) or run the 64-bit version of Regasm.exe to register the component for 64-bit apps with the /codebase option.

避免嵌套类,COM没有等价的。声明COM可见声明的最自然方式是使用接口关键字。这里是你需要的结果类。

Avoid nested classes, COM has no equivalent for that. The most natural way to declare a COM visible declaration is with the Interface keyword. Exactly what you need here for the Results class.

这篇关于使用从VBScript可见的Visual Studio 2010创建COM对象从命令行运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆