Добрый день. Захотелось попробовать создавать свои компоненты для TS CRM. Для разработки использую Delphi 7 и TS CRM 3.3.2. Создал свой COM объект подключил интерфейсы IWindowComponent, ICoreCollectionItem, ICoreObject. Указал родительский интерфейс для своего компонента IWindowComponent. Скомпилировал, зарегистрировал dll. Добавил компонент в файл WindowSettings.xml. В результате после создания окна в Администраторе TS появился мой компонент,
но при попытки добавить его в дерево объектов возникает ошибка:
Объект MyComponent.MyComponent ({095C50B4-37FD-4653-9ECE-6D8D9C718AD8}) не поддерживает интерфейс {12498E9F-2F20-4491-AAF8-F258E72BEF5B} ({12498E9F-2F20-4491-AAF8-F258E72BEF5B}).
Был бы очень благодарен если бы подсказали в чем может быть ошибка или дали ссылку на простейший пример разработки компонентов для TS.

Нравится

40 комментариев

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

Добрый день. А можно узнать когда примерно Ваш специалист проконсультирует меня ?:smile:

Добрый день!

Обращение находится в департаменте разработки, решение вопроса будет предоставлено до 03.02.2014.

Спасибо Арсений. Буду ждать.

Добрый день, Сергей!

По этой ссылке статья о работе с оконными компонентами в Terrasoft: Работа с окнами (Window)
Проверьте пожалуйста, все ли обязательные поля вы определили в своем компоненте?
Так же необходимо проверить правильно ли объявлен класс компонента, вот пример:

  TCalculatorControl = class(TFrameItem, ICalculatorControl, IConnectionPointContainer)

Вы создаёте элемент управления или оконный компонент?

С ув. Величко Максим, разработчик Terrasoft 3.x

Здравствуйте Максим. Спасибо за ссылку, но работать с компонентами Terrasoft я умею.
В классе компонента интерфейсы я объявил по примеру компонентов Terrasoft.
Свойства я унаследовал от IWindowComponent.
Я пробовал создавать и элементы управления и оконный компонент.
Не понятно, что это за интерфейс {12498E9F-2F20-4491-AAF8-F258E72BEF5B}, в реестре системы он не зарегистрирован.
Пробовал создавать компонент на С# та же история.
Был бы очень благодарен за простейший пример на любом языке программирования, можно создания пустого компонента.

Добрый день, Сергей!

{12498E9F-2F20-4491-AAF8-F258E72BEF5B} - это ID интерфейса IInternalWindowComponent
Попробуйте подключить этот интерфейс, он реализован в библиотеке TSWindowLibrary.dll

Спасибо Максим. Я попробую.

Добрый день, Сергей!

Хочу поинтересоваться как у Вас успехи с компонентом? Получилось ли добавить его в дерево? Ошибка исчезла?

Здравствуйте Максим. К сожалению у меня не получилось. При подключении интерфейса IInternalWindowComponent, пишет что необъявленный идентификатор.

TMyComponent = class(TAutoObject, IMyComponent, ICoreCollectionItem, ICoreObject, IWindowComponent, IInternalWindowComponent)

У меня такое ощущение, что я пошел не в том направлении, наверно все сложнее чем мне показалось на первый взгляд. Без явного примера с одним TLB файлом тяжело реализовать компонент. Будет свободное время продолжу попытки:smile:

Спасибо за помощь.

Сергей, если что - обращайтесь!

Дмитрий, Вы можете выложить пример на Delphi для создания простого оконного компонента? Это очень актуально.

Евгений, я передал Вашу просьбу разработчикам.

Спасибо!
Жду.

Это действительно актуально. У меня есть много полезных COM библиотек, написаных на разных языках, в том числе и для телефонии, все они прекрасно работаю в Террасофт, но хотелось бы сделать их компонентами системы.
Дмитрий если разработчики согласятся выложить простейший пример создания компонента на любом из языков программирования, прошу Вас сообщить мне :smile:.

Добрый день!

Вот пример создания COM-контрола FloatDataControl:

Объявление класса контроал

  TFloatDataControl = class(TDataControl, IFloatDataControl,
    IDataControl, IBaseDataControl, IFrameItem, IFrameBaseItem,
    IWindowControl, IWindowComponent, ICoreCollectionItem, ICoreObject,
    IInternalControlWithButtons)
    ...
  protected
    function Get_Buttons(): IActionMenu; safecall;
    procedure Set_Buttons(const AValue: IActionMenu); safecall;
    function Get_ButtonsName(): WideString; safecall;
    procedure Set_ButtonsName(const AValue: WideString); safecall;
    ...
  protected
    property Buttons: IActionMenu
      read Get_Buttons write Set_Buttons;
    property ButtonsName: WideString
      read Get_ButtonsName write Set_ButtonsName;
  public
    procedure Initialize(); override;
    destructor Destroy(); override;
  end;

Объявление интерфейса IFloatDataControl

  IFloatDataControl = interface(IDataControl)
    ['{E2B975D4-6C8D-4FCA-8C80-46AB6DCECD36}']
    function Get_Buttons: IActionMenu; safecall;
    procedure Set_Buttons(const Value: IActionMenu); safecall;
    property Buttons: IActionMenu read Get_Buttons write Set_Buttons;
  end;

Определение контрола в IDL-файле

	// ------------------------------------------------------------------
	// ILookupDataControl (2043XX)
	// ------------------------------------------------------------------
	[
		odl,
		uuid(8670BB97-7134-4FED-A3E8-79EE08E25B6F),
		version(1.0),
		helpstring("Dispatch interface for LookupDataControl Object"),
		dual,
		oleautomation
	]
	interface ILookupDataControl : IDataControl {
		[id(204301), propget]
		HRESULT SelectWindowUSI([out, retval] BSTR* Value);
		[id(204301), propput]
		HRESULT SelectWindowUSI([in] BSTR Value);
 
		[id(204302)]
		HRESULT UnprepareDropDownList();
 
		[id(204303), propget]
		HRESULT Buttons([out, retval] IActionMenu** Value);
		[id(204303), propput]
		HRESULT Buttons([in] IActionMenu* Value);
 
		[id(204304), propget]
		HRESULT Text([out, retval] BSTR* Value);
	};

Максим извините, но разве TFloatDataControl не должен наследовать TAutoObject?

Добрый день, Сергей!

Всё верно, просто в данном примере указно наследование от TDataControl, который по иерархии наследования, наследует TAutoObject.

Так же необходимо в секции initialization добавить следующий код:

initialization
  CoInitialize(nil);

Спасибо Максим. Буду пробовать.

У меня похожая ситуация, создаю компонент для добавления его в дерево сервисов. При добавлении выдает: "Object doesn't support interface {BFA833D5-0868-426E-AABE-05C0D5AFA5D0}". Это что за интерфейс?

К сожалению мне так и не удалось полноценно внедрить компонент. Было бы не плохо если бы выложили бы подробный пример создания компонента террасофт.

Добрый день, Алексей!

{BFA833D5-0868-426E-AABE-05C0D5AFA5D0} - это ID интерфейса IInternalService.

Приятного дня!

"Вильшанский Дмитрий" написал:{12498E9F-2F20-4491-AAF8-F258E72BEF5B} - это ID интерфейса IInternalService.

В принципе это и так было понятно из сообщения об ошибки.:smile:

Это какой то скрытый интерфейс?
В TSObjectLibrary его нет...
Есть какая нибудь tlb с этими внутренними интерфейсами?

"Шмитько Алексей Анатольевич" написал:

Это какой то скрытый интерфейс?

В TSObjectLibrary его нет...

Есть какая нибудь tlb с этими внутренними интерфейсами?

Алексей, это внутренний интерфейс и он находится в библиотеке TSObject.bpl

"Вильшанский Дмитрий" написал:Алексей, это внутренний интерфейс и он находится в библиотеке TSObject.bpl

Эта библиотека простым смертным недоступна, я так понимаю?
У меня версия 3.3.2.157

Алексей, данная библиотека доступна в бинарных файлах. Ее просто необходимо подключить/добавить.

В общем для разработки это не годится :(

Не получается подгрузить TSObject.bpl, т.к конфликтует с rtl70.bpl. C динамической подгрузкой тоже ничего не получилось. Использую Delphi 7.

Я так понимаю, что TSObject.bpl это run-time пакет и просто так его не подключить хотелось бы получить инструкцию как его подключать.

У меня вообще эти интерфейсы находятся в TSObjectLibrary.dll. Это "служебные" интерфейсы для разработчиков. Я просто взял и добавил в своей Type Lib недостающий интерфейс с ID из ошибки.
И он перестал ругаться :)
Но дальше пока не стал копать.

Ну я думаю еще пару лет и Мы осилим:smile:

Здравствуйте.
Пишите, если возникнут вопросы.

Я то конечно пишу, а толку? За 2 года не получил полезной информации. Сначала пишут одно потом другое.

"Перонко Сергей Сергеевич" написал:Я то конечно пишу, а толку? За 2 года не получил полезной информации. Сначала пишут одно потом другое.

100%

"Котенко Александр" написал:Здравствуйте.
Пишите, если возникнут вопросы.

Вопросы есть :)
Вы сотрудник компании Terrasoft? Если да, то можно ли получить модуль с объявлением Internal интерфейсов?

Здравствуйте.
Исходные файлы внутренней реализации кода закрыты. Мы можем предоставить idl-файл (во вложении), в котором описаны доступные интерфейсы библиотеки TSObjectLibrary.dll. Если возникнут сложности - прикрепите пример своего компонента чтобы можно было понять в чем проблема.

Извините, но зачем предоставлять idl файл который я и так могу получить из TSObjectLibrary.dll.
Проблема заключается в том что для разработки необходимо подключить пакет TSObject.bpl. Это не возможно сделать т.к. скорей всего это run-time пакет. А необходимый интерфейс находится именно в этом пакете. Я конечно не исключаю пробелы в знаниях делфи, поэтому прикрепляю свой компонент.

:lol:
Вы или не поняли тематику данной проблемы или издеваетесь )))
Могли бы изначально написать, что ваша компания запрещает создание компонентов, которые можно интегрировать в конфигурацию в Terrasoft Administrator. И всё.
Если Вас не затруднит, то предоставьте пожалуйста пример разработки компонента, который можно добавить в конфигурацию как показано ниже.

"Шмитько Алексей Анатольевич" написал:

:lol:

Вы или не поняли тематику данной проблемы или издеваетесь )))

Могли бы изначально написать, что ваша компания запрещает создание компонентов, которые можно интегрировать в конфигурацию в Terrasoft Administrator. И всё.

Если Вас не затруднит, то предоставьте пожалуйста пример разработки компонента, который можно добавить в конфигурацию как показано ниже.


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

Здравствуйте!
Те компоненты, о которых Вы пишете не реализуются на уровне конфигурации. Это сугубо ядровая логика

Показать все комментарии

Работать с COM, web service из кода событий карточек можно? Если можно, напишите пожалуйста где пример посмотреть.

Нравится

2 комментария

Добрый день.

Можно...
С СOM все просто - просто создаете ActiveX компонент:

var myComObj = new ActiveX('Excel.Application');

По веб. сервисам - запросы можно отправлять(получать) через соответствующий COM:

var webAddress = 'http://bank.gov.ua/control/uk/index';
var xmlHttpReq = new ActiveXObject("MSXML2.XMLHTTP.6.0");
xmlHttpReq.open("GET", webAddress, false);         
xmlHttpReq.send();

http://www.community.terrasoft.ru/blogs/8935

Показать все комментарии

Добрый день.
Есть следующий код на C#

string[] guid = new string[] {"{guid1}", "{guid2}"};
foreach(string id in guid)
{
    dsTask.SelectQuery[0].Filters["ID"].IsEnabled = true;
    dsTask.SelectQuery.Parameters["ID"].Value = "{Чего-то там}";
    dsTask.Open();
    if(!dsTask.IsEOF)
    {
        dsTask.Edit();
        dsTask.DataFields["StatusID"] = "GUID статуса";
        dsTask.DataFields["ResultID"] = "GUID результата";
        dsTask.Post();
    }
}

Цикл из двух итераций. Стабильно на второй итерации на строке dsTask.Edit() вываливается ошибка "Разрушительный сбой". Один раз эта ошибка вывалилась с описанием "Ошибка добавления объекта в Microsoft Script Control. Ошибка добавления модуля 'System\__GeneratedEnumsModule'. Разрушительный сбой". Guid1 и guid2 местами менять пробовал - результат тот же. Создавать ds_Task через GetNewItemByUSI для каждой итерации тоже пробовал - "Разрушительный сбой".
Версия ПО Террасофт: 3.3.2.245.

Нравится

6 комментариев

Попробовал изменить код на такой:

string[] guid = new string[] {"{guid1}", "{guid2}"};
string[] workflowItemIDs = new string[] {"{wItem1}", "{wItem2}"};
workflowEngineComObj = Activator.CreateInstance(Type.GetTypeFromProgID("TSWorkflowLibrary.WorkflowEngine"));
WorkflowEngine we = new WorkflowEngine(workflowEngineComObj);
we.SetConnector(TS3Connector.comObj);
TS3Connector.Attributes["WorkflowEngine"] = workflowEngineComObj;
for(int i = 0; i < guid.Length; ++i)
{
    dsTask.DisableEvents();
    dsTask.SelectQuery[0].Filters["ID"].IsEnabled = true;
    dsTask.SelectQuery.Parameters["ID"].Value = guid[i];
    dsTask.Open();
    if(!dsTask.IsEOF)
    {
        dsTask.Edit();
        dsTask.DataFields["StatusID"] = "GUID статуса";
        dsTask.DataFields["ResultID"] = "GUID результата";
        dsTask.Post();
        we.ProcessWorkflowItem(workflowItemIDs[i]);
    }
}

Теперь код стабильно падает с той же ошибкой на втором вызове WorkflowEngine.ProcessWorkflowItem(). В чем может быть дело?

Как минимум в конце цикла надо добавить

dsTask.Close();

Потому что иначе обе итерации работают над одной записью.

if(!dsTask.IsEOF)
    {
        dsTask.Edit();
        dsTask.DataFields["StatusID"] = "GUID статуса";
        dsTask.DataFields["ResultID"] = "GUID результата";
        dsTask.Post();
    }

Исправьте на

if(!dsTask.IsEOF)
    {
        dsTask.Edit();
        dsTask.DataFields["StatusID"] = "GUID статуса";
        dsTask.DataFields["ResultID"] = "GUID результата";
        dsTask.Post();
        dsTask.GotoNext();
    }

У Вас получается зацикливание в dsTask.IsEOF, так как набор данных не доходит до конца.

Добавление GotoNext() не поможет - в каждой итерации сначала указывается фильтр по ID, потом открывается датасет, в нем одна запись. Просто датасет надо закрыть в конце итерации, чтобы новый фильтр сработал при последующем открытии датасета.

Спасибо за комментарии, dsTask у меня закрывается, просто код скопировал не до конца. Вот исправленный вариант:

string[] guid = new string[] {"{guid1}", "{guid2}"};
string[] workflowItemIDs = new string[] {"{wItem1}", "{wItem2}"};
workflowEngineComObj = Activator.CreateInstance(Type.GetTypeFromProgID("TSWorkflowLibrary.WorkflowEngine"));
WorkflowEngine we = new WorkflowEngine(workflowEngineComObj);
we.SetConnector(TS3Connector.comObj);
TS3Connector.Attributes["WorkflowEngine"] = workflowEngineComObj;
for(int i = 0; i < guid.Length; ++i)
{
    dsTask.DisableEvents();
    dsTask.SelectQuery[0].Filters["ID"].IsEnabled = true;
    dsTask.SelectQuery.Parameters["ID"].Value = guid[i];
    dsTask.Open();
    if(!dsTask.IsEOF)
    {
        dsTask.Edit();
        dsTask.DataFields["StatusID"] = "GUID статуса";
        dsTask.DataFields["ResultID"] = "GUID результата";
        dsTask.Post();
        we.ProcessWorkflowItem(workflowItemIDs[i]);
    }
    dsTask.Close();
}

"Разрушительный сбой" продолжает наблюдаться.

Riptor, вложите, пожалуйста, сервисы.

Показать все комментарии

Коллеги, нужен совет!

Имеем COM Visible класс на C# .Net 3.5, в котором имеется массив значений
Из-под админки Terrasoft на debbuger я могу видить структуру этого массива и значения.... а вот доступ получить не удается
Как-то так: Instant.Items(1) или так Instant.Items[1] - ошибка и все тут!

Как описать этот массив в C#, что бы достучаться до него из JScript ?

Спасибо!

Нравится

2 комментария

Здравствуйте.

А так?
Что бы получить доступ, добавьте Set аксессор.

public class Test
{
    /// <summary>
    /// String array field instance.
    /// </summary>
    string[] _elements = { "one", "two", "three" };
 
    /// <summary>
    /// String array property getter.
    /// </summary>
    public string[] Elements
    {
	get { return _elements; }
    }
 
    /// <summary>
    /// String array indexer.
    /// </summary>
    public string this[int index]
    {
	get { return _elements[ index] ; }
    }
}

Дмитрий, спасибо!

Вот этого нам и не хватало:

public string this[int index]
    {
        get { return _elements[ index] ; }
    }

:smile:

Показать все комментарии

Коллеги, здравствуйте.

Темой к написанию заметки послужило обращение клиента с помощью по реализации ActiveX элемента управления на C# и использовании его в конфигурации.

Информация для проверки:

  1. Описание процесса создания графического элемента управления смотрим в: Порядок создания элемента управления ActiveX.docx
  2. Исходный код проекта: CSharpProject, с комментариями.
  3. Сам элемент управления: ActiveXSample, только в ActiveXSample.reg (регистрация ActiveX) – нужно изменить путь к библиотеке ActiveXSample.dll, на свой, или использовать для регистрации RegAsm.exe (описано в Порядок создания элемента управления ActiveX.docx)
  4. Сервисы с примером использования в конфигурации: TSSample, проверить можно прямо из TSAdmin-а (нажав в сервисе скрипта “ wnd_ActiveXSampleScript ”, F9. Не забываем зарегистрировать элемент перед проверкой)

Нравится

Поделиться

0 комментариев
Показать все комментарии

При попытке открыть в клиенте Terrasoft 3.4.0 окно с размещённым в нём ActiveX вылетала ошибка "The system cannot find the file specified". Проблемы не наблюдалось в TSClient 3.3.2 и в TSAdmin 3.4.0 (запуск показа окна по F9 в его скрипте). ActiveX-компонент разработан на .NET Framework 2.0.

Спасибо за разгадку А. Лучкиву:

Цитата:
Проблема заключается в том, что в сборках есть файл конфигураций TSClient.exe.config, который явно указывает версию поддерживаемой .NET Framework Runtime, там у нас указано v1.1.4322. Это сделано для решения проблем Oktel, возникающих у некоторых клиентов. Проблема воспроизводится, если на сервере Oktel установлены .NET Framework 1.1 и .NET Framework 2.0. Решением этой проблемы является удаление .NET Framework 1.1 с сервера Oktel либо явное указание на клиентских машинах использование NET Framework 1.1, с помощью TSClient.exe.config.

Вместе с тем, явное указание Runtime=1.1 c помощью TSClient.exe.config делает невозможным использование ActiveX и COM написанных на .Net старших версий.
Для исправления ошибки работы ActiveX для .NET Framework > 1.1, нужно удалить файл TSClient.exe.config из папки Bin.

После переименования (на всякий случай, чтобы не удалять) файла TSClient.exe.config компонент на форме заработал как следует.

Нравится

Поделиться

0 комментариев
Показать все комментарии

Добрый вечер.
Столкнулся с такой проблемой. В течение дня из Terasoft 3.3.2 создается несколько COM-соединений с 1С 7.7 от имени одного пользователя. Но в некоторых случаях (повторить не удалось, события случайны) при завершении работы с COM-объектом не происходит завершения процесса 1С. В результате при следующем создании COM-объекта соединения с 1С получаю "Каталог пользователя занят".
Как это победить - не представляю. Если только перед созданием подключения искать процессы 1С-ки и их грохать?

Нравится

2 комментария

Данная ситуация скорей всего возникает из-за того, что вы объявляете некоторые переменные для работы с объектами 1С и не очищаете их. В случае работы с 1С 7.7 это автоматически не происходит (в других версиях уже поправлено).
Вам нужно во всех местах где Вы присваиваете переменный ссылки на объекты 1С в конце использования очищать с помощью System.EmptyValue. Пример:

function OnBeforeRecordImport(Param, Dataset, Select1C) {
        var Kind = Param.CurrentTabularSection.ПервичныйДокумент.Вид();
	if (Kind != 'Счет') {
                return true;
        }
        Kind = System.EmptyValue;
}

не хватает еще одной строки Kind = System.EmptyValue перед return

function OnBeforeRecordImport(Param, Dataset, Select1C) {
        var Kind = Param.CurrentTabularSection.ПервичныйДокумент.Вид();
	if (Kind != 'Счет') {
                Kind = System.EmptyValue;
                return true;
        }
        Kind = System.EmptyValue;
}

Переменная Kind должна быть очищена в любом случае.

Петр, некоторые комментации по решению, предоставленному Максимом:

В случае, если у Вас есть дополнительные скрипты синхронизации с 1С (т.е. не только настройки утилиты интеграции), следует внести правки в скрипты в соответствии с комментарием Максима.

Если у Вас возникнут трудности с самостоятельной модификацией скриптов, просим предоставить скрипты в техническую поддержку.

Показать все комментарии

В этот блог буду выкладывать последние версии IDL-файлы COM-объектов Terrasoft. Эта информация является хорошим справочным материалом и облегчит разработчику ориентироваться в объектах платформы Terrasoft 3.X.

Нравится

Поделиться

0 комментариев
Показать все комментарии

Иногда возникает необходимость обращения к свойствам или методам определенных библиотек.
В моем примере мне необходимо было узнать, каким образом установить в скрипте значение для темы (Themes) при просмотре графиков.

1

Для этого пришлось немного узнать о возможностях обращения к COM (Component Object Model)-объектам (взаимодействующим компонентам).
COM-объекты находятся в файлах типа dll, exe или ocx. Чтобы источник COM-объектов успешно функционировал, он должен быть зарегистрирован на компьютере. Суть регистрации заключается в том, что информация о COM-объекте заносится в системный реестр. После регистрации источник COM-объектов готов к работе.
Для того чтобы посмотреть «содержимое» такого объекта можно использовать среду Visual Basic, которую можно вызвать через офисные средства (в случае ее отсутствия, Вы можете установить как дополнительный компонент через установку/удаление программ).
К примеру, в Microsoft Outlook 2007 среду можно вызвать через комбинацию клавиш Alt+F11 (в офисе версии 2010 - аналогично).
В открывшемся окне необходимо через меню инструментов вызвать окно связей (Tools --> References):

1

В окне выбора необходимо через кнопку «Browse» вызвать окно выбора объекта:

1

Выбрав необходимый тип COM-овского объекта, отправляемся на его поиски:

1

В моем примере за графики отвечает ActiveX Control - TeeChart8.ocx, который находится в папке Bin с установленным Terrasoft’ом:

1

После выбора библиотека отобразится в списке связей:

1

Далее необходимо открыть обозреватель объектов через меню View --> Object Browser, или нажать на клавишу F2:

1

Теперь в обозревателе выбираем необходимую библиотеку из выпадающего списка:

1

Затем воспользуемся поиском (в моем случае ввожу в строке Themes) и обращаем внимание на возможные действия:

1

Для решения моего вопроса подходит функция SetTheme, пример использования которой также предлагается в обозревателе.

Надеюсь, данная информация будет полезной.

Нравится

Поделиться

1 комментарий

Спасибо, Игорь, очень полезная информация

Показать все комментарии

Задача: реализовать интеграцию с Террасофт 3.X в консольном приложении (или в Windows service), написанном на C#
Решается достаточно просто при использовании Visual Studio - для созданного проекта консольного приложения выполняете команду Add reference, вкладка COM, выбираете Terrasoft Object Library и импортируете библиотеку типов.
Что необходимо далее? Открыть соединение, что то поделать с объектами конфигурации и закрыть соединение.

        static void Main(string[] args)
        {
            String ConfigName = "Developing";
            String TSLogin = "";
            String TSPassword = "";
            AuthenticationModeEnum AuthenticationMode;
            AuthenticationMode = AuthenticationModeEnum.amWindows;
            TSObjectLibrary.Connector TSConnector = new ConnectorClass();
            Boolean LoggedIn = TSConnector.OpenConfigurationByName(ConfigName, AuthenticationMode, TSLogin, TSPassword);
            string LoggingResult = "LoggedIn = " + LoggedIn.ToString();
            Console.WriteLine(LoggingResult); // проверка успешного подключения

            /*..здесь через TSConnector что-то делаем с сервисами для поставленной задачи..*/

            TSConnector.CloseConfiguration(); // Закрываем соединение
}

Простой код, все работает - до тех пор, пока ваше консольное приложение не завершает работу. У вас валятся ошибки аля "Неизвестное программное исключение" и "Runtime error"

Причина: по умолчанию услужливая Visual Studio задает параметры проекта так, что поток, в котором мы создали экземпляр TSObjectLibrary.Connector, работает в режиме MTA (Multi Threaded Apartment), в то время, как сам коннектор создан только для работы в STA

Решение простое: перед строкой static void Main(string[] args) добавить атрибут [STAThread]
И все.

Нравится

Поделиться

1 комментарий

Спасибо!!! Очень полезный материал.

Показать все комментарии