Форум: "Начинающим";
Текущий архив: 2009.10.25;
Скачать: [xml.tar.bz2];
ВнизПочему не срабатывает 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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.048 c