Аннотация:
Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.
Как в нативе так и в Net. Единственно, что без страниц свойств, которые в большинстве и не нужны. Получить все нужные интерфейсы и вперед. Минимум затрат, максимум комфорта.
и солнце б утром не вставало, когда бы не было меня
А>Авторы: А>Alexey Stolpovskikh
А>Аннотация: А>Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.
1C — работает с COM объектами (есть ограничения, конечно...). Поэтому вполне возможно, что городить огород через внешнюю компоненту для связи с .Net не требуется.
В 8ке работа с COM объектами сделана еще проще. Более того — теперь можно в форму вставить свой ActiveX. При чем Дизайнер форм позволяет теперь сделать обработку событий от этого объекта средствами встроенного языка 1С.
Правда, для внешних компонент в V8 оказались от некоторых возможностей, что были в 7.7. Зато теперь нормальная работа с COM.
Использовать прямой доступ к файлам "1С" плохо — так как есть опасность разрушить реляционную модель прикладных данных построенную Конфигуратором. Для доступа к данным из "1С" лучше всего использовать открытые "интерфейсы" 7.7:
— V77.Appication;
— Технологию Внешних Компонент.
— Файлы для обмена данными.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Serginio1, Вы писали:
S>>Здравствуйте, Аноним, Вы писали:
S>>Помоему проще воспользоваться S>>http://1c.proclub.ru/modules/mydownloads/personal.php?cid=115&lid=2019 S>>http://1c.proclub.ru/modules/mydownloads/personal.php?cid=115&lid=2305
S>> Как в нативе так и в Net. Единственно, что без страниц свойств, которые в большинстве и не нужны. Получить все нужные интерфейсы и вперед. Минимум затрат, максимум комфорта.
А>Использовать прямой доступ к файлам "1С" плохо — так как есть опасность разрушить реляционную модель прикладных данных построенную Конфигуратором. Для доступа к данным из "1С" лучше всего использовать открытые "интерфейсы" 7.7: А> — V77.Appication; А> — Технологию Внешних Компонент. А> — Файлы для обмена данными.
Во первых там ссылка на 20.01.03 Исходник ВК которая загружает Объект Автоматизации поддерживающий ITypeInfo и выполняет все его свойства и методы через IlanguageExtender.
Поддержка Var и Out параметров, передача в методы Объектов 1С, а так же поддержка Свойст Массивов.
То есть делаешь свой Automation Object и ( если нужны данные интерфейсов 1С делаешь метод InitFrom1C) итд. в том числе и на Net
По поводу прямого доступа, то при изменении конфигурации нужно делать перекомпиляцию.
Зато выигрышь по скорости на различных алгоритмах достигает сотни раз.
Во многих задачах обчинка стоит выделки.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Аноним, Вы писали:
А>1C — работает с COM объектами (есть ограничения, конечно...). Поэтому вполне возможно, что городить огород через внешнюю компоненту для связи с .Net не требуется.
Ага, все так. Там даже в 7.5 по части взаимодействия с COM все было примерно как в VBA. По крайней мере попользовать из 1С стандартным образом ADO или Excel — никаких проблем.
А так — круто, конечно. Статья, да еще и про .NET с COM+.
Здравствуйте, Gaperton, Вы писали:
А>>1C — работает с COM объектами (есть ограничения, конечно...). Поэтому вполне возможно, что городить огород через внешнюю компоненту для связи с .Net не требуется. G>Ага, все так. Там даже в 7.5 по части взаимодействия с COM все было примерно как в VBA. По крайней мере попользовать из 1С стандартным образом ADO или Excel — никаких проблем.
Не совсем так, в 7.5 были проблемы со свойствами, которые были устранены в 7.7.
Нынешние проблемы это свойства массивы, передача var (ref) параметров, и передача в оле объекты ссылки на объекты 1С. Городить в ручную ВК достаточно муторно, поэтому оболочки вокруг ILanguageExtender для доступа к IDispatch ным объектам очень упрощают жизнь. Все от потребностей
и солнце б утром не вставало, когда бы не было меня
Re: COM+-компонент для 1С на C#
От:
Аноним
Дата:
06.12.04 10:57
Оценка:
А>Статья:
А>Авторы: А>Alexey Stolpovskikh
А>Аннотация: А>Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.
Добрый день!
Подсткажите пожалуйста, где можно взять рабочий пример к этой статье?
То что описано не работает....
А>Авторы: А>Alexey Stolpovskikh
А>Аннотация: А>Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.
А есть исходники к этой статье?
Re: COM+-компонент для 1С на C#
От:
Аноним
Дата:
24.02.05 11:08
Оценка:
А>Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.
исходники бы посмотреть....
Re[2]: COM+, C# внешняя компонента для 1С
От:
Аноним
Дата:
01.03.05 08:36
Оценка:
Добрый день, ALL
написал свою ВК на VB.NET
компонента загружается, объека создается, все работает, но
необходимо внутри ВК запустить второй поток и по событию (например по таймеру)
лезть за документами в 1С. эта часть тоже работает, но 1С при закрытии
не выгружается из памяти, а если все делать в одно потоке, то выгружатся
причем если в Method1() (вызывается из 1С) создать объект (например Документ.Чек)
и потом работать с ним во втором потоке, то 1С тоже закрывается, но это не выход
у кого есть мнения как побороть?
Здравствуйте, <Аноним>, Вы писали:
А>Добрый день, ALL А>написал свою ВК на VB.NET А>компонента загружается, объека создается, все работает, но А>необходимо внутри ВК запустить второй поток и по событию (например по таймеру) А>лезть за документами в 1С. эта часть тоже работает, но 1С при закрытии А>не выгружается из памяти, а если все делать в одно потоке, то выгружатся А>причем если в Method1() (вызывается из 1С) создать объект (например Документ.Чек) А>и потом работать с ним во втором потоке, то 1С тоже закрывается, но это не выход А>у кого есть мнения как побороть?
Здесь проблемы с подсчетом ссылок. Иногда их невозможно их преодолеть (вернее у меня не получилось).
Вторая проблема может быть с маршалингом интерфейсом, хотя помоему AppDispatch маршализируется (т.е. все вызовы проходят в основном потоке приложения).
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
и солнце б утром не вставало, когда бы не было меня
Внешние компоненты используются в основном не для доступа к данным, а для организации работы с оборудованием и т.п.(например POS терминалы или кассовые аппараты).
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, Serginio1, Вы писали:
S>>Здравствуйте, Аноним, Вы писали:
S>>Помоему проще воспользоваться S>>http://1c.proclub.ru/modules/mydownloads/personal.php?cid=115&lid=2019 S>>http://1c.proclub.ru/modules/mydownloads/personal.php?cid=115&lid=2305
S>> Как в нативе так и в Net. Единственно, что без страниц свойств, которые в большинстве и не нужны. Получить все нужные интерфейсы и вперед. Минимум затрат, максимум комфорта.
А>Внешние компоненты используются в основном не для доступа к данным, а для организации работы с оборудованием и т.п.(например POS терминалы или кассовые аппараты).
А где здесь речь про данные???? В приведенных ссылках речь идет о "Исходник ВК которая загружает Объект Автоматизации поддерживающий ITypeInfo и выполняет все его свойства и методы через IlanguageExtender.
Поддержка Var и Out параметров, передача в методы Объектов 1С, а так же поддержка Свойст Массивов."
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
и солнце б утром не вставало, когда бы не было меня
Re[2]: COM+-компонент для 1С на C#
От:
Аноним
Дата:
02.08.05 01:37
Оценка:
Для работы надо наследовать класс Component;
using System;
using System.Collections;
using System.EnterpriseServices;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
[assembly: Guid("49E484AE-02C4-4c77-A36E-7B4ED0BCE11F")]
[assembly: ApplicationID("49E484AE-02C4-4c77-FFFF-7B4ED0BCE11F")]
[assembly: ApplicationAccessControl(AccessChecksLevel=AccessChecksLevelOption.Application)]
[assembly: ApplicationName("SimpleExternalComponent Application")]
[assembly: ApplicationActivation(ActivationOption.Library)]
[assembly: AssemblyKeyFile("key.snk")]
[Guid("AB634001-F13D-11d0-A459-004095E1DAEA")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInitDone
{
void Init(
[MarshalAs(UnmanagedType.IDispatch)]
object connection);
void Done();
void GetInfo(
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_VARIANT)]
ref object[] info);
}
[Guid("AB634003-F13D-11d0-A459-004095E1DAEA")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ILanguageExtender
{
void RegisterExtensionAs(
[MarshalAs(UnmanagedType.BStr)]
ref String extensionName);
void GetNProps(ref Int32 props);
void FindProp(
[MarshalAs(UnmanagedType.BStr)]
String propName,
ref Int32 propNum);
void GetPropName(
Int32 propNum,
Int32 propAlias,
[MarshalAs(UnmanagedType.BStr)]
ref String propName);
void GetPropVal(
Int32 propNum,
[MarshalAs(UnmanagedType.Struct)]
ref object propVal);
void SetPropVal(
Int32 propNum,
[MarshalAs(UnmanagedType.Struct)]
ref object propVal);
void IsPropReadable(Int32 propNum, ref bool propRead);
void IsPropWritable(Int32 propNum, ref Boolean propWrite);
void GetNMethods(ref Int32 pMethods);
void FindMethod(
[MarshalAs(UnmanagedType.BStr)]
String methodName,
ref Int32 methodNum);
void GetMethodName(Int32 methodNum,
Int32 methodAlias,
[MarshalAs(UnmanagedType.BStr)]
ref String methodName);
void GetNParams(Int32 methodNum, ref Int32 pParams);
void GetParamDefValue(
Int32 methodNum,
Int32 paramNum,
[MarshalAs(UnmanagedType.Struct)]
ref object paramDefValue);
void HasRetVal(Int32 methodNum, ref Boolean retValue);
void CallAsProc(
Int32 methodNum,
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_VARIANT)]
ref object[] pParams);
void CallAsFunc(
Int32 methodNum,
[MarshalAs(UnmanagedType.Struct)]
ref object retValue,
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_VARIANT)]
ref object[] pParams);
}
[ClassInterface(ClassInterfaceType.None)]
[ProgId("AddIn.SimpleExternalComponent")]
//[Description("SimpleExternalComponent.Component class")]public class Component : ServicedComponent,IInitDone
{
//private IAsyncEvent asyncEvent = null;
//private IStatusLine statusLine = null;
Hashtable nameToNumber;
Hashtable numberToName;
Hashtable numberToParams;
Hashtable numberToRetVal;
Hashtable propertyNameToNumber;
Hashtable propertyNumberToName;
Hashtable numberToMethodInfoIdx;
Hashtable propertyNumberToPropertyInfoIdx;
MethodInfo[] allMethodInfo;
PropertyInfo[] allPropertyInfo;
public Component(){
}
public void RegisterExtensionAs([MarshalAs(UnmanagedType.BStr)]
ref String extensionName)
{
try{
// initialize data members
nameToNumber = new Hashtable();
numberToName = new Hashtable();
numberToParams = new Hashtable();
numberToRetVal = new Hashtable();
propertyNameToNumber = new Hashtable();
propertyNumberToName = new Hashtable();
numberToMethodInfoIdx = new Hashtable();
propertyNumberToPropertyInfoIdx = new Hashtable();
// Заполнение хэш-таблиц
Type type = this.GetType();
Type[] allInterfaceTypes = type.GetInterfaces();
// Определение идентификатораint Identifier = 0;
foreach(Type interfaceType in allInterfaceTypes)
{
if (
!interfaceType.Name.Equals("IDisposable")
&& !interfaceType.Name.Equals("IManagedObject")
&& !interfaceType.Name.Equals("IRemoteDispatch")
&& !interfaceType.Name.Equals("IServicedComponentInfo")
&& !interfaceType.Name.Equals("IInitDone")
&& !interfaceType.Name.Equals("ILanguageExtender")
)
{
// Обработка методов
MethodInfo[] interfaceMethods = interfaceType.GetMethods();
foreach (MethodInfo interfaceMethodInfo in interfaceMethods)
{
nameToNumber.Add(interfaceMethodInfo.Name, Identifier);
numberToParams.Add(Identifier,
interfaceMethodInfo.GetParameters().Length);
if (typeof(void) != interfaceMethodInfo.ReturnType)
numberToRetVal.Add(Identifier, true);
Identifier++;
}
// Обработка свойств
PropertyInfo[] interfaceProperties = interfaceType.GetProperties();
foreach (PropertyInfo interfacePropertyInfo in interfaceProperties)
{
propertyNameToNumber.Add(interfacePropertyInfo.Name, Identifier);
Identifier++;
}
}
}
foreach (DictionaryEntry entry in nameToNumber)
numberToName.Add(entry.Value, entry.Key);
foreach (DictionaryEntry entry in propertyNameToNumber)
propertyNumberToName.Add(entry.Value, entry.Key);
// Сохранение информации о методах класса
allMethodInfo = type.GetMethods();
// Сохранение информации о свойствах класса
allPropertyInfo = type.GetProperties();
// Отображение номера метода на индекс в массивеforeach (DictionaryEntry entry in numberToName)
{
bool found = false;
for(int ii = 0; ii < allMethodInfo.Length; ii++)
{
if (allMethodInfo[ii].Name.Equals(entry.Value.ToString()))
{
numberToMethodInfoIdx.Add(entry.Key, ii);
found = true;
}
}
if (false == found)
throw new COMException("Метод не реализован ");
}
// Отображение номера свойства на индекс в массивеforeach (DictionaryEntry entry in propertyNumberToName)
{
bool found = false;
for(int ii = 0; ii < allPropertyInfo.Length; ii++)
{
if (allPropertyInfo[ii].Name.Equals(entry.Value.ToString()))
{
propertyNumberToPropertyInfoIdx.Add(entry.Key, ii);
found = true;
}
}
if (false == found)
throw new COMException("The property is not implemented");
}
// Компонент инициализирован успешно
// Возвращаем имя компонента
extensionName = "print";//componentName;
}
catch (Exception)
{
return;
}
}
public void Init([MarshalAs(UnmanagedType.IDispatch)]
object connection)
{
}
public void GetInfo([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_VARIANT)]
ref object[] info)
{
info[0] = 1000;
}
public void Done(){
}
public void FindMethod([MarshalAs(UnmanagedType.BStr)]
String methodName,
ref Int32 methodNum)
{
methodNum = (Int32)nameToNumber[methodName];
}
public void GetNParams(Int32 methodNum, ref Int32 pParams)
{
pParams = (Int32)numberToParams[methodNum];
}
public void HasRetVal(Int32 methodNum, ref Boolean retValue)
{
retValue = (Boolean)numberToRetVal[methodNum];
}
public void CallAsFunc(Int32 methodNum,
[MarshalAs(UnmanagedType.Struct)]
ref object retValue,
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_VARIANT)]
ref object[] pParams)
{
retValue = allMethodInfo[(int)numberToMethodInfoIdx[methodNum]].Invoke(
this, pParams);
}
public void GetNProps(ref Int32 props){
}
public void FindProp([MarshalAs(UnmanagedType.BStr)]
String propName,
ref Int32 propNum){
}
public void GetPropName(
Int32 propNum,
Int32 propAlias,
[MarshalAs(UnmanagedType.BStr)]
ref String propName){
}
public void GetPropVal(
Int32 propNum,
[MarshalAs(UnmanagedType.Struct)]
ref object propVal){
}
public void SetPropVal(
Int32 propNum,
[MarshalAs(UnmanagedType.Struct)]
ref object propVal){
}
public void IsPropReadable(Int32 propNum, ref bool propRead){
}
public void IsPropWritable(Int32 propNum, ref Boolean propWrite){
}
public void GetNMethods(ref Int32 pMethods){
}
public void GetMethodName(Int32 methodNum,
Int32 methodAlias,
[MarshalAs(UnmanagedType.BStr)]
ref String methodName){
}
public void GetParamDefValue(
Int32 methodNum,
Int32 paramNum,
[MarshalAs(UnmanagedType.Struct)]
ref object paramDefValue){
}
public void CallAsProc(
Int32 methodNum,
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_VARIANT)]
ref object[] pParams){
}
}
// Наш класс работающий в 1сpublic class MyComponent:Component{
public MyComponent(){}
public void Print(){
MessageBox.Show("Компонента работает нормально");
}
}
В 1С:
Если ПодключитьВнешнююКомпоненту("AddIn.SimpleExternalComponent")<>0 Тогда
ECR = СоздатьОбъект("MyComponent"); // Создание объекта из внешней компоненты
ECR.Print(); //Вызов нашего метода
Иначе
Сообщить("Внешняя компонента не найдена",5);
КонецЕсли;
AS>Авторы: AS>Alexey Stolpovskikh
AS>Аннотация: AS>Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.
А каким образом его зарегистрить с помощью RegSvr32 =/?
Получается только с помощью Regsvcs как приложение COM+... И 1С'ка компоненту не видит...
Re[2]: COM+-компонент для 1С на C#
От:
Аноним
Дата:
06.02.06 05:42
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Alexey Stolpovskikh, Вы писали:
AS>>Статья: AS>>COM+-компонент для 1С на C#
AS>>Авторы: AS>>Alexey Stolpovskikh
AS>>Аннотация: AS>>Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.
А>А каким образом его зарегистрить с помощью RegSvr32 =/? А>Получается только с помощью Regsvcs как приложение COM+... И 1С'ка компоненту не видит...
AS>>Авторы: AS>>Alexey Stolpovskikh
AS>>Аннотация: AS>>Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.
А>А каким образом его зарегистрить с помощью RegSvr32 =/? А>Получается только с помощью Regsvcs как приложение COM+... И 1С'ка компоненту не видит...
Re[2]: COM+-компонент для 1С на C#
От:
Аноним
Дата:
08.08.06 02:59
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Alexey Stolpovskikh, Вы писали:
AS>>Статья: AS>>COM+-компонент для 1С на C#
AS>>Авторы: AS>>Alexey Stolpovskikh
AS>>Аннотация: AS>>Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.
А>А каким образом его зарегистрить с помощью RegSvr32 =/? А>Получается только с помощью Regsvcs как приложение COM+... И 1С'ка компоненту не видит...
Чтобы зарегестрировать 'managed assembly' для COM клиенов нужно использовать regasm.exe