Как я могу исправить ошибку времени выполнения 430 из-за импорта пользовательской DLL в проект VBA

Я боролся с этим несколько часов и не могу найти, что я делаю неправильно.

Я создал новый проект DLL С#, вот содержимое единственного класса, который он содержит:

using System;
using System.Runtime.InteropServices;

namespace PolygonSl {

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class Config {

        [ComVisible(true)]
        public string GetCompany() {
            return "POL";
        }
    }
}

Я в основном удаляю из него все, пытаясь заставить его работать, единственная ссылка — System.

Я проверил флаг Make assembly COM-Visible на Assembly Information, и мой проект подписан (требуются швы для кодовой базы).

Компилируется нормально, после этого я вызвал RegAsm.exe, дал ей свою dll, добавил /codebase и /tlb, команда прошла успешно.

Когда я перехожу к своему проекту VBA, я могу добавить свой новый файл tlb в ссылки, и он работает нормально. После этого я могу использовать его в своем коде, автозаполнение работает, и я могу компилировать без ошибок.

Затем, когда я выполняю, я получил это:

Run-time error '430':
Class does not support Automation or does not support expected interface

Вот мой пример кода в VBA:

Private Sub Button1_Click()
    'With CreateObject("PolygonSl.Config")
    With New PolygonSl.Config
        MessBox .GetCompany, MB_OK, "Test"
    End With
End Sub

Я попробовал позднее связывание, и мой код работает с ним нормально, но я хотел бы иметь возможность использовать автозаполнение.

У кого-нибудь есть предложение о том, что я мог бы попытаться заставить его работать?

Изменить (добавление некоторых сведений о моей среде)

  • Я работаю над VS2008 для проектов, связанных с Dynamics SL (одна из ERP Microsoft).
  • Я использую Windows Server 2008 R8 Standard, работаю с VMWare.
  • Компиляция на платформе Framework 3.5, Release, x86, клиент Dynamics SL — 32-разрядный.
  • Я попробовал свою dll в Dynamics, а также в Excel, чтобы убедиться, что проблема не в Dynamics;)

Самая основная причина заключается в том, что вы изменили DLL, но забыли удалить и добавить измененный .tlb в свой проект VBA. Или просто забыли снова запустить Regasm, одна из веских причин позволить VS делать это автоматически.

Hans Passant 10.04.2019 19:21

@HansPassant, у меня есть созданный мной файл cmd, который каждый раз регенерирует файл tbl. Я почти уверен, что каждый раз запускаю regasm unregister и register, так как это никогда не срабатывало, я внимательно слежу за каждым шагом. Я только что попытался проверить регистрацию для COM-взаимодействия (после того, как отменил регистрацию другого), и у меня тот же результат, только работает поздняя привязка.

Alex Dupuis 10.04.2019 19:31

@HansPassant, в мониторе процессов я вижу запись класса и интерфейса RegAsm (мой фактический код такой же, как у Freeflow). Но когда я смотрю на свою программу, я вижу, что она читает хороший класс, но не читает интерфейс. После этого много чего не находит но ничего с clsid.

Alex Dupuis 10.04.2019 20:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вам нужно определить интерфейс, чтобы иметь возможность видеть getcompany.

using System;
using System.Runtime.InteropServices;

namespace PolygonSl
{
    [Guid("6DC1808F-81BA-4DE0-9F7C-42EA11621B7E")]
    [System.Runtime.InteropServices.ComVisible(true)]
    [System.Runtime.InteropServices.InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IConfig
    {
        string GetCompany();
    }

    [Guid("434C844C-9FA2-4EC6-AB75-45D3013D75BE")]
    [System.Runtime.InteropServices.ComVisible(true)]
    [System.Runtime.InteropServices.ClassInterface(ClassInterfaceType.None)]
    public class Config : IConfig
    {
        public string GetCompany()
        {
            return "POL";
        }
    }
}

Вы можете сгенерировать интерфейс автоматически, поместив курсор в определение класса и используя Edit.Refactor.ExtractInterface.

Я должен признать, что здесь я нахожусь на пределе своих возможностей, и вышеизложенное составлено на основе примеров, которые я видел в других местах.

Редактировать

Следующий тестовый код отлично работает на моем ПК

Option Explicit
Sub polygontest()

    Dim my_polygon As SOPolygon.Config
    Set my_polygon = New SOPolygon.Config
    Debug.Print my_polygon.GetCompany

End Sub

Где SOPolygon — название проекта.

У меня точно такой же результат. При использовании ссылки я получил ошибку, но позднее связывание работает так же, как и раньше.

Alex Dupuis 10.04.2019 17:19

@AlexDupuis: Может ли это быть так же просто, как тот факт, что вы используете MessBox, а не MsgBox? Я добавил код VBA для теста, который правильно возвращает POL на моей машине. Пожалуйста, убедитесь, что у вас есть Option Explicit в качестве первой строки в каждом из ваших модулей/классов.

freeflow 10.04.2019 18:00

Да, у меня был Option Explicit, а MessBox — это что-то из приложения, которое я использую (Dynamics SL). Чтобы быть уверенным, я скопировал оба ваших источника и вставил их на свою сторону, я даже использовал Excel, и у меня тот же результат. Может быть, это что-то в моей настройке. Я использую VS2008, FW 3.5, компилирую в Release x86.

Alex Dupuis 10.04.2019 18:56

Я использую VS2019Community, FW 4.5. Подозреваю, что дело может быть в этом.

freeflow 11.04.2019 11:18

Попробую обновиться на снапшоте этого сервера, чтобы быть уверенным, что ничего не тормозит ;)

Alex Dupuis 11.04.2019 14:55

Вы можете найти эту ссылку полезной. bestsolutions.com/csharp/excel-interop/… В VS2017 и 2019 нет необходимости выполнять regasm отдельно, если в диалоговых окнах свойств проекта отмечены все правильные поля.

freeflow 11.04.2019 15:58

У меня есть доступ к VS2017 в другой системе, я создал точно такой же проект и скопировал DLL на виртуальную машину, использовал RegAsm, и он отлично работал. Возможно что-то не так с 2008. Я проверю, чтобы установить его на свою виртуальную машину.

Alex Dupuis 11.04.2019 17:13

Другие вопросы по теме