Как написать 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 не будет опубликован. Обязательные поля помечены *