2012-05-02 32 views
6

Mam klienta/partnera, który stara się połączyć swoją aplikację z nasza pomocą naszego odsłoniętą funkcjonalność COM. Jak dotąd mają obiekt COM reprezentujący egzemplarz naszego pakietu oprogramowania, a następnie wykorzystują nasze metody COM do programistycznego budowania czegoś dla użytkownika na podstawie tego, co zrobili w swojej aplikacji. Zasadniczo jest to funkcja "eksportu".Release „własność” obiektu COM w .NET

Co oni poprosił mnie do zrobienia, których nie mogę dowiedzieć się, jak zrobić to pozwolić użytkownikowi zdecydować, gdy instancja jest zamknięta. Mam na myśli to, że nasz pakiet oprogramowania jest załadowany, jest widoczny i jest współdziała z użytkownikiem. Gdy skończysz, klikną naturalnie krzyż w prawym górnym rogu, aby opuścić oprogramowanie. To nie działa, ponieważ obiekt COM jest nadal "aktywny" w swojej aplikacji. Nasz pakiet oprogramowania można zamknąć tylko przez zabicie procesu w menedżerze zadań, podczas gdy aplikacja, która załadowała go przez COM pozostaje otwarta. Gdy ich aplikacja zostanie zamknięta, nasza aplikacja zostanie automatycznie zamknięta. Wygląda na to, że ich aplikacja "posiada" naszą z powodu wywołania COM.

Zrobiłem szybką aplikację demonstracyjną w języku C#, aby spróbować użyć rzeczy takich jak Marshal.FinalReleaseComObject(myObject) bezskutecznie.

Zdaję sobie sprawę, że używanie COM do tego typu rzeczy nie jest tym, do czego jest przeznaczone, ale mam nadzieję, że istnieje jakiś sposób obejścia tego problemu? Klient/partner używa VB.NET, ale C# jest w porządku.

+0

Proszę wyjaśnić, czy aplikacja jest zautomatyzowana z poziomu samej aplikacji (podobnie do skryptów VBA w aplikacjach VS lub Office) lub z zewnątrz (podobnie jak przy użyciu automatyzacji programu Word w celu utworzenia nowego dokumentu z własnej aplikacji/skryptu konsoli)? –

+0

Nie można zamknąć okna? To nie ma sensu, musisz to wyjaśnić. –

+0

To z zewnątrz, używają VB, aby rozpocząć nowy proces, odwołując się do naszego exe i tworząc instancję obiektu COM z niego. Mamy "Open", który robi dokładnie to, na co wygląda, otwiera użyteczne okno naszego pakietu oprogramowania. Jeśli chodzi o brak możliwości zamknięcia okna, nie można kliknąć czerwonego X w prawym górnym rogu, dobrze, ale nic się nie dzieje. Zamknie się tylko, gdy ich aplikacja VB zostanie zamknięta. Nie wiem wiele o współdziałaniu z COM, ale wygląda na to, że aplikacja VB ma własność lub jest rodzicem tego procesu. – sxthomson

Odpowiedz

3

pan pominięte pewne ważne informacje na temat własnej aplikacji, w tym przede wszystkim w jaki sposób realizują interfejsy COM, które naraża do aplikacji klienckiej. Jednym z aspektów twojego opisu, który jest dla mnie czerwoną flagą, jest tworzenie aplikacji. Mówisz, że aplikacja kliencka to "używanie VB do rozpoczęcia nowego procesu przez odniesienie do naszego exe." Nie powinno to być konieczne, jeśli prawidłowo zaimplementowałeś i zarejestrowałeś swój serwer COM. Pozwólcie, że opowiem wam architekturę, której użyłbym, by osiągnąć to, o co prosicie, i mam nadzieję, że będzie wam przydatna.

Na początek, jeśli chcesz dostarczyć obiekt COM z oddzielnego procesu, właściwym sposobem jest wdrożenie COM poza serwerem procesu. Jeśli serwer jest poza procesem, COM uruchomi aplikację automatycznie, gdy klient zażąda jednego z interfejsów za pośrednictwem COM. Częścią wymagań implementacyjnych serwera poza procesem jest automatyczne wyłączanie, gdy ostatni klient COM wypuszcza ostatni wskaźnik interfejsu.

Aby odsłonić interfejs użytkownika z serwera procesu, należy utworzyć osobny wątek jednowątkowego mieszkania (STA) z pętlą komunikatów. Umożliwi to zamknięcie dowolnego okna w wątku STA, w tym w oknie głównym, bez zabijania serwera COM. Dzieje się tak dlatego, że implementacja serwera COM będzie uruchamiała własny wątek pętli komunikatów MTA (Multi-threaded Apartment), aby obsłużyć wywołania COM poza proc. Wątek MTA jest głównym wątkiem aplikacji, a serwer zamknie go po wydaniu ostatniego interfejsu klienta.

Serwer COM nie powinien być wyłączony, a interfejsy pozostać niewydane. Oznacza to, że aplikacja kliencka ma obowiązek odpowiednio zwolnić interfejsy. Ale Twoja ramka testowa .NET powinna była to zrobić, więc wydaje się, że coś jest nie tak z twoją implementacją.

Zakładając, że postępujesz zgodnie z tymi wskazówkami, będziesz potrzebować planu obsługi scenariusza, w którym ostatni interfejs klienta zostanie zwolniony, ale nadal masz otwarte okna interfejsu użytkownika. Gdy wszystko zostanie poprawnie skonfigurowane, nie powinno to stanowić większego problemu. Na przykład po otwarciu interfejsu można po prostu odwołać się do jednego z własnych interfejsów, co uniemożliwi zamknięcie MTA.