Otwieranie pliku przez ShellExecute w już otwartej Aplikacji

0

Jeśli otwieram jakiś plik:

ShellExecute(Handle, 'open', PChar('JakaśAplikacja'), PChar('JakiśPlik_Ścieżka), nil, SW_SHOW);

a mam tę JakąśAplikację już otwartą a zminimalizowaną na pasku zadań to i tak plik zostaje otwarty w nowym egzemplarzu aplikacji, co w przypadku niektórych aplikacjii trwa o wiele dłuuuuuużej. :(

Jak zmodyfikować polecenie aby plik był ładowany do już otwartej aplikacji???
Proszę o radę :)

3

Ta aplikacja musi to ogarniać a nie Twój program.
Ewentualnie musisz użyć jakiegoś API jeśli jest albo przez WinAPI zasymulować użytkownika otwierającego plik.

1

A o jaki program konkretnie chodzi?

2

Jeżeli "JakaśAplikacja" to TWOJA czyli napisana przez ciebie aplikacja w delphi to najprościej możesz użyć CreateMutex (w JakaśAplikacja) w celu zabezpieczenia wielokrotnego uruchamiania tej samej aplikacji. Wtedy zwykły shellexecute uruchomi plik ale faktycznie nie odpali drugiej instancji (jak byś chciał przykładowy kod to pisz). Ponadto możesz oprogramować sobie np ParamStr aby przechwytywał parametr z nazwą pliku.

Gorzej w momencie gdy "JakaśAplikacja" to już nie jest Twoja apka tylko coś "zewnętrznego" (np word) wtedy czystym shellexecutem nie zrobisz ... będziesz musiał pobrać z listy procesów uchwyt otwartej aplikacji i spróbować do niej "wstrzyknąć" ten plik chyba, że ta aplikacja ma jakieś API (w przypadku worda chyba można to zrobić poprzez skrót). Aby być bardziej konkretnym musisz podać więcej szczegółów.

0

Czy jak klikasz plik ręcznie to otwieranie trwa długo? Jeżeli nie to znaczy że sprawa nie jest do końca przegrana, choć trzeba by było popatrzeć dokładnie jak system wywołuje wtedy aplikacje (rejestr + sys internals tools).

Generalnie problem jest znany:
https://stackoverflow.com/questions/177559/getting-rid-of-the-evil-delay-caused-by-shellexecute
https://groups.google.com/g/borland.public.delphi.nativeapi.win32/c/46ysevJthQg

1

Jeśli dany program ma oprogramowane trzymanie jednej sesji i przesyła żądania do istniejącej instancji z tej nowo otwieranej, to ShellExecute wystarczy. Jednak jeżeli nie ogarnia, ale obsługuje drag & drop, to możesz spróbował znaleźć uchwyt okna tego programu, a następnie wysłać do niego komunikat WM_DROPFILES. Ale nigdy tego nie testowałem, więc traktuj to jako pomysł, nie konkretne i sprawdzone rozwiązanie. Choć w teorii powinno się udać.

0

Przepraszam że tak długo nie odpowiadałem, :)

@0xmarcin : Chodzi o Libre Office Writer (ten otwiera się z pliku " .odt" rzeczywiście znacznie szybciej niż sam program bez pliku), a drugi to Borland Studio ten z kolei otwiera się tak samo wolno z pliku ".pas" jak i pusty program z pliku ".exe" (30 sek).
Okazuje się ku mojemu zaskoczeniu że obydwa obsługują drag&Drop.
I byłoby to ciekawe rozwiązanie chociaż nie wiem w tej chwili jak wysłać taki komunikat, bo:
-uchwyt (pod kursorem myszki) do otwartego programu jest inny dla głównego okna , do paska narzędzi inny i do paska menu inny
-nie znam składni komunikatu WM_DROPFILES. Wypróbuję jak będę miał nieco więcej wiedzy i o udzielenie takowej proszę @furious programming

Być może jest jeszcze inny sposób przez uchwyt? Czy nie dałoby się wysłać "komunikatu" przez menu plik/otwórz (ścieżka do pliku)?

3
  1. Do LibreOffice mozesz dostać się przez OLE - przykład że się da: Automatyzacja LibreOffice/OpenOffice Writer.
  2. Uchwyt okna - powinien być ten do którego należy pasek aplikacji. Teoretycznie. Ale to możesz sam sprawdzić próbując wysłać komunikat do różnych okien.
  3. Wysłanie WM_DROPFILES - jest tego trochę w sieci: https://groups.google.com/g/microsoft.public.platformsdk.shell/c/W70dZ5E6wsc?hl=de
0
dziobu napisał(a):
  1. Uchwyt okna - powinien być ten do którego należy pasek aplikacji. Teoretycznie. Ale to możesz sam sprawdzić próbując wysłać komunikat do różnych okien.

W Lazarusie można upuszczać pliki na głównym oknie, czyli tym wąskim z menu i paletą komponentów — a to okno jest głównym, więc je najłatwiej znaleźć. Obstawiam, że w Delphi jest tak samo. Jeszcze łatwiej będzie w przypadku gdy IDE jest zadokowane i ma tylko jedno okno.

0

Ale pytanie (i odpowiedź) dotycząca szukania okna dotyczy LibreOffice a nie Lazarusa/Delphi :D A które okno przyjmie komunikat to i tak przeważnie trzeba sprawdzić doświadczalnie.

0

Dziękuję za pomoc, będę sprawdzał

0
ShellExecute(Handle,'open',PChar(ExtractFilePath(Application.ExeName)+'...'),nil,nil,SW_SHOW);

Są problemy zarówno w Windows XP jak i w nowszych systemach. Czasami zadziała, a jak proces jest otwarty.i, gdy nie wiesz kiedy klikniesz dwa razy zatem dzieją się takie rzeczy. Wielu programistów zapomina o PChar(ExtractFilePath(Application.ExeName)+ co np. w systemie Windows XP sama ścieżka nie wystraszy system nie odpali pliku za pomocą ShellExecute PChar('JakaśAplikacja'),

1
Mariusz Bruniewski napisał(a):

Są problemy zarówno w Windows XP jak i w nowszych systemach.

Wątpię, aby kogokolwiek jeszcze ten system obchodził.

Wielu programistów zapomina o PChar(ExtractFilePath(Application.ExeName)+ co np. w systemie Windows XP sama ścieżka nie wystraszy system nie odpali pliku za pomocą ShellExecute PChar('JakaśAplikacja'),

Sama ścieżka nie wystarczy, bo istotna jest nazwa pliku wykonywalnego — bez niej system co najwyżej otworzy katalog w oknie eksploratora. Ale nawet jeśli brać pod uwagę samą nazwę pliku wykonywalnego (bez pełnej ścieżki), to nadal to co napisałeś jest nieprawdą.

System Windows (łącznie z XP) potrafi otworzyć dany program, jeśli ma do dyspozycji wyłącznie nazwę exeka. Najpierw sprawdzi katalog bieżący (czyli ten, w którym znajduje się plik wykonywalny aplikacji wołającej ShellExecute lub ustawiony za pomocą SetCurrentDir). Jeśli nie znajdzie pliku, to sprawdzi m.in. katalog Windows\Win32\ i pewnie jeszcze kilka innych miejsc, zanim się podda i zwróci kod błędu.

I właśnie dzięki temu, że pełna ścieżka nie jest wymagana, w systemowym oknie Run (skrót: Win+R) można podać nazwę programu (nawet bez rozszerzenia .exe), który chcemy otworzyć i ten go znajdzie, jeśli jest poprawnie zainstalowany. Sam w ten sposób zawsze otwieram Painta (nazwa to mspaint), kalkulator (calc), tablicę znaków (podając charmap) czy Notepad++ (wpisując notepad++) i się programy odpalają. Nie muszę tracić czasu na obsługę myszy czy na szukanie tych aplikacji na dysku (lub w jakichś menu).

Poza tym, jak się chce odpalić jakiś program, to się w jednym parametrze podaje jego ścieżkę, a w innym nazwę. Ja wiem, że złączenie ścieżki i nazwy a następnie przekazanie go jako jeden ciąg do ShellExecute działa, ale z jakiegoś powodu ścieżka i nazwa zostały rozbite na dwa parametry.

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