Как написать COM-объект для 1С на Visual Studio C# 2008

Расширяем функционал 1С с помощью разработки подключаемого COM-объекта! Пишем код на Visual C# 2008 для открытия CD-ROM’а, получения списка процессов и использования возможностей системы text-to-speech.

Привет! В данной статье я расскажу, как вы можете создать свой COM-объект для 1С с помощью Visual C# 2008.

Для этого на понадобится собственно сам Microsoft Visual Studio 2008 с предустановленным .NET Framework 3.5, 1С Предприятие 8.2 и желание 🙂

Начнем с того что запустим Microsoft Visual Studio 2008 от имени администратора, делается это так правой кнопкой по ярлыку(рис.1 ):

рис.1

 

Далее создадим новый проект File->New->Project, выбираем Class Library(рис.2)

рис.2

Студия сформирует шаблон класса следующего содержания:

рис.3

Удаляем все пишем заново код приведенный ниже:

        //1. подключаем необходимые пространства имен
        using System;
        using System.Text;
        using System.Runtime.InteropServices;
        using SpeechLib;

  
        //2. описываем наше пространство имен, собственно так и будет называется наш COM-объект
        namespace HowToComObjectFor1C
        {
        //3. объявляем интерфейс для класса, создаем GUID с помощью утилиты "C:Program FilesMicrosoft SDKsWindowsv6.0ABinguidgen.exe" поясняю, запускаем утилиту устанавливаем значение на п.4 нажимаем Copy переносим в наш код:

рис.4

        [Guid("6844AACB-9194-46bf-81AF-9DA73EE687DC")]
        internal interface IMyClass
        {
            [DispId(1)]
            //4. описываем методы которые можно будет вызывать из вне
            string PrintIn1C(string mymessage);
            void OpenCD(bool MyParam);
            string GetAllSystemProcess();
            void SpeakVoice(string SpeakText);
        }

        //5. определим интерфейс для COM-событий(GUID получаем и записываем с помощью утилиты guidgen.exe)
        [Guid("70DD7E62-7D82-4301-993C-B7D919430990"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        public interface IMyEvents
        {
        }

        //6. описываем класс реализующий интерфейсы(GUID получаем и записываем с помощью утилиты guidgen.exe)
        [Guid("69EE0677-884A-4eeb-A3BD-D407844C0C70"), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IMyEvents))]
        public class MyClass : IMyClass //название нашего класса MyClass
        {
            string StringProcess; //строковая переменная для функции ниже
            [DllImport("winmm.dll")] //подключаем dll для процедуры ниже
            static extern Int32 mciSendString(String command, StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback);
            //простенькая функция которая вернет строку в 1С которую мы также пошлем из 1С, можете написать ей Hello World к примеру
            public string PrintIn1C(string mymessage)   
            {
                return mymessage;
            }
            //процедура для открытия/закрытия CD-ROM’а из 1С 😉
            public void OpenCD(bool MyParam)
            {
                if (MyParam)
                {
                    mciSendString("set CDAudio door open", null, 0, IntPtr.Zero);
                }
                else
                    mciSendString("set CDAudio door closed", null, 0, IntPtr.Zero);
            }
            //получаем список процессов и передаем 1С
            public string GetAllSystemProcess()
            {
                foreach (System.Diagnostics.Process winProc in System.Diagnostics.Process.GetProcesses())
                {  
                    StringProcess = StringProcess + "
Process " + winProc.Id + ": " + winProc.ProcessName;
                }
                return StringProcess;
            }
            //кое-что поинтересней процедура для вызова "говорящего компьютера" передаем ей текст, а она нам голосом!:)
            public void SpeakVoice(string SpeakText)
            {
                SpVoice voice = new SpVoice();
                voice.Speak(SpeakText, SpeechVoiceSpeakFlags.SVSFDefault);
            }   
        }
        }

 

Теперь когда код написан, нужно в свойствах проекта

рис.5

включить галочку Register for COM interop на закладке Build.

рис.6

Подписать сборку уникальными именем (StrongName). На закладке свойств проекта: Properties — Signing — Sign the Assembly — далее, нужно указать имя файла ключа. Пароль указывать не обязательно. Будет автоматически создан файл *.snk, в данном случае, было указано имя ComObjectFor1C.snk

рис.7

В файле AssemblyInfo.cs нужно указать параметр, содержащий имя файла подписи и параметр ComVisible установить true:

рис.8

Чуть не забыли добавить в проект расширение SpeechLib для "говорилки", правой кнопкой по проекту Add Reference…

рис.9

Приступим к компиляции, установим Solution Configuration значение Release, далее меню Build->Build Solution и в результате чего в папке проекта  binRelease получим библиотеку *.dll готовую для регистрации в системе как COM-объект. 

рис.10

Зарегистрировать в системе библиотеку с помощью утилиты regasm.exe, которая находится по умолчанию в папке "C:WINDOWSMicrosoft.NETFrameworkv2.0.50727RegAsm.exe". Удобнее это делать через Visual Studio 2008 Command Prompt(можно найти в "Пуске") запускаем а админискими правами, набираем:

c:Program Files (x86)Microsoft Visual Studio 9.0VC>regasm "C:UsersUserNameDocumentsVisual Studio 2008ProjectsHowToComObjectFor1CHowToComObjectFor1CinReleaseHowToComObjectFor1C.dll" /codebase

 

или через CMD

C:WINDOWSMicrosoft.NETFrameworkv2.0.50727RegAsm.exe "C:UsersUserNameDocumentsVisual Studio 2008ProjectsHowToComObjectFor1CHowToComObjectFor1CinReleaseHowToComObjectFor1C.dll" /codebase
 

совсем ленивые могут запустить батник RegDLL.bat в приложении к публикации.

Если видим сообщение "Типы успешно зарегистрированы" значит все COM-объект зарегистирован.

Переходим к любимой 1С, создаем новую внешнюю обработку на форме по кнопке выполнить пишем:

Процедура КнопкаВыполнитьНажатие(Кнопка)
     МойОбъект = Новый COMОбъект("HowToComObjectFor1C.MyClass");
     Сообщить(МойОбъект.PrintIn1C("Hello from Com-object;)"));
     МойОбъект.OpenCD(Истина);  //открыть CD-ROM, параметр ложь соотвественно закроет его
     Сообщить(МойОбъект.GetAllSystemProcess());
     МойОбъект.SpeakVoice("My оn Ass Chess Knock Pale Man what can i do Yellow blue bus"); //заставим компьютер говорить по-русски
КонецПроцедуры

Теперь остается запустить обработку увидеть результат и прослушать речь про любовь компьютера к майонезу, чесноку, пельменям и водке:)

 

Вот и все ребят!  Буду рад вашему плюсу к статье.

Все примеры описанные в публикации вы можете найти в архиве в приложении.

 

53 Comments

  1. akomar

    Очень интересно, спасибо.

    Reply
  2. Rudakov_D

    Автор напиши пожалуйста публикацию,dll которая берет на входе: папку, текущего пользователя и качество картинки, а по результату сохраняет её в указанную папку с указанным качеством скринешет с именем содержащим имя пользователя и текущую дату и время. Вот это было бы круто :), а не то иногда такое в практике требуется…

    Reply
  3. RainyAugust22

    akomar, спасиба.

    Arch_1, «папку, текущего пользователя и качество картинки, а по результату » — не совсем понял что имелось ввиду..

    Reply
  4. cvmbackup

    Интересно! Обычно пишут приблуды с COM соединением от Win к 1С, а тут РЕВЕРС. Может где и пригодится! СПАСИБО!!!

    Reply
  5. comol

    А в чём «Для 1С-ность» этого COM объекта? Обычный COM вроде… 2-ой курс института, в продвинутых институтах 1-ый. А вот «иллюстрированное руководство» по NativeAPI или хотя бы по «1С-ным» COM (внешние события которых 1С может обрабатывать) было бы очень в тему.

    Reply
  6. sertrain

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

    Reply
  7. RainyAugust22

    (5) comol, (6) sertrain, именно как пример, я подумал что ограничиваться лишь «Hello world!» довольно скучно, а так повеселее и методы класса довольно просты. Практическое использование зависит от фантазии самого разработчика 😀

    Reply
  8. Belomor

    (5) comol, на Delphi тут лежит пример NativeAPI http://infostart.ru/public/88060/

    Reply
  9. comol

    (8) Belomor, Delphi…. а оно ещё живо? И на нём даже кто-то что-то пишет? :))))

    Reply
  10. cvmbackup

    (9) comol, А чем Delphi XE3 хуже других средств ООП ??? По моему firemonkey поддерживает наисовременнейший интерфейс и мультиплатформенность!

    Reply
  11. comol

    (10) cvmbackup, Да про delphi я не говорю вообще — оно хуже по определению… только потому что в основе Pascal с его защитной типизацией. А это досвидос полиморфизм, виртуальные ф-ции и прочие прелести.

    В своё время достаточно много народу писали на глючном и тормознутом C++ Builder-e, потому как у MS было только VS6, в котором почти полностью отсутствовало IDE, а QT ещё было в зародыше…. Потом у MS появился пусть и не менее тормознутый, но гораздо более безглючный C# уже с user-friendly IDE (да такой что дальше некуда). И где сейчас на рынке место Delphi вообще непонятно…

    Reply
  12. EmpireSer

    (11) comol, В моей конторе пишут на Delphi XE.

    И полиморфизм и перегрузка операций и виртуальные функции и кучи ещё прелестей (атрибуты, хелперы, генерики, полный rtti всего и вся и т.п.). И ещё x64 в XE2. И поддержка MacOS и iOS (хотя не нативная по сути).

    Да это не С++. Но если его покупают (а покупают не только из-за поддержки, т.к. и Delphi 7 и ниже нормально работают) — то значит кому-то нужен. А если его ещё и развивают — значит нужен он не такому уж маленькому количеству людей (Для Embarcadero он ещё приносит прибыть). Я тоже думал что он практически умер, а пришёл в эту контору и приятно удивился.

    (10) cvmbackup, Ну FireMonkey я бы ещё не рекламировал… Мой начальник при выходе XE3 его поставил и попытался использовать их демку с FireMonkey. Ну что сказать — проект в метро интерфейсе запустился, а закрыться не смог. Пришлось убивать процесс. Вот и FireMonkey 2…

    (7) А неужели кто-то задавал вопросы про COM на C#? Я, до этого, полагал, что это в Visual Studio сделать может почти каждый.

    Reply
  13. tazmag

    (8) Belomor, Спасибо, это намного интереснее

    Reply
  14. Kuzja_R

    (5) comol, вот здесь готовый шаблон COM ВК с поддержкой внешних событий для 1С: http://infostart.ru/public/140411/

    Reply
  15. comol

    (12) EmpireSer, Безусловно кому-то нужен и не такому маленькому количеству людей. Студентов ведь много ещё пока :). Блин… вот прямо заинтриговали… как можно было умудриться к паскалю (!!!) прикрутить полиморфизм (!!!!). Это по-моему всё равно что на 1С движок для 3D игр писать :))).

    Reply
  16. comol

    (14) Kuzja_R, Шаблон это не проблема… они уже давно есть.. а вот какой-нить мануальчик если бы для людей как здесь подробный написали… «великое дело» было бы (так то события сделать, так то обрабатывать, так параметры передавать, такие то требования к параметрам и т.п.)…

    Reply
  17. EmpireSer

    (15) comol, Я что-то не понял почему полиморфизм это не для Delphi (не для паскаля, а именно для Delphi (а он официально язык)) ? Я тут вообще проблемы не вижу и не видел (ну на Delphi 7 его, в полной мере, реализовать сложнее…)

    Да и 3D на нём уже пишут :Р FireMonkey реализует его как раз.

    У каждого языка своя специфика и, как говорят умные люди, нужно не только пытаться использовать, для решения задачи, то, что лучше всего подходит, но и то, что лучше всего знает команда :)))

    (16) comol, А вот я не видел шаблона как подружить 1С и Java. Или Python или Perl или Ruby. А вот как подружить 1С и PHP я уже, случайно, узнал. Если будет время — сделаю компоненту (конечно там будет через «костыль», но всё же работать, думаю, будет).

    Reply
  18. comol

    (17) EmpireSer, Я уже к счастью плохо помню паскаль… но помню что с указателями жесть… если в C++ воспринимаешь как ссылку на область памяти, то в паскале преобразуешь к типу обязательно, не можешь записать больше чем объявил, не можешь выполнять операции ну и прочая другая чушь.

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

    Особенно долго я матерился когда понял в своё время что STL в паскале не было, нет и быть не может… А кто на C++ без STL писал в последнее время? Думаю единицы…

    О да… Java 1С Вот уж точно не хватало… чтобы пользователь наверняка успевал заснуть пока приложение запустится :).

    Reply
  19. EmpireSer

    (18) comol, Простите, но у Вас слишком предвзятое отношение.

    Если делать глупые программные ошибки, то и С++ и чистый С не спасут от ужасного расхода памяти и тактов процессора.

    Я рад, что сообщество создаёт возможность применения в 1С любой ВК на любом языке и так же в любом языке использовать данные из 1С.

    STL, Boost — это библиотеки. Для Delphi есть JEDI — очень классная библиотека, в которой можно найти тоже самое и даже больше. Думаю, и в других языках тоже создали развитые библиотеки. Просто это не входит сразу в поставку. Вспомните — когда-то STL и Boost тоже не были в стандарте.

    Вот я лучше напишу на С#, на Delphi, на Java или на PHP то, что нужно, чем со своими скудными знаниями напишу это на С++. Меня намного меньше будут, за мои творения, «бить» :))))

    Reply
  20. comol

    (19) EmpireSer, ээээ… STL библиотека шаблонов… В паскале я как то шаблонов не встречал… А Delphi VCL это отдельная история до сих пор удивляюсь приложениям которые открывают окошко и при этом с ними поставляется файлик мегабайт на 10… 🙂

    Я не говорю про C++ с ним Delphi сравнивать не правильно… разные цели. Я про C#,с появлением которого у MS появилась нормальная IDE, и Delphi лишилось того преимущества, которое держало с ним кучу разработчиков..

    Reply
  21. EmpireSer

    (20) comol, самое интересное, что JEDI JCL тоже имеет шаблоны :)) они просто там в виде специальных комментария, который вызовом bat файла превращаются в код. Кастыль, но хоть что-то :)))

    А С# — это умное решение. Оно лишает язык лишних сложностей, тем самым уменьшая порог вхождения в него. По сути также сделали и в 1С со своим языком :)))

    А Delphi утратило своих позиций из-за провалов маркетинга, планов развития и т.п., из-за чего кучи языков (развитие которых зависит от определённой компании) теряли позиции. А Microsoft лишь этим воспользовались :))))

    Reply
  22. comol

    (21) EmpireSer, Ну так я и в 1С поддержку шаблонов сделаю :)) комментарии батниками разбирая :)…

    Да delphi утратили свои позиции когда перестали быть «монополистом» на IDE. Либо нужно было вложиться и переработать тот же C++ Builder до нормальной полноценной среды, либо… остаться там же где и был…

    Reply
  23. EmpireSer

    (22) comol, отличная идея! Когда сделаешь? (шаблоны в 1С)

    А то мне очень не хватает в 1С классов, генериков и т.п.

    Так что буду с нетерпением ждать реализации 😉

    Reply
  24. bissov

    Пытался зарегестирировать всеми описанными способами и свою и авторскую с заменой guid пишет что не удается найти входную сборку или одну из ее зависимых сборок что это может быть?

    Reply
  25. RainyAugust22

    bissov, скриншот командной строки покажите

    Reply
  26. bissov

    Вот!!!

    Reply
  27. RainyAugust22

    (26) bissov,

    ошибка связана с тем что в папке inRelease нет файла HowToComObjectFor1C.dll или что-то с путями намудрили. В общем сделайте так:

    скопируйте HowToComObjectFor1C.dll в C:Windowssystem32

    затем в командной строке(с админ. правами) пропишите:

    cd «C:Windowssystem32»

    regasm HowToComObjectFor1C.dll /codebase

    ps. через regsvr зарегать не получится т.к это net компонента

    Reply
  28. bissov

    Спасибо зарегестрировал и все работает!!!

    Reply
  29. bissov

    А есть ли функция которая кирилицу тоже озвучивает? ну русские слова…

    Reply
  30. RainyAugust22

    (29) bissov, возможно погуглите по словами к примеру «microsoft speech lib russian», «text to speech russian» и т.д

    Reply
  31. comol

    (23) EmpireSer, Круто. работа нашлась… а то я как раз думал чем бы мне заняться 🙂

    Reply
  32. Zas1402

    крута.

    Reply
  33. RainyAugust22

    Спс 🙂

    Reply
  34. jonpigo

    У меня выдает сообщение 1с «Класс не зарегистрирован», хотя сделал как рекомендовал RainyAugust22.вроде сделал как указано

    Reply
  35. mozz

    может кому нибудь и моя поделка для изучения пригодится http://infostart.ru/public/84246/

    Reply
  36. bayce

    А как сделать так, что бы она по русский говорила?

    Reply
  37. RainyAugust22

    (105) Gazza, руссифицированный speech lib найти. Как вариант от гугля попробовать, если у них интеграция есть.

    Reply
  38. salex2002

    Подскажите пожалуйста, можно ли сделать вызов DLL из 1с, которая через RemoteApp webkit запускается ?

    Reply
  39. azazana

    Добрый день!

    Свою библиотеку на C#. Успешно зарегистрировала ее через regasm, но когда пишу в 1с » Cервис = Новый COMОбъект(«AddIn.MyWraper»);» Получаю ошибку: в чем может быть причина?

    -2147024891(0x80070005): Access is denied.

    Reply
  40. RainyAugust22

    (39) azazana, Добрый день. Предполагаю требуется запустить 1С с правами администратора или повысить права пользователя под которым 1С запускается.

    Reply
  41. DenisSapp

    Подскажите пожалуйста почему не работает через ЗагрузитьВнешнююКомпоненту(«…..») ?

    Reply
  42. RainyAugust22

    (41) DenisSapp, добрый день. Это работает только через Новый COMОбъект. Полагаю столкнулись с проблемой установки и вызове компоненты на сервере?

    Reply
  43. azazana

    Написала по вашему примеру свою библиотеку. На моем компьютере все работает, а на компьютере пользователя ошибка:

    «Secure mode turned on. Operation is not allowed». В чем может быть дело? Не хватает каких-то прав?

    Reply
  44. RainyAugust22

    (43) azazana, у пользователя администраторские права на компьютере? Если нет, решите проблему с сис. администраторами или дайте пользователю админские права на его компе Не исключено что блокировка может появляться из-за антивируса или подобного ПО. Проверьте стоит ли пункт DEP(Win7): Мой компьютер — Свойства системы — Дополнительно -Быстродействие -Предотвращение выполнения данных — Включить DEP только для основных программ и служб.

    Еще особенность 64тный платформе, нужно дополнительно вручную регать компоненту почитайте тут мне помогло с win2008: 1clancer.ru/article/osobennosti_raboty_s_com-obektami_na_64-bitnoj_platforme_1s_predpriyatie_8.2_847

    Reply
  45. maljaev

    Михаил, огромное вам спасибо за шаблон! Всё просто и понятно, работает даже в фоновых заданиях на сервере, в отличии от ЭТОГО. До вашей публикации уже почти руки опустились, но теперь всё получилось. Делал компоненту-драйвер для мультивыгрузки на несколько весов Mettler Toledo через фоновые процессы.

    Reply
  46. RainyAugust22

    (45) maljaev, спасибо, рад что помогло

    Reply
  47. user1036472

    Пожалуйста, подскажите. У меня есть COM-библиотека(hybrid.dll) написанная на C++. В ней внутри есть список констант:

    enum DECLSPEC_UUID(«****») COLOR

    { green = 0x1,

    black = 0x2,

    blue = 0x3

    };

    Вопрос. Как в PHP можно работать с такими константами (как мне вызвать этот список)?

    Пробовал вот так:

    $PHP_LIB = new COM(«HybridLib.HybridCOM») ;

    $PHP_LIB -> COLOR(«green»); и так: $PHP_LIB -> COLOR->green; и так: $PHP_LIB -> COLOR::green;

    Никак не получилось. Всегда ошибку выводит.

    В C# это делается вот так:

    Green = HybridCOMLib.СOLOR.GREEN;

    А в PHP не знаю(

    Reply
  48. Kazey

    Огромное спасибо за эту статью! Очень помогла.

    От себя, могу дополнить одним моментом:

    Чтобы не регистрировать через regasm, надо добавить полученную сборку в макет 1С, в виде двоичных данных.

    Тогда, эту сборку можно вызывать прямо из конфигурации, исключительно средствами встроенного языка:

    СсылкаНаАрхив  = ПоместитьВоВременноеХранилище(ПолучитьМакет(«Макет»), Новый УникальныйИдентификатор);
    ПодключитьВнешнююКомпоненту(СсылкаНаАрхив, «MyClass», ТипВнешнейКомпоненты.COM);
    

    Далее можно создавать Com-объект, как вы и написали выше:

    МойОбъект = Новый COMОбъект(«HowToComObjectFor1C.MyClass»);
    
    Reply
  49. user777376

    (48) Очень интересно, а по подробней можно?

    Reply
  50. user777376

    Вот я зарегистрировал свою dll в виде COM, и теперь мне понадобилось что то изменить. Как перезарегистрировать свой COM ?

    Reply
  51. user777376

    (50)Вопрос отпал нужно отменить регистрацию ключем /unregister, перекомпилировать проект и опять зарегистрировать с ключем /codebase.

    Reply
  52. Nickolas

    Помогите разобраться! все сделал как написано выше, зарегистрировал и т.п., но при попытке в 1С вызвать конструктор Com объекта выдает ошибку

    -2147221005(0x800401F3): Недопустимая строка с указанием класса

    Reply
  53. Nickolas

    (52) проблема решена: билдил библиотеку под 64бит, 1С (64бит) отказывалась ее кушать, под x86 все норм

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *