Excel, COM, uruchamianie w TServiceApplication

0

Witam

Czy walczył ktoś może z użyciem:

x := Create.OleObject('Excel.Application');
...
x.Workbooks.Open('c:\test.xls')

?

Googlowałem ile wlezie, co rusz natrafiałem na opis przekonfigurowywania dostępu w dcomcnfg. Poustawiałem tam maks ile się da (czyli wszystko do wszystkiego ;]), usługę odpalałem na koncie użytkownika zamiast LOCAL SYSTEM. Ostatecznie doprowadziłem do stanu, ze Excel się odpala, i Open chyba też idzie. Ale znowu zaczął mi sie wykrzaczać Excel przy normalnym otwieraniu pliku - no i w usłudze nie idzie dalej po Open. Dzisiaj admin przeinstaluje mi kompa - a pytanie moje jest takie: czy ma ktoś garść dobrych rad w tej materii ?

b

0

Ja używam i nie mam problemów. No chyba że to Win7, to z tym różnie bywało.
Co do porad to w serwisach używam zawsze ścieżek bezpośrednich oraz jeśli odwołujesz się do sieciowego zasobu, to żeby user na który logujesz serwis miał uprawnienia : > No, ale to zapewne wiesz.

otocz w try catch i zapisz treść wyjątku do pliku lub podaj kod :)
Pewnie pisałeś z głowy, bo nie ma kropki w CreateOleObject

0
maciejmt napisał(a)

Ja używam i nie mam problemów. No chyba że to Win7, to z tym różnie bywało.
Co do porad to w serwisach używam zawsze ścieżek bezpośrednich oraz jeśli odwołujesz się do sieciowego zasobu, to żeby user na który logujesz serwis miał uprawnienia : > No, ale to zapewne wiesz.

otocz w try catch i zapisz treść wyjątku do pliku lub podaj kod :)
Pewnie pisałeś z głowy, bo nie ma kropki w CreateOleObject

maciejmt napisał(a)

Ja używam i nie mam problemów. No chyba że to Win7, to z tym różnie bywało.

To niestety a może stety Vista.

maciejmt napisał(a)

Co do porad to w serwisach używam zawsze ścieżek bezpośrednich oraz jeśli odwołujesz się do sieciowego zasobu, to żeby user na który logujesz serwis miał uprawnienia : > No, ale to zapewne wiesz.

Tu sprawa jest prosta - plik jest na dysku lokalnym. Podaję pełną ścieżkę.

maciejmt napisał(a)

Pewnie pisałeś z głowy, bo nie ma kropki w CreateOleObject

No tak z głowy.

maciejmt napisał(a)

otocz w try catch i zapisz treść wyjątku do pliku lub podaj kod :)

Moja prawdziwa historia jest taka:
TServiceApplication uruchamia do wykonywania poszczególnych zadań osobne wątki. W moim przpadku zadaniem wątku jest preparacja i uruchomienie raportu w FastReport. Ten raport nie nie prezentuje, ale ma pewien kod w OnStartReport który się wykonuje. I w tymże właśnie raporcie (konkretnie jest to FastScript) mam napisany kawałek kodu (Pascal) który to kod:
loguje się do POP3
ściąga mail'a
zapisuje z niego załącznik na dysk
walczę z otwarciem tego pliku i skopiowania jego zawartości
wysyła to przez POST pod pewien adres
wysyła SMS'a z rezultatem wywołania

Wszystko działa - jak odpalam raport jako aplikację. Ale to generalnie może niepotrzebnie piszę o całości. Problem który się pojawił po odpaleniu w usłudze dotyczy Excel'a. W tym fastscripcie nie da się albo nie umię przechwycić komunikatu wyjątku (nie działa On E: Exception do). No więc po trochu robię kod na boku, i testuję. Tyle co zdążyłem wyłapać, to na początek brak CoInitialize - bez tego nie chciał się w ogóle tworzyć obiekt. Ale za nim na to wpadłem przegrzebałem i pozmieniałem co mi tylko wpadło w ręce - głównie dcomcnfg. Koniec końców przestał mi działać Excel w ogóle. Przed wyjście z roboty, ruszył mi xlsapp.workbook.open, ale nie wiem czego to było rezultatem ... eh. Zanim ruszył komunikat był że nie można otworzyć pliku i podane trzy przyczyny:

  • jest używany przez inną aplikację
  • ścieżka jest nieprawidłowa
  • i jeszcze jedna - ale nie pamiętam

W każdym razie żadna nie była prawdziwa.

Czyli reasumując, powiedz mi tak: u Ciebie w TServiceApplication korzystanie z COM działa od strzała ? Czy musiałeś coś przekonfigurowywać ?

b

0

nie wiem czy problemem nie będzie to, że odpalasz OLE w wątku, który nie zainicjował OLE. Spróbuj odpalić CoInitialize na początku i CoUnInitialize na końcu Execute wątku (moduł ActiveX)

tylko pamiętaj aby przypisać nil do wszystkich zmiennych interfejsowych (w Twoim przykładzie np. x) bo inaczej się wysypie CoUninitialize

0
Misiekd napisał(a)

nie wiem czy problemem nie będzie to, że odpalasz OLE w wątku, który nie zainicjował OLE. Spróbuj odpalić CoInitialize na początku i CoUnInitialize na końcu Execute wątku (moduł ActiveX)

tylko pamiętaj aby przypisać nil do wszystkich zmiennych interfejsowych (w Twoim przykładzie np. x) bo inaczej się wysypie CoUninitialize

No to to w końcu rozkminiłem, jak zacząłem robić ten programik na boku. W zasadzie było to proste, bo exception.message był mniej więcej taki: "Funkcja CoInitialize nie została wywołana" : ). Eh jakby wszystkie wylotki były takie.

No ale OK. Przywróciłem wszystko do normalności, Excel mi się zaczął znowu uruchamiać. Kod mam taki:

procedure TExcelTest.ServiceExecute(Sender: TService);
var theApp : OleVariant;
begin
CoInitialize(nil);
try
theApp := CreateOleObject('Excel.Application');
theApp.WorkBooks.Open('f:\test.xls');
except
on E : Exception do
Begin
zapisz E.Message do pliku
End;
end;
CoUnInitialize();
end;

Komunikat:
"
Program Microsoft Office Excel nie może uzyskać dostępu do pliku 'f:\test.xls'. Istnieje kilka możliwych powodów:

• Nazwa pliku lub ścieżka nie istnieje.
• Plik jest używany przez inny program.
• Skoroszyt, który próbujesz zapisać, ma taką samą nazwę jak obecnie otwarty skoroszyt
"

Office 2007
Vista x86

b

0

czy plik który otwierasz, był utworzony na tym samym koncie użytkownika ?

0
maciejmt napisał(a)

czy plik który otwierasz, był utworzony na tym samym koncie użytkownika ?

Teraz odpaliłem excel'a utworzyłem plik i zapisałem w tym katalogu - to samo. Tylko że ja to robię na swoim koncie, a usługa działa na koncie SYSTEM. Jak ją przestawiłem na mojego - jest to samo. To samo jest też jak wybiorę Usługa lokalna. Jak wybiorę usługa sieciowa - jest "Odmowa dostępu".

b

0

Jakieś 3 tygodnie temu pisałem o tym, tyle że na Win7.
Własne utworzone pliki odczytywał, utworzone na innym kompie już nie.
Ustawiałem właścicieli, wyłączałem UACa i inne.
Plik mogłem otworzyć np poprzez Read, a poprzez Api Excela już nie, cały czas ten sam komunikat co ty miałeś. Odpuściłem sobie ten temat wtedy(odczytywałem CSVki, więc zrobiłem odczyt przez TStringList). Może to ich bug ? :)

http://4programmers.net/Forum/Delphi_Pascal/184438-dostep_do_pliku_win7_aplikacja_uslugowa

0

udostępnij ten katalog do zapisu dla wszystkich i spróbuj

0
maciejmt napisał(a)

Odpuściłem sobie ten temat wtedy(odczytywałem CSVki, więc zrobiłem odczyt przez TStringList). Może to ich bug ? :)

No może. Ja niestety nie mam csv.

b

0
Misiekd napisał(a)

udostępnij ten katalog do zapisu dla wszystkich i spróbuj

Dodałem 'Wszyscy', pełna kontrola - to samo ; [
b

0
maciejmt napisał(a)

Jakieś 3 tygodnie temu pisałem o tym, tyle że na Win7.
Własne utworzone pliki odczytywał, utworzone na innym kompie już nie.
Ustawiałem właścicieli, wyłączałem UACa i inne.
Plik mogłem otworzyć np poprzez Read, a poprzez Api Excela już nie, cały czas ten sam komunikat co ty miałeś. Odpuściłem sobie ten temat wtedy(odczytywałem CSVki, więc zrobiłem odczyt przez TStringList). Może to ich bug ? :)

http://4programmers.net/Forum/Delphi_Pascal/184438-dostep_do_pliku_win7_aplikacja_uslugowa

Jak masz ten przypadek spróbuj tego:

dcomcnfg > usługi składowe > komputery > mój komputer > konfiguracja DCOM > Microsoft Excel Application > właściwości > Tożsamość > zaznacz "Użytkownik interakcyjny"

U mnie Workbooks.Open poszło : )))))))) Mam dalsze problemy, ale to chyba już z czego innego wynikając (i hope so). Daj znać jak u Ciebie.

Aha, nie wiem czy to jest idealna solucja, nie wiem jak się to zachowa jak nie będzie zalogowany nikt. Ale to wkrótce sprawdzę.

b

0

Nie do końca jest z tym tak jakby się chciało. Ta opcja z użytkownikiem interakcyjnym działa OK, ale tylko wtedy gdy na komputerze na którym działa usługa jest zalogowany użytkownik na którym ten mechanizm działa.
Jak nikt nie jest zalogowany - lipa

b

0

No i jeszcze jedna opcja. Jeśli zaznaczy się tam nie użytkownik interakcyjny, tylko Ten użytkownik - i poda się użytkownika na koncie którego to działa to szmaciarz działa i z usługi i nie z usługi. Yeah ! Ale jest jeden problem - Excel odmawia posłuszeństwa jak się go normalnie otworzy. Na początek jest komunikat - Łączenie i osadzanie obiektów nie jest możliwe. Próby otwarcia jakiegoś pliku = wylot Excel'a

b

0

Wybaczcie, że się wtrące, ale rozumiem b0bik, że koniecznie musisz skorzystać z Excela i OpenOffice Calc opada? Bo ja wprawdzie przez Delphi OpenOffice Calciem bawiłem się tylko raz w prostym programie, który stworzyłem na swoje potrzeby aby w ewentualnym turniejem w grze Sensible World of Soccer wygenerować sobie szybko tabelki par spotkań i różne grupy na kolejnych arkuszach. Po to aby wygodnie wpisywać wyniki na kartce po wydrukowaniu. Wprawdzie teraz używam Windowsa 7 i to z wyłączonym UAC, ale stwierdziłem przy okazji że OpenOffice ma swoje API chyba lepiej udokumentowane niż to co w google znajdowałem na temat Excela. Jest może jak na moje wydzimiśie ciutke chyba bałaganiarskie, ale ujdzie. Osobiście przekonałem się do OO Calca i OO Writera. Bo nawet jeśli nie kombinujesz tylko dla siebie ale pod kątem działania programu dla jakiejś firmy, to może warto zachęcić ich do stosowania OO Calca. W końcu to wolne oprogramowanie i nie tylko w działaniu wolne ;) Oczywiście nie twierdzę, że jest to idealny produkt, ale podejrzewam, że BYĆ MOZE we wspołdziałaniu na płaszyźnie ActiveX i Delphi było by tu znacznie mniej problemów.

0
olesio napisał(a)

...że koniecznie musisz skorzystać z Excela i OpenOffice Calc opada?

Szczerze - nie brałem pod uwagę OO. Generalnie mam plik xls, który da się też otworzyć w OO. Jeśli wyciągnięcie z niego danych via COM jest proste to czemu by nie spróbować. Masz może gdzieś jakiś przykład ? Chodzi mi o to żeby otworzyć plik i zapisać jego zawartość do pliku tekstowego rozdzielanego tabulatorami.

b

0

to może inaczej - jeśli z tego arkusza potrzebujesz tylko dane bez takich cudów jak formatowania, kolorki i inne duperele to zamiast otwierać excela potraktuj plik jako zwykły plik BD - use ado luke

0

@b0bik: ogólnie o ile pamiętam przykłady potrzebnego mi kodu, który raczej tworzył niż odczytywał znalazłem w API OO na: http://api.openoffice.org/docs/common/ref/com/sun/star/module-ix.html i pochodnych stronach oraz w google. Taki link znalazłem w swoich zakładkach. Z odczytem nie wiem czy ogarniesz, ale nie jesteś przecież "Total Newbie" to uważam, że powinieneś ogarnąć. Potrzebne moduły oraz przykładowy kod mojego dawnego w sumie dzieła dołaczyłem wraz z plikiem wykonywalnym do tego kodu. Kod może nie jest idealny, ale pisany na szybko, moje potrzeby spełniał. Myślę, że w google da radę znaleźć przykłady użycia API OO w celu również otwierania i operacji na już istniejących plikach XLS. A może ktoś tutaj też się tym bawił i będzie mógł się podzielić jakimś przykładowym kodem, który również ułatwi Tobie pisanie Twojego własnego programu.

0

Trochę pogooglowałem, i pierwsze co się rzuca w oczy to czytelność dostępu do tego OO - masakra. Excel jest o wiele bardzie programmer-friendly : ) W Excelu zawsze można se nagrać macro i po kosmetyce wrzucić to do Delphi. Mam nadzieje że w OO też coś takiego jest. Na Twój program zerknę jutro.
Dzięki i dobranoc

b

0

Co do nagrywania, to nie bawiłem się w to, bo nie potrzebowałem, ale jak najbardziej taka możliwośc istnieje w menu Narzędzia -> Makra. Natomiast API OO jest udokumentowane jak jest, ja na przykład jak szukałem przykładów do Excela to znajdowalem tylko posty ludzi z fragmentami kodu, a jako takiej przejrzystej dokumentacji nie widziałęm. Moze źle szukałem. Podsumowując nie namawiam do OO, ale może uda się Tobie zrobić z użyciem OO Calca to co nie udało się Tobie zrobić w Excelu.

0

Jeszcze wracają do Excel'a - może to ograniczenie licencyjne ? Ja bym w sumie chciał osiągnąć efekt taki, że na komputerze sobie dłubie, jak chce to używam Excel'a, a w tle działa sobie jakiś TServiceApplication który jak potrzebuje to też używa Excel'a.

Więc to jakbym chciał mieć dwie licencje.

No bo generalnie ostatecznie efekt jest taki że albo działa w usłudze (nie ważne czy ktoś jest zalogowany czy nie) ale nie działa wtedy Excel jak się zaloguje, albo jak przestawię w dcomcnfg to działa Excel, ale w usłudze działa tylko jak jestem zalogowany.

b

0

Dzisiaj zacząłem sprawę drążyć w MicroSofcie. Jutro będę kontynuował, dam znać co wydumamy.

b

1 użytkowników online, w tym zalogowanych: 0, gości: 1