Как выгрузить COM dll ? #758808


#0 by DES
сделал на C# свою COM dll. Загружаю на сервере 1С. Все работает. Но вот кажется dll создает проблему при загрузке *.dt. Так как система ругается что dll захвачена какой -то программой и ее заменить не удается, пока не перезагружу 1с-сервер. Т.е. при обращении клиента к серверу он грузит dll и захватывает ее файл и держит до скончания веков. Как отпустить файл dll в у конце процесса на сервере?
#1 by mehfk
"ругается что dll захвачена какой -то программойЙ" Скриншот покажи.
#2 by DES
ну не вопрос какой программой, вопрос как освободить. А ругается при загрузке *.dt winsock откинулся на стороне сервера.
#3 by ДенисЧ
так и должно быть. Расслабься и выпей коньяку.
#4 by DES
ну неужели нельзя вернуть память в кучу ??
#5 by Serginio1
О ты уже на C# программируешь. Быстро. По сабжу то это не простая манагед память, а скомпилированная нативная. Она не выгружается. Можно выгрузить только домен полностью, но это по сути отдельный процесс в едином адресном пространстве
#6 by su_mai
поставь process explorer и по имении dll найди программу её использующую.
#7 by su_mai
Какой то поток в dll работает, может TCPListener слушает порт или что то еще?
#8 by Serginio1
5+ DynamicMethod подвергается сборке мусора. Кстати, то что DLL не выгружается есть и свои плюсы. Ты можешь в статических полях держать данные. По сути это аналог переменных на сервере правда только в одном рабочем процессе
#9 by DES
это все понятно, плохо то что не могу загрузить данные с рабочей базы в тестовую на том же сервере. Нужно перезапустить процесс 1С,  а это не всегда возможно. А как перезагрузить сервер 1с для конкретного инстанса ?
#10 by DES
Да, работаю с winsock , но вроде бы закрываю канал сразу после чтения
#11 by DES
->
#12 by H A D G E H O G s
"в статических полях держать данные" все равно указатель на клиент возвращать
#13 by DES
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sender.Shutdown(SocketShutdown.Both);
#14 by H A D G E H O G s
попробуй FreeLibraryAndExitThread( HlNSTANCE hinstDll, DWORD dwExitCode);
#15 by H A D G E H O G s
очень годная статья про dll из нее я только что узнал про переадресацию
#16 by su_mai
Открой процесс dll в process explorer и посмотри в Threads и LAN что творится
#17 by DES
кстати, могу выложить код сюда, чтобы маэстро оценил труды.
#18 by Serginio1
Главное, что мои труды не пропали зря. Молодец.
#19 by DES
я, вообщем то, удивляюсь на этот код, но он работает, причем на сервере.     [Guid("13011962-0013-0001-1962-001301196200")]     internal interface IMyClass     {         [DispId]         string Exec(string ConnectString, string CMD, string partXML, bool Otladka);     }     [Guid("70DD7E62-7D82-4301-993C-B7D919430992"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]     public interface IMyEvents     {     }     [Guid("69EE0677-884A-4eeb-A3BD-D407844C0C72"), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IMyEvents))]     public class Utilites : IMyClass     {         public string Exec(string LogPass, string CMD, string oXML, bool Otladka = false)         {                 try                 {                     IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(IPaddr), IPport);                     Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                     try                     {                         }     } }
#20 by DES
все таки есть какой то метод выгрузки, только куда его примастырить ?
#21 by Serginio1
Так на будущее  проще и моднее использовать WCF
#22 by su_mai
Вызывает смущение: try { нет catch и finally пустой Вообще так не пишут используют конструкцию using(var obj = new MyClass) {   трололо }
#23 by DES
как конкретно нужно бы ?
#24 by su_mai
using(Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) {     try         } }
#25 by DES
не понял Убрать try  с sender.Shutdown ? А если канал не открылся ?
#26 by su_mai
Нельзя маскировать исключение в фиктивном блоке try или Попытка, что в C#?, что в 1С. Ошибка может скрыться, а неуправляемые ресурсы повиснуть, подвесив сам объект в куче или хрен знает что еще.
#27 by Serginio1
finally  ничего не маскирует она нужна для очистки ресурсов перед вызовом исключения по стеку В его примере в его блок просто не нужен. В рамках обработки исключений, связанный блок finally гарантированно будет выполнен.  Однако если исключения необработано, то выполнение блока finally зависит от того, как активирована операция очистки исключения.  Это, в свою очередь, зависит от того, как настроен компьютер. Дополнительные сведения см. в статье Обработка необработанных исключений в CLR.
#28 by su_mai
Там внизу мелким шрифтом:
#29 by su_mai
C# также содержит оператор using, который предоставляет аналогичную функциональность для объектов IDisposable в удобном синтаксисе.
#30 by DES
а разве try  не есть аналог транзакции ? происходит откат всех действий, в том числе и удаление всех переменных ?
#31 by su_mai
Тема управления памятью CLR объемная, но хорошо описана. Если упрощенно, то среда CLR выделяет память в "управляемой куче" для новых объектов оператором new. Когда на объект нет ссылок он признается подлежащим удалению и помещается в очередь удаления. Со временем уборщик мусора удалит его. Однако, если во время выполнения объект захватывал внешние неуправляемые CLR данные и не освободил их сам, то образуются утечки памяти. Например если создать временный файл на диске и не удалить его то объект удалиться, а файл останется. (Такое же поведение и в транзакциях.) Есть правило, если класс оперирует неуправляемыми данными, то он должен наследовать интерфейс IDisposable и соответственно реализовать метод Dispose, в котором освободить все "хвосты". При использовании таких объектов необходимо учитывать, что выполнение программы может прерваться из-за исключения, по этому используют конструкцию } finally { <Вызов метода объекта Dispose> } Это громоздкая конструкция заменяется элегантной using(<Создание объекта>) } Компилятор преобразует её в конструкцию try finally.
#32 by Serginio1
Я к , что finally ничего не маскирует
#33 by su_mai
Да, оно просто не успевает, его процесс "убивают" раньше...
#34 by Serginio1
Еще раз finally ничего не маскирует. Так же вызывается исключение. Просто если бы внутри finally  закрывались ресурсы смысл в нем был бы. Плюс если бы по стеку в  catch обрабатывалось исключение
#35 by Serginio1
Кстати, а почему ты не используешь
#36 by su_mai
И я о том же, просто некорректно сказал про маскировку. Я хотел сказать, что создается видимость обработки исключения. Поэтому я и распинался про using. А должен? :)
#37 by Serginio1
finally  не обрабатывает исключение Так и расскажи почему тебя не заинтересовало. Например с   можно отказаться от создания ВК. Особенно с динамической компиляцией обертки событий . Можешь получить глобальный контекст для вызова функций 1С, а так же получения интерфейсов IAsyncEvent,IExtWndsSupport итд. Кстати там обертка для глобального контекста, так как тип и объект при вызове Это не есть сущности одного объекта Там куча вещей которые можно использовать.
#38 by Serginio1
Кстати про фильты искключений в C# 6
#39 by su_mai
Спасибо посмотрю на досуге!
#40 by DES
раз вы уже тут, то поясните про GUID-ы ИХ там 3 шт, Какой в них смысл. Не один из них не нашел в реестре по-ходу после регистрации dll.
#41 by Serginio1
ProgID поставь.У тебя же есть примеры.     [ComVisible(true)]     [ProgId("NetObjectToIDispatch45")]     [Guid("DFDADA57-B22C-4276-928A-8B91C9891FF1")]     public class NetObjectToIDispatch45 Тем более испорльзуя .NET(C#) для 1С. Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия Писать COM объект не нужно
#42 by Serginio1
Или там можно сгенерировать как C# файлы, так и 1С методы событий
#43 by Serginio1
Если ты библиотеку подгружаешь через NetObjectToIDispatch45 то зачем тебе засорять регистр?
#44 by DES
нет, я гружу только свою ДЛЛ  и она работает. (без оберток) примеры то я взял, но что к чему не разобрался до конца.
#45 by Serginio1
А как ты в 1С подключаешь?
#46 by Serginio1
А вообще тебе интерфейсы не нужны. Ты их не используешь.     [Guid("AFDADA57-B22C-4276-928A-8B91C9891FF1")] public class Utilites Тогда вызов из 1С объект=Новый ComОбъект("ИмяТвоегоКласса"); и все публичные методы и непомеченные как  [ComVisible(false)] будут видны
#47 by xaozai
#48 by DES
Об.ЗавершитьРаботуКомпонента а что в DDL в этой функуции ?
#49 by DES
это [Guid("AFDADA57-B22C-4276-928A-8B91C9891FF1")] от фонаря или строго определенный   ?
#50 by H A D G E H O G s
Ничего. Это еротические фантазии автора .
#51 by H A D G E H O G s
Давай мы попробуем что-то придумать, если: 1) Ты можешь дать удаленный доступ 2) Есть сервер 1с в режиме отладки, который можно завалить.
#52 by DES
правда что ли ?
#53 by DES
организуем завтра
#54 by Serginio1
Гуид должен быть уникальным. В VS сервис- создать GUID
#55 by DES
Не догоняю, какие строчки лишние? У меня и так срабытывает объект=Новый ComОбъект("ИмяТвоегоКласса");
#56 by DES
переделал try на using dll-ко стало вести себя прилично, т.е. не блокирует загрузку *.dt. Спасибо за желание помочь.
#57 by Serginio1
Тогда класс у тебя должен описан как в И соответсвенно ты должен найти Guid этого класса. В регистр записываются только GUID класса у которого определен ProgId. Кстати в моих примерах есть обмен по TCP/IP
#58 by DES
там у тебя асинхронный пример
#59 by Serginio1
Нет отправка там синхронная Функция СоздатьСерверTCP(Врап)
#60 by Serginio1
bool СоединитьсяССервером(string ServerAdress,int порт)         {             {                 MessageBox.Show("Ошибка соединения с сервером: " + ex.Message);         }       public  ДанныеОтветаПоTCP ОтправитьКоманду(string ServerAdress,int порт,string Команда, string ДанныеДляКоманды, bool ЕстьОтвет, bool ЗакрытьСоединение)         {             {                     return new ДанныеОтветаПоTCP("Ошибка", ОшибкаСоединения);                 }                 using (var strim = new NetworkStream(клиент))                 {                     try                     {                     {                 }             {                 MessageBox.Show("Ошибка соединения с сервером: " + ex.Message);         }      }
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С