Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1250765034
webpauk
2009-08-20 14:43
2009.10.25
Длина TLabel


11-1207080348
Lotos
2008-04-02 00:05
2009.10.25
Splitter


15-1251381842
Пит
2009-08-27 18:04
2009.10.25
Перевод строки в TEXTAREA


2-1251312234
sanx
2009-08-26 22:43
2009.10.25
TEdit, как отличить user ввод от присвоения Text нового значения?


15-1251192191
_Андрей
2009-08-25 13:23
2009.10.25
слабый сигнал?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский