perlon Opublikowano 26 Października 2018 Zgłoś Udostępnij Opublikowano 26 Października 2018 Witam. Czy jest możliwość skonstruowania .dll'ki wczytywanej przez NETLOAD tak aby po jej załadowaniu automatycznie wykonał się jakiś kod z jej wnętrza? Coś w rodzaju autostartu wewnątrz dll bez wydawania komendy z commandline. I pytanie główne raczej dotyczy ogólnie C# czy w takim kodzie jest możliwe sprawdzenie jaka aplikacja załadowała do swoich assemblies taką właśnie dll'kę. Chodzi mi o możliwość używania jednej skompilowanej dll w różnych środowiskach CAD (AutoCAD, ZwCAD, BricsCad etc.) gdzie wewnętrzna metoda sprawdzałaby środowisko i za pomocą fabryki tworzyła instancję klasy Document zgodną z tym środowiskiem. Tak na marginesie, czy w ogóle jest możliwe stworzenie takiej dll która raz skompilowana będzie pracowała na różnych platformach CAD obsługujących .NET'a Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kruszynski Opublikowano 26 Października 2018 Zgłoś Udostępnij Opublikowano 26 Października 2018 Godzinę temu, perlon napisał: Czy jest możliwość skonstruowania .dll'ki wczytywanej przez NETLOAD tak aby po jej załadowaniu automatycznie wykonał się jakiś kod z jej wnętrza Podejrzewam że tak. W ZRX jest to możliwe. Poszukam czegoś, albo dopytam w ZWSOFT. Godzinę temu, perlon napisał: czy jest możliwe sprawdzenie jaka aplikacja załadowała do swoich assemblies taką właśnie dll'kę. Również postaram się czegoś dowiedzieć Godzinę temu, perlon napisał: czy w ogóle jest możliwe stworzenie takiej dll która raz skompilowana będzie pracowała na różnych platformach CAD obsługujących .NET'a Tu mam najgorsze przeczucia. Raczej stworzyłbym 2 projekty , czy nawet więcej i ładowałbym te same pliki źródłowe. Problem może wynikać z dodawania różnych "References" do tego samego projektu. A może to tylko bezpodstawne moje obawy. Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kruszynski Opublikowano 26 Października 2018 Zgłoś Udostępnij Opublikowano 26 Października 2018 52 minuty temu, kruszynski napisał: czy jest możliwe sprawdzenie jaka aplikacja załadowała do swoich assemblies taką właśnie dll'kę. Mogę się mylić, ale tak na szybko szukałbym czegoś takiego: Assembly.GetExecutingAssembly() Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
perlon Opublikowano 26 Października 2018 Autor Zgłoś Udostępnij Opublikowano 26 Października 2018 Tak sobie trochę sam odpowiem 😉 Co do generowania różnych dll to myślę że rozwiązaniem połowicznym może być globalny #define i w poszczególnych deklaracjach using zamykać je w #ifdef #endif. Jeszcze tylko muszę poszukać czy da się zautomatyzować generowanie nazwy dll w zależności od takiego #define 10 minut temu, kruszynski napisał: Mogę się mylić, ale tak na szybko szukałbym czegoś takiego: Assembly.GetExecutingAssembly() Będę to sprawdzał. Na razie AppDomain.CurrentDomain.SetupInformation.ApplicationName; zwraca mi ZwCAD.exe więc już jest jakieś zaczepienie. Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kruszynski Opublikowano 26 Października 2018 Zgłoś Udostępnij Opublikowano 26 Października 2018 2 godziny temu, perlon napisał: Czy jest możliwość skonstruowania .dll'ki wczytywanej przez NETLOAD tak aby po jej załadowaniu automatycznie wykonał się jakiś kod z jej wnętrza? Znalazłem: namespace test { public class Class1 : ZwSoft.ZwCAD.Runtime.IExtensionApplication { public void Initialize() { MessageBox.Show("Initialize!"); } public void Terminate() { Console.WriteLine("Cleaning up..."); } [CommandMethod("test2492")] public static void test2492() { MessageBox.Show("Hello World!"); } } } Ale jestem z siebie dumny Parikon 1 Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Parikon Opublikowano 26 Października 2018 Zgłoś Udostępnij Opublikowano 26 Października 2018 (edytowane) using System; using System.Windows.Forms; using zza = ZwSoft.ZwCAD.Runtime; namespace StartDLL { public class Class1 : zza.IExtensionApplication { public void Initialize() { MessageBox.Show("Initialize!"); } public void Terminate() { Console.WriteLine("Cleaning up..."); } [zza.CommandMethod("test2492")] public static void test2492() { MessageBox.Show("Hello World!"); } } } Przy załadowywaniu wykonuje się metoda Initialize(), po wywołaniu komendy test2492 metoda test2492(). Jak wywołać metodę Terminate() - zakończenie? Edytowane 26 Października 2018 przez Parikon Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
perlon Opublikowano 28 Października 2018 Autor Zgłoś Udostępnij Opublikowano 28 Października 2018 Dnia 26.10.2018 o 14:18, kruszynski napisał: Znalazłem: namespace test { public class Class1 : ZwSoft.ZwCAD.Runtime.IExtensionApplication { public void Initialize() { MessageBox.Show("Initialize!"); } public void Terminate() { Console.WriteLine("Cleaning up..."); } [CommandMethod("test2492")] public static void test2492() { MessageBox.Show("Hello World!"); } } } Ale jestem z siebie dumny No jest z czego Próbowałem coś przez konstruktora ale jest wołany przy pierwszym użyciu dowolnej metody. O Initialize nie doczytałem. Wygląda na to, że metoda Initialize jest wywoływana tylko z jednej klasy pomimo zdefiniowania interfejsu IExtensionApplication w kilku. Wniosek : trzeba stworzyć klasę np. Autostart z interfejsem IExtensionApplication niekoniecznie zawierającą CommandMethod. Dzięki za rozwiązanie Z testów mi wyszło że Terminate() jest wołana przy niszczeniu obiektu a to następuje przy zamykaniu ZwCAD'a. Chyba może być wykorzystana do ręcznego wywołania Garbage Collector ewentualnie zapisu stanu aplikacji przed zamknięciem zwcad'a. Ale żeby tak w trakcie działania wywołać terminate() to chyba się nie da bo trzeba by mieć do tego obiektu referencję. A zdaje się że obiekt jest powoływany na zapleczu bez globalnie wystawionej referencji. Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
kruszynski Opublikowano 29 Października 2018 Zgłoś Udostępnij Opublikowano 29 Października 2018 hm. jeszcze nie wiem do czego, ale mam takie podskórne wrażenie, że będę tego używał. Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Parikon Opublikowano 29 Października 2018 Zgłoś Udostępnij Opublikowano 29 Października 2018 W PI mam stworzonego lispa, który ładuje dll-kę, w której jest metoda ładująca inne dll-ki. Przy czym ta metoda wywołuje się jako komenda, którą trzeba uruchomić z poziomu aplikacji lisp. Teraz mogę stworzyć dll, które na stale mogę wpisać do dll-startowych w oryginalnym pliku ZwCAD. Ta dll-ka sama wywoła metodę, która załaduje resztę moich plików *.dll Metoda Terminate() zapewne powinna być wywoływana przy zamykaniu ZwCAD, ale nie zauważyłem aby wyskakiwała konsola z napisem. Zapewne jej wywołanie jest blokowane przez ZwCAD. Mówię o kodzie , jak powyżej. Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
perlon Opublikowano 29 Października 2018 Autor Zgłoś Udostępnij Opublikowano 29 Października 2018 (edytowane) Ładowanie innych dll z głównego dll może rozwiązać problem platformy xxxCAD i zwiększyć uniwersalność aplikacji Tak jeszcze w uzupełnieniu do terminate(). U mnie komunikat z terminate() wyskakuje po zamknięciu okna ZwCAD'a. (w trybie debug) wtedy już nie ma okna konsoli. Żeby to sprawdzić wystarczy zamienić Console.WriteLine("Cleaning up..."); na MessageBox.Show("Cleaning up..."); Można w metodzie Initialize() zapisać referencję do obiektu IExtensionApplication np w jakimś singleton globalnym dla całej aplikacji i wołać jego metody w tym również terminate w dowolnym momencie ale i tak metoda terminate() będzie wywołana przy zamknięciu całego CAD'a. Tu pojawia się chyba kwestia niemożności odładowania dll'ki (brak NETUNLOAD) w trakcie trwania sesji CAD'a. Może są jakieś inne sposoby na usunięcie z pamięci wskazanej dll przez mechanizmy ogólne systemu a nie to co oferuje ZwCAD. Edytowane 29 Października 2018 przez perlon Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
perlon Opublikowano 31 Października 2018 Autor Zgłoś Udostępnij Opublikowano 31 Października 2018 Niestety poniższe podejście nie daje efektu. Initialize() w ogóle nie startuje. Uruchomi się tylko gdy usunę interfejs z klasy AcAutoStart (ciekawe dlaczego tak jest). Wymuszenie za pomocą [assembly: ...] również nic nie daje. Żeby mieć wspólną dll'kę dla ZwCAD i AutoCAD musiałbym chyba przejść na typy dynamic i stosować jakieś fabryki obiektów. Na 4programers ktoś zaproponował opakować klasy CAD'a klasą proxy. Ale to trzeba by zrobić 1:1 całe API .NET'a. W czort roboty i trzeba jeszcze to umieć 😞 using System; // [assembly: ZwSoft.ZwCAD.Runtime.ExtensionApplication(typeof(CADKit.ZwAutoStart))] // [assembly: Autodesk.AutoCAD.Runtime.ExtensionApplication(typeof(CADKit.AcAutoStart))] namespace CADKit { public class ZwAutoStart : ZwSoft.ZwCAD.Runtime.IExtensionApplication { public void Initialize() { string env = AppDomain.CurrentDomain.SetupInformation.ApplicationName; System.Windows.Forms.MessageBox.Show("ZwCAD -> " + env.ToUpper()); } public void Terminate() { } } public class AcAutoStart : Autodesk.AutoCAD.Runtime.IExtensionApplication { public void Initialize() { string env = AppDomain.CurrentDomain.SetupInformation.ApplicationName; System.Windows.Forms.MessageBox.Show("AutoCAD ->" + env.ToUpper()); } public void Terminate() { } } } Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Dołącz do dyskusji
Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.