none
Немогу использовать CoInitializeSecurity в Visual Basic. RRS feed

  • Общие обсуждения

  • Помогите пожалуйста разобраться!!!

    Я самоучка и пытаюсь использовать функции COM объекта, в моем случае LoodsmanServerApplication, для моего приложения под программу Лоцман. В описании, которое было получено от разработчиков PLM системы Лоцман, мне необходимо использовать функцию CoInitializeSecurity перед использованием соответствующей библиотеки. И я написал код в Visual Basic 2005 для соединения с сервером:

    Public Class ConnectToSP

        Public _serverf2 As LoodsmanServerApplication.MainSystem
        Public f2errorCode, f2errorMessage As Object
        Dim ReturneCode As Integer

        Private Function ConnectToServer(ByVal serverName As String) As LoodsmanServerApplication.MainSystem
       
      ConnectToServer = CType(Activator.CreateInstance(Type.GetTypeFromCLSID(New Guid("{392BA982-A82F-44AB-BA8A-69BE25199F73}"), serverName, False)), LoodsmanServerApplication.MainSystem)

        End Function

        Public Sub AssertErrorCode2()
            If ReturneCode <> 0 Then
                MessageBox.Show("Ошибка подключения к БД")
                Throw New ApplicationException(CStr(f2errorMessage))
            End If
            ReturneCode = 0
        End Sub

        Public Sub ConnectToLoodsmanBase()
            If Form1._DBName = "" Or Form1._ServerName = "" Then
                MessageBox.Show("Отсутствуют параметры настройки! Обратитесь к Администратору!")
            Else
                Try
                    _serverf2 = ConnectToServer(Form1._ServerName)


                Catch ex As ApplicationException
                    MessageBox.Show(ex.Message, "Ошибка подключения")
                End Try
                If Form1._DBName <> "" Then
                    _serverf2.ConnectToDB(Form1._DBName, f2errorCode, f2errorMessage)
                    _serverf2.SetFormat("IDataSet", f2errorCode, f2errorMessage)

                    ReturneCode = CInt(Form1.errorCode)
                    AssertErrorCode2()
                End If
            End If
        End Sub

    End Class

    При этом не могу использовать функцию Windows CoInitializeSecurity из библиотеки ole32.dll . Подключить библиотеку тоже не могу - отказывается. В результате мое приложение постоянно вылетает, после определенного количества обращений к серверу с ошибкой

    InvalidCastException was unhandled

    Unable to cast COM object of type 'Loodsman.DataSetClass' to interface type 'Loodsman.IDataSet'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{60446488-9D7B-4776-866E-7EE647F72972}' failed due to the following error: Сервер RPC недоступен. (Exception from HRESULT: 0x800706BA).

    Пожалуйста помогите разобраться, что можно сделать для использования функции CoInitializeSecurity, или что можно использовать в Visual Basic 2005 как аналог CoInitializeSecurity. Если возможно, то с примером.

    • Изменен тип I.Vorontsov 25 августа 2010 г. 8:32
    • Перемещено Tagore Bandlamudi 3 октября 2010 г. 0:23 MSDN Forums consolidation (От:Форум по .NET Framework)
    5 августа 2010 г. 7:58

Все ответы

  • Проверь лог (Event Log) на предмет ошибок dcom.
    5 августа 2010 г. 8:34
  • Возникают ошибки, которые связаны с групповой политикой, к примеру 1030. Но на сколько я понимаю, функция CoInitializeSecurity как раз и решает данную проблему. Ведь само приложение (плагин) пытается работать с COM от имени пользователя, а не администратора. Таким образом запуск COM на сервере не должен происходить, но COM запускается и работает, правда не долго. Потом происходит разрыв соединения, примерно через 3-4 секунды. Видимо поэтому и нужна эта функция, так как с помощью нее искусственно задаются права администратора на время работы с приложением, для запуска COM на сервере. Я так это понял!!! Единственный вопрос, который у меня остался - как это все реализовать в Visual Basic!!! Если это сделать, то проблема должна отпасть сама собой.
    5 августа 2010 г. 9:20
  • Извини, не вчитался в первое сообщение :(
     
    Посмотри статью http://www.pinvoke.net/default.aspx/ole32/coinitializesecurity.html. Там есть пример на C#, с описанием подводных камней.
    5 августа 2010 г. 9:49
  • Эту ссылку я уже давно читал и то, что там предлагают я пробывал, но к сожалению ни чего не получилось или я что то не так делаю. А как правильно не знаю уже ...

    То как она описывается, вроде как без ошибок, в Visual Basic:

    Пример того как пытался это сделать в Visual Basic:

    Declare Function CoInitializeSecurity Lib "ole32.dll" (ByVal pVoid As IntPtr, _
       ByVal cAuthSvc As Integer, ByVal asAuthSvc() As Net.AuthenticationSchemes, _
       ByVal pReserved1 As IntPtr, ByVal dwAuthnLevel As Integer, ByVal dwImpLevel As Integer, _
       ByVal pAuthList As IntPtr, ByVal dwCapabilities As Integer, ByVal pReserved3 As IntPtr) As Integer

    CoInitializeSecurity(IntPtr.Zero, -1, Nothing, IntPtr.Zero, 0, 4, IntPtr.Zero, 0, IntPtr.Zero)

    А мне бы понять как описать ниже приведенный пример из С++ для Visual Basic 2005.

    Пример использования в C++

    Пример использования

    hr = ::CoInitializeSecurity(

                   NULL,

                    -1,

                    NULL,

                    NULL,

                    RPC_C_AUTHN_LEVEL_NONE,

                    RPC_C_IMP_LEVEL_DELEGATE, /* 4 */

                    NULL,

                    0,

                    NULL

                             );

    5 августа 2010 г. 11:29
  • Вроде правильно пытался. Что вернул CoInitializeSecurity в примере на VB?
    5 августа 2010 г. 17:26
  • Все!!! Нашел!!! )))  Для тех кто мучается такой же проблемой как и я смотрите здесь http://support.microsoft.com/kb/239561/ru. В том, что я делал CoInitializeSecurity возвращал значение больше 0, что собственно не верно. В общем завтра буду пробывать. Спасибо PashaPash!!!
    5 августа 2010 г. 17:43
  • Не хочу огорчать, но по линку пример для 6-го VB, который не .net.

    Аналог на .net выглядит примерно так, как код из твоего предыдущего поста. Единственное, что можно попробовать поменять - сделать объявить третий параметр как IntPtr, и передать IntPtr.Zero. В остальном - там полный аналог вызова на C++.

    5 августа 2010 г. 18:46
  • Да ..., но собственно третий параметр нельзя объявить как IntPtr.Zero, т.к. это ошибка, ведь третий параметр является массивом.
    6 августа 2010 г. 4:51
  • Третий параметр - SOLE_AUTHENTICATION_SERVICE *asAuthSvc, обычный указатель. Никаких System.Net.AuthenticationSchemes там не долно быть Объяви как 

     

    Declare Function CoInitializeSecurity Lib "ole32.dll" (ByVal pVoid As IntPtr, _
      ByVal cAuthSvc As Integer, ByVal asAuthSvc As IntPtr, _
      ByVal pReserved1 As IntPtr, ByVal dwAuthnLevel As Integer, ByVal dwImpLevel As Integer, _
      ByVal pAuthList As IntPtr, ByVal dwCapabilities As Integer, ByVal pReserved3 As IntPtr) As Integer
    

     

    и вызывай с Zero.

    6 августа 2010 г. 7:43
  • Я уже как только не пытался, но значение все равно получается -2147417831.

    Вот как я это делаю:

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ProvIniFile()
            LoodsmanBaseConnect()
            hr = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero, 2, 4, IntPtr.Zero, 0, IntPtr.Zero)
            'MessageBox.Show(CStr(hr))
            NameBaseVisible()
            SpisokNaryadovISZ()
            IDisposeClass.Dispose()
        End Sub

    Кстати пример для VB6 работает также.

    Может еще что то надо писать???

     

    9 августа 2010 г. 6:15
  • -2147417831 - это RPC_E_TOO_LATE, значит что CoInitializeSecurity уже был вызван. В статье по ссылке выше написано как это обойти, кусок от Yahor Sinkevich.
    9 августа 2010 г. 9:24
  • Написал для VB:

    Imports System.Threading

    Declare Function CoInitializeSecurity Lib "ole32.dll" (ByVal pVoid As IntPtr, ByVal cAuthSvc As Integer, ByVal asAuthSvc As IntPtr, _
                                                           ByVal pReserved1 As IntPtr, ByVal dwAuthnLevel As Integer, ByVal dwImpLevel As Integer, _
                                                           ByVal pAuthList As IntPtr, ByVal dwCapabilities As Integer, ByVal pReserved3 As IntPtr) As Integer

            Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim t As New Thread(AddressOf ThreadProc)
            t.SetApartmentState(ApartmentState.STA)
            hr = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero, 2, 4, IntPtr.Zero, 0, IntPtr.Zero)
            t.Start()

            ProvIniFile()
            LoodsmanBaseConnect()
            NameBaseVisible()
            SpisokNaryadovISZ()
            IDisposeClass.Dispose()
        End Sub

        Private Sub ThreadProc()
            Thread.Sleep(2000)
        End Sub

    Но проблемы моей это так и не решило. hr=o и все вроде бы должно быть нормально, но работать программа не желает.

    Ладно!!! Буду писать еще раз разработчикам.

    10 августа 2010 г. 9:23