Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.10.25;
Скачать: CL | DM;

Вниз

Почему не срабатывает ShellExecute и чем это заменить?   Найти похожие ветки 

 
Andy BitOff ©   (2009-08-25 16:02) [0]

Собственно вот:

program Project1;

uses
 Forms, SysUtils, ShellAPI, Windows,
 Unit1 in "Unit1.pas" {Form1},
 Unit2 in "Unit2.pas";

{$R *.res}

var
 mt: TMThread;

begin
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 mt := TMThread.Create(False);
 sleep(15000);
 Application.Run;
end.

=======

unit Unit2;

interface

uses
 Classes, ShellAPI, Windows;

type
 TMThread = class(TThread)
 protected
   procedure Execute; override;
 end;

implementation

procedure TMThread.Execute;
begin
 ShellExecute(0, "open", "http://www.ya.ru/", nil, nil, SW_SHOWNORMAL);
end;

end.


Так ShellExecute сработает только после sleep(15000);

Однако, если сделать так:

begin
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 ShellExecute(0, "open", "http://www.ya.ru/", nil, nil, SW_SHOWNORMAL);
 sleep(15000);
 Application.Run;
end.


То сработает сразу.

В чем загвоздка? У как решить эту задачу? Нужно что бы вызов работал именно из потока.


 
Kolan ©   (2009-08-25 16:07) [1]

Ну заменить можно на CreateProcess.

Но у меня ваш код срабатывает с примерно секундной задержкой. Может это даже нормально, так как в FF открыто куча табов.


 
Медвежонок Пятачок ©   (2009-08-25 16:09) [2]

If the function fails, the return value is an error value that is less than or equal to 32. The following table lists these error values:
....
....
....


 
Andy BitOff ©   (2009-08-25 16:18) [3]


> Медвежонок Пятачок ©   (25.08.09 16:09) [2]

Она не завершается ошибкой.


> Kolan ©   (25.08.09 16:07) [1]

Да, надо попробовать.


 
Медвежонок Пятачок ©   (2009-08-25 16:27) [4]

Нужно что бы вызов работал именно из потока.

Зачем?
Чтобы не было задержек с появлением формочки?
ПостМессадж форме и тот же самый код из основного потока.


 
Kolan ©   (2009-08-25 16:30) [5]

Интересно, Andy, а не зависит ли время от браузера?


 
Leonid Troyanovsky ©   (2009-08-25 19:11) [6]


> Andy BitOff ©   (25.08.09 16:02)  

> Так ShellExecute сработает только после sleep(15000);

SE, видимо, непроста, бо может работать и с DDE и другой фигней.
Возможно, что для каждого потока она требует вещей вроде DDEInitialize
&etc и начинает трудиться лишь после таймаута.

Поэтому, CreateProcess - неплохой выбор, но FindExecutable,
на всякий случай, лучше сделать из первичного потока :)

--
Regards, LVT.


 
Andy BitOff ©   (2009-08-26 10:01) [7]

Блин. CreateProcess (во всяком случае с параметрами по умолчанию) ведет себя также. =(
Путем всяческих экспериментов выяснилось, что слип тут не причем. Видимо, ему для запуска действительно нужно выполение Application.Run;
Очень скверно =(


 
Leonid Troyanovsky ©   (2009-08-26 10:34) [8]


> Andy BitOff ©   (26.08.09 10:01) [7]

> Путем всяческих экспериментов выяснилось, что слип тут не
> причем.

У меня код из [0] пускает IE6 без всяких задержек.
Машина, правда, однопроцессорная, 2003 сервер.

--
Regards, LVT.


 
Andy BitOff ©   (2009-08-26 10:46) [9]

Вот ведь... А у меня даже с циклами (без слипа) выполняется только после Application.Run;
D7, XPsp2

Кстати. IE у меня правда не запускается вообще (вываливается с AV), но такое ощущение, что он все-таки действительно пытается запуститься когда надо. Вообще-то я пользуюсь оперой. Видимо Kolan ©   (25.08.09 16:30) [5] прав.
Хотя не понимаю причем тут могут быть браузеры...


 
MonoLife ©   (2009-08-26 18:43) [10]

Строки
...
Application.Initialize;
Application.CreateForm(TForm1, Form1);
mt := TMThread.Create(False);
Application.Run;
...
(без sleep) в мозилле открывает мгновенно, ну, или как >Kolan ©   (25.08.09 16:07) [1]


 
Юрий Зотов ©   (2009-08-26 19:04) [11]


begin
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 with TMyThread.Create(True) do
 begin
   FreeOnTerminate := True;
   Resume
 end;
 Application.Run;
end.

procedure TMyThread.Execute;
begin
 ShellExecute(0, "open", "http://www.ya.ru/", nil, nil, SW_SHOWNORMAL)
end;

Все летает и никаких проблем. D7, XP SP3, IE7.


 
lohnes   (2009-08-27 00:50) [12]

У меня аналогичная проблема.
Порыл информацию и пришел к выводу, что в ShellExecute используется COM-объект и, если не вдаваться в подробности, взаимодействие с этим COM-объектом внутри потоков осуществляется при помощи windows-сообщений, причем сообщение отсылается тому потоку который создал этот COM-объект.
Возможно у вас при создании формы создается COM-объект использующийся в ShellExecute, в итоге она не срабатывает пока основной поток не запустит цикл обработки сообщений (см. Application.Run).
Почитать про это можно тут: http://www.podgoretsky.com/ftp/Docs/Delphi/DX/COMmodel.html


 
lohnes   (2009-08-27 01:07) [13]

Да, может ShellExecuteEx ведет себя по другому...


 
Andy BitOff ©   (2009-08-27 08:55) [14]


> Юрий Зотов ©   (26.08.09 19:04) [11]

Юрий, а если перед Run заснуть Sleep(10000);?


 
sniknik ©   (2009-08-27 09:15) [15]

> Юрий, а если перед Run заснуть Sleep(10000);?
да без проблем.
begin
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 ShellExecute(0, "open", "http://www.ya.ru/", nil, nil, SW_SHOWNORMAL);
 Sleep(10000);
 Application.Run;
end.

> Все летает и никаких проблем.


 
sniknik ©   (2009-08-27 09:19) [16]

похоже он просто пытается синхронизироваться с основным потоком, а это без цикла выборки, что в Run; не получается.
используй что-нибудь другое (ShellExecuteEx, CreateProcess, ...).


 
Andy BitOff ©   (2009-08-27 09:31) [17]


> sniknik ©   (27.08.09 09:15) [15]

Этот вариант описан в [0] как рабочий. Не работает с потоком и, видимо, не могу проверить, с разными браузерами. В частности с оперой у меня не работает.

Сейчас буду пробовать другие варианты, хотя такой у меня тоже не сработал. Точнее сработал с задержкой.
var
 Rlst: LongBool;
 StartUpInfo: TStartUpInfo;
 ProcessInfo: TProcessInformation;
 DBP:string;
///////////////
 function GetDefaultBrowserPath: string;
 begin
   Result := "";
   with TRegistry.Create do begin
     try
       RootKey := HKEY_CLASSES_ROOT;
       if OpenKey("http\shell\open\command", False) then begin
         Result := StringReplace(ReadString(""), """, "", [rfReplaceAll]);
         CloseKey;
         end;
       end;
     finally
       Free;
     end;
   end;
 end;
/////////////////
Begin
 FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0);
 with StartUpInfo do begin
   cb := SizeOf(TStartUpInfo);
   dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
   wShowWindow := SW_SHOWNORMAL;
 end;
 DBP := GetDefaultBrowserPath();
 if DBP <> "" then begin
   CreateProcess(PChar(DBP), " http://www.ya.ru/", nil, nil, false, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo);
 end;


 
lohnes   (2009-08-27 18:24) [18]

Попробуй добавить в поток работу с очередью windows-сообщений, т.е. реализацию метода "Application.ProcessMessages" основного потока.



Страницы: 1 вся ветка

Текущий архив: 2009.10.25;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.019 c
2-1251219105
stas
2009-08-25 20:51
2009.10.25
Установлен ли сервис


4-1219915857
sniknik
2008-08-28 13:30
2009.10.25
Как узнать кем стартуется сервис...


15-1251078092
имя
2009-08-24 05:41
2009.10.25
Деноминация


3-1228563453
Антон_207
2008-12-06 14:37
2009.10.25
курсовая


2-1251362876
Polkin
2009-08-27 12:47
2009.10.25
Наведение мыши в потомке TLabel