Привет! В данной статье я расскажу, как вы можете создать свой 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"); //заставим компьютер говорить по-русски
КонецПроцедуры
Теперь остается запустить обработку увидеть результат и прослушать речь про любовь компьютера к майонезу, чесноку, пельменям и водке:)
Вот и все ребят! Буду рад вашему плюсу к статье.
Все примеры описанные в публикации вы можете найти в архиве в приложении.
Очень интересно, спасибо.
Автор напиши пожалуйста публикацию,dll которая берет на входе: папку, текущего пользователя и качество картинки, а по результату сохраняет её в указанную папку с указанным качеством скринешет с именем содержащим имя пользователя и текущую дату и время. Вот это было бы круто :), а не то иногда такое в практике требуется…
akomar, спасиба.
Arch_1, «папку, текущего пользователя и качество картинки, а по результату » — не совсем понял что имелось ввиду..
Интересно! Обычно пишут приблуды с COM соединением от Win к 1С, а тут РЕВЕРС. Может где и пригодится! СПАСИБО!!!
А в чём «Для 1С-ность» этого COM объекта? Обычный COM вроде… 2-ой курс института, в продвинутых институтах 1-ый. А вот «иллюстрированное руководство» по NativeAPI или хотя бы по «1С-ным» COM (внешние события которых 1С может обрабатывать) было бы очень в тему.
Я думаю была задача сделать пример, а не что то готовое к использованию.
(5) comol, (6) sertrain, именно как пример, я подумал что ограничиваться лишь «Hello world!» довольно скучно, а так повеселее и методы класса довольно просты. Практическое использование зависит от фантазии самого разработчика 😀
(5) comol, на Delphi тут лежит пример NativeAPIhttp://infostart.ru/public/88060/
(8) Belomor, Delphi…. а оно ещё живо? И на нём даже кто-то что-то пишет? :))))
(9) comol, А чем Delphi XE3 хуже других средств ООП ??? По моему firemonkey поддерживает наисовременнейший интерфейс и мультиплатформенность!
(10) cvmbackup, Да про delphi я не говорю вообще — оно хуже по определению… только потому что в основе Pascal с его защитной типизацией. А это досвидос полиморфизм, виртуальные ф-ции и прочие прелести.
В своё время достаточно много народу писали на глючном и тормознутом C++ Builder-e, потому как у MS было только VS6, в котором почти полностью отсутствовало IDE, а QT ещё было в зародыше…. Потом у MS появился пусть и не менее тормознутый, но гораздо более безглючный C# уже с user-friendly IDE (да такой что дальше некуда). И где сейчас на рынке место Delphi вообще непонятно…
(11) comol, В моей конторе пишут на Delphi XE.
И полиморфизм и перегрузка операций и виртуальные функции и кучи ещё прелестей (атрибуты, хелперы, генерики, полный rtti всего и вся и т.п.). И ещё x64 в XE2. И поддержка MacOS и iOS (хотя не нативная по сути).
Да это не С++. Но если его покупают (а покупают не только из-за поддержки, т.к. и Delphi 7 и ниже нормально работают) — то значит кому-то нужен. А если его ещё и развивают — значит нужен он не такому уж маленькому количеству людей (Для Embarcadero он ещё приносит прибыть). Я тоже думал что он практически умер, а пришёл в эту контору и приятно удивился.
(10) cvmbackup, Ну FireMonkey я бы ещё не рекламировал… Мой начальник при выходе XE3 его поставил и попытался использовать их демку с FireMonkey. Ну что сказать — проект в метро интерфейсе запустился, а закрыться не смог. Пришлось убивать процесс. Вот и FireMonkey 2…
(7) А неужели кто-то задавал вопросы про COM на C#? Я, до этого, полагал, что это в Visual Studio сделать может почти каждый.
(8) Belomor, Спасибо, это намного интереснее
(5) comol, вот здесь готовый шаблон COM ВК с поддержкой внешних событий для 1С:http://infostart.ru/public/140411/
(12) EmpireSer, Безусловно кому-то нужен и не такому маленькому количеству людей. Студентов ведь много ещё пока :). Блин… вот прямо заинтриговали… как можно было умудриться к паскалю (!!!) прикрутить полиморфизм (!!!!). Это по-моему всё равно что на 1С движок для 3D игр писать :))).
(14) Kuzja_R, Шаблон это не проблема… они уже давно есть.. а вот какой-нить мануальчик если бы для людей как здесь подробный написали… «великое дело» было бы (так то события сделать, так то обрабатывать, так параметры передавать, такие то требования к параметрам и т.п.)…
(15) comol, Я что-то не понял почему полиморфизм это не для Delphi (не для паскаля, а именно для Delphi (а он официально язык)) ? Я тут вообще проблемы не вижу и не видел (ну на Delphi 7 его, в полной мере, реализовать сложнее…)
Да и 3D на нём уже пишут :Р FireMonkey реализует его как раз.
У каждого языка своя специфика и, как говорят умные люди, нужно не только пытаться использовать, для решения задачи, то, что лучше всего подходит, но и то, что лучше всего знает команда :)))
(16) comol, А вот я не видел шаблона как подружить 1С и Java. Или Python или Perl или Ruby. А вот как подружить 1С и PHP я уже, случайно, узнал. Если будет время — сделаю компоненту (конечно там будет через «костыль», но всё же работать, думаю, будет).
(17) EmpireSer, Я уже к счастью плохо помню паскаль… но помню что с указателями жесть… если в C++ воспринимаешь как ссылку на область памяти, то в паскале преобразуешь к типу обязательно, не можешь записать больше чем объявил, не можешь выполнять операции ну и прочая другая чушь.
Потом каким то хитрым образом в паскаль ввернули ООП и появился Delphi, вроде и с типизацией стало чуть получше, хотя не уверен.
Особенно долго я матерился когда понял в своё время что STL в паскале не было, нет и быть не может… А кто на C++ без STL писал в последнее время? Думаю единицы…
О да… Java 1С Вот уж точно не хватало… чтобы пользователь наверняка успевал заснуть пока приложение запустится :).
(18) comol, Простите, но у Вас слишком предвзятое отношение.
Если делать глупые программные ошибки, то и С++ и чистый С не спасут от ужасного расхода памяти и тактов процессора.
Я рад, что сообщество создаёт возможность применения в 1С любой ВК на любом языке и так же в любом языке использовать данные из 1С.
STL, Boost — это библиотеки. Для Delphi есть JEDI — очень классная библиотека, в которой можно найти тоже самое и даже больше. Думаю, и в других языках тоже создали развитые библиотеки. Просто это не входит сразу в поставку. Вспомните — когда-то STL и Boost тоже не были в стандарте.
Вот я лучше напишу на С#, на Delphi, на Java или на PHP то, что нужно, чем со своими скудными знаниями напишу это на С++. Меня намного меньше будут, за мои творения, «бить» :))))
(19) EmpireSer, ээээ… STL библиотека шаблонов… В паскале я как то шаблонов не встречал… А Delphi VCL это отдельная история до сих пор удивляюсь приложениям которые открывают окошко и при этом с ними поставляется файлик мегабайт на 10… 🙂
Я не говорю про C++ с ним Delphi сравнивать не правильно… разные цели. Я про C#,с появлением которого у MS появилась нормальная IDE, и Delphi лишилось того преимущества, которое держало с ним кучу разработчиков..
(20) comol, самое интересное, что JEDI JCL тоже имеет шаблоны :)) они просто там в виде специальных комментария, который вызовом bat файла превращаются в код. Кастыль, но хоть что-то :)))
А С# — это умное решение. Оно лишает язык лишних сложностей, тем самым уменьшая порог вхождения в него. По сути также сделали и в 1С со своим языком :)))
А Delphi утратило своих позиций из-за провалов маркетинга, планов развития и т.п., из-за чего кучи языков (развитие которых зависит от определённой компании) теряли позиции. А Microsoft лишь этим воспользовались :))))
(21) EmpireSer, Ну так я и в 1С поддержку шаблонов сделаю :)) комментарии батниками разбирая :)…
Да delphi утратили свои позиции когда перестали быть «монополистом» на IDE. Либо нужно было вложиться и переработать тот же C++ Builder до нормальной полноценной среды, либо… остаться там же где и был…
(22) comol, отличная идея! Когда сделаешь? (шаблоны в 1С)
А то мне очень не хватает в 1С классов, генериков и т.п.
Так что буду с нетерпением ждать реализации 😉
Пытался зарегестирировать всеми описанными способами и свою и авторскую с заменой guid пишет что не удается найти входную сборку или одну из ее зависимых сборок что это может быть?
bissov, скриншот командной строки покажите
Вот!!!
(26) bissov,
ошибка связана с тем что в папке inRelease нет файла HowToComObjectFor1C.dll или что-то с путями намудрили. В общем сделайте так:
скопируйте HowToComObjectFor1C.dll в C:Windowssystem32
затем в командной строке(с админ. правами) пропишите:
cd «C:Windowssystem32»
regasm HowToComObjectFor1C.dll /codebase
ps. через regsvr зарегать не получится т.к это net компонента
Спасибо зарегестрировал и все работает!!!
А есть ли функция которая кирилицу тоже озвучивает? ну русские слова…
(29) bissov, возможно погуглите по словами к примеру «microsoft speech lib russian», «text to speech russian» и т.д
(23) EmpireSer, Круто. работа нашлась… а то я как раз думал чем бы мне заняться 🙂
крута.
Спс 🙂
У меня выдает сообщение 1с «Класс не зарегистрирован», хотя сделал как рекомендовал RainyAugust22.вроде сделал как указано
может кому нибудь и моя поделка для изучения пригодитсяhttp://infostart.ru/public/84246/
А как сделать так, что бы она по русский говорила?
(105) Gazza, руссифицированный speech lib найти. Как вариант от гугля попробовать, если у них интеграция есть.
Подскажите пожалуйста, можно ли сделать вызов DLL из 1с, которая через RemoteApp webkit запускается ?
Добрый день!
Свою библиотеку на C#. Успешно зарегистрировала ее через regasm, но когда пишу в 1с » Cервис = Новый COMОбъект(«AddIn.MyWraper»);» Получаю ошибку: в чем может быть причина?
-2147024891(0x80070005): Access is denied.
(39) azazana, Добрый день. Предполагаю требуется запустить 1С с правами администратора или повысить права пользователя под которым 1С запускается.
Подскажите пожалуйста почему не работает через ЗагрузитьВнешнююКомпоненту(«…..») ?
(41) DenisSapp, добрый день. Это работает только через Новый COMОбъект. Полагаю столкнулись с проблемой установки и вызове компоненты на сервере?
Написала по вашему примеру свою библиотеку. На моем компьютере все работает, а на компьютере пользователя ошибка:
«Secure mode turned on. Operation is not allowed». В чем может быть дело? Не хватает каких-то прав?
(43) azazana, у пользователя администраторские права на компьютере? Если нет, решите проблему с сис. администраторами или дайте пользователю админские права на его компе Не исключено что блокировка может появляться из-за антивируса или подобного ПО. Проверьте стоит ли пункт DEP(Win7): Мой компьютер — Свойства системы — Дополнительно -Быстродействие -Предотвращение выполнения данных — Включить DEP только для основных программ и служб.
Еще особенность 64тный платформе, нужно дополнительно вручную регать компоненту почитайте тут мне помогло с win2008: 1clancer.ru/article/osobennosti_raboty_s_com-obektami_na_64-bitnoj_platforme_1s_predpriyatie_8.2_847
Михаил, огромное вам спасибо за шаблон! Всё просто и понятно, работает даже в фоновых заданиях на сервере, в отличии отЭТОГО . До вашей публикации уже почти руки опустились, но теперь всё получилось. Делал компоненту-драйвер для мультивыгрузки на несколько весов Mettler Toledo через фоновые процессы.
(45) maljaev, спасибо, рад что помогло
Пожалуйста, подскажите. У меня есть 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 не знаю(
Огромное спасибо за эту статью! Очень помогла.
От себя, могу дополнить одним моментом:
Чтобы не регистрировать через regasm, надо добавить полученную сборку в макет 1С, в виде двоичных данных.
Тогда, эту сборку можно вызывать прямо из конфигурации, исключительно средствами встроенного языка:
Далее можно создавать Com-объект, как вы и написали выше:
(48) Очень интересно, а по подробней можно?
Вот я зарегистрировал свою dll в виде COM, и теперь мне понадобилось что то изменить. Как перезарегистрировать свой COM ?
(50)Вопрос отпал нужно отменить регистрацию ключем /unregister, перекомпилировать проект и опять зарегистрировать с ключем /codebase.
Помогите разобраться! все сделал как написано выше, зарегистрировал и т.п., но при попытке в 1С вызвать конструктор Com объекта выдает ошибку
-2147221005(0x800401F3): Недопустимая строка с указанием класса
(52) проблема решена: билдил библиотеку под 64бит, 1С (64бит) отказывалась ее кушать, под x86 все норм