Отправляет email-рассылки с помощью сервиса Sendsay

Программирование. Форум !!!

Cpp Builder | Delphi WinExec

Дрова!

Есть такая API'шная функция
UINT WinExec(LPCSTR lpCmdLine, // address of command line
UINT uCmdShow // window style for new application
);
Дык когда я ее юзаю под Delphi - все ОК, а вот под Cpp Builder выдает значение
0 (The system is out of memory or resources) [все на 100% идентично, т.е. копируем
из Дельфа и вставляем в Срр]

Что делать? И в чем вся фигня???

Ответить   -=BorMaN=- Wed, 10 Mar 2004 20:41:01 +0200 (#100493)

 

Ответы:

значение

Ну, во-первых один из ее кодов завершения -- не хватает памяти,
во вторых --
This function is provided for compatibility with earlier versions
of Windows.
For Win32-based applications, use the CreateProcess function.

BOOL CreateProcess(

LPCTSTR lpApplicationName, // pointer to name of executable module
LPTSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process
security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security
attributes
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCTSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to
PROCESS_INFORMATION
);

Удачи.
P.S. Пожалуйста, указывайте версии ваших операционок и средств разработки.
Номер выпуска : 2531
Возраст листа : 171 (дней)
Количество подписчиков : 380
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/100598
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

-*Информационный канал Subscribe.Ru
Написать в лист: mailto:comp.soft.prog.prog-list@subscribe.ru
Отписаться: mailto:comp.soft.prog.prog--unsub@subscribe.ru

http://subscribe.ru/ mailto:ask@subscribe.ru

Ответить   "Sn" Thu, 11 Mar 2004 08:10:09 +0400 (#100598)

 

Тема: Cpp Builder | Delphi WinExec

Всегда лучше использовать CreateProcess - не интересовался в Builder'e, но в
Delphi все равно идет вызов CreateProcess

Ответить   Thu, 11 Mar 2004 07:41:25 +0300 (#100607)

 

==-==-=-Привета!11 марта 2004 г. (четверг 6:41:25) Surin_bp (E-Mail: <surin_***@m*****.ru>) в мессаге
<<Cpp Builder | Delphi WinExec>> накрапал

Surin_bp> Тема: Cpp Builder | Delphi WinExec

Surin_bp> Всегда лучше использовать CreateProcess - не
Surin_bp> интересовался в Builder'e, но в
Surin_bp> Delphi все равно идет вызов CreateProcess

Говорят, что прога, загруженная через CreateProcess может закрится при закрытии
запустившей ее проги... Это так?
И еще, WinExec - API'шная функция (т.е. ее можно юзать "везде") В чем же все-таки
проблемма в Cpp?

Ответить   -=BorMaN=- Thu, 11 Mar 2004 19:50:37 +0200 (#101084)

 

"-=BorMaN=-" ты не прав

Тема: Re[2]: Cpp Builder | Delphi WinExec

Специально не проверял - вроде задач таких не было. Но судя по описанию, проблемой
является подождать, пока этот новый процесс не завершиться. Рекомендуется после
создания процесса закрыть его дескрипторы с помощью CloseHandle. Иначе он остается
в памяти пока его потоки не завершатся и дескрипотры не будут закрыты.
Наверно, чтоб не закрылся с закрытием родиельского, стоит не наследовать дескрипотры
родительские:
lpInheritHandles = FALSE, а dwCreationFlags = CREATE_NEW_CONSOLE (создается процесс
со своим окном)

WinExec все равно реализована через CreateProcess - посмотри исходники хотя бы,
да и в хороших книгах об этом есть. (Этот факт обычно отмечают в разделе CreateProcess).
Да и сохраняется только для совместимости с ранними (!) версиями Windows (!!)

Ответить   Fri, 12 Mar 2004 08:19:06 +0300 (#101152)

 

процесс

Кажется, просьба читать документацию превращается в глас вопиющего в пустыне.
Хотя, чем черт не шутит, может кого-нибудь проймет.

Во-первых, мало ли что говорят. Люди склонны заблуждаться. Если не предпринимать
дополнительных усилий, порожденный процесс не завершится
при завершении родительского.
Во-вторых, признак наследования дескрипторов определяет, будут ли в порожденном
процессе доступны дескрипторы открытых объектов (с теми же значениями и
правами доступа). К заданному вопросу он не имеет никакого отношения.
В-третьих, CREATE_NEW_CONSOLE заставляет создать отдельную
консоль для порожденного процесса, а не отдельное окно. Это
разные вещи - окна могут создаваться только явно.
В-четвертых, закрывать дескрипторы из структуры PROCESS_INFORMATION
после вызова CreateProcess действительно необходимо. Иначе, даже
если порожденный процесс завершится, объект процесса будет
существовать до завершения родительского процесса (хотя
большая часть ресурсов, использованных потомком,
все-таки будет освобождена). Дескриптор порожденного процесса
может понадобиться разве что для ожидания его завершения
(с помощью WaitForSingleObject), а в большинстве
случаев его можно закрыть сразу.

Это так. Причем, судя по документации, реализована очень просто.
А раз функция API не работает именно при использовании конкретной
среды разработки (в данном случае C++ Builder), есть смысл
посмотреть на свои исходники и файлы заголовков -
нет ли там каких тонкостей.
Номер выпуска : 2551
Возраст листа : 172 (дней)
Количество подписчиков : 378
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/101337
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

-*Информационный канал Subscribe.Ru
Написать в лист: mailto:comp.soft.prog.prog-list@subscribe.ru
Отписаться: mailto:comp.soft.prog.prog--unsub@subscribe.ru

http://subscribe.ru/ mailto:ask@subscribe.ru

Ответить   Fri, 12 Mar 2004 12:51:34 +0300 (#101337)

 

Здравствуйте, -=BorMaN=-.

Вы писали 11 марта 2004 г., 19:50:37:

Программа, загруженная через CreateProcess, может быть закрыта программой
запустившей её, только, если эта программа (вызвавшая CreateProcess) специально
того захочет, т.е. вызовет TerminateProcess, передав функции в качестве
описателя процеса (HANDLE) описатель загруженной программы. Например,
при закрытии Fara программы запущенные им автоматически не выгружаются.

В MSDN по этому поводу сказано:
Note This function is provided only for compatibility with 16-bit Windows.
Applications should use the CreateProcess function.
Тем более, что WinExec, если я не ошибаюсь, всё равно вызывает
CreateProcess. С этой функцией у меня ни в Cpp ни в Delphi проблем не
было.

А вообще, если хочешь в этом разобраться, почитай Джефри Рихтера "Windows
для проффесионалов".

Ответить   Пастернак Сергей Fri, 12 Mar 2004 10:23:27 +0200 (#101396)

 

Здарова, -=BorMaN=-!

11 марта 2004 г., четверг, 22:50:37 (GMT+05:00), ты намылил:

Surin_bp>> Тема: Cpp Builder | Delphi WinExec

Surin_bp>> Всегда лучше использовать CreateProcess - не
Surin_bp>> интересовался в Builder'e, но в
Surin_bp>> Delphi все равно идет вызов CreateProcess

Вот код WinExec:
function WinExec; external kernel32 name 'WinExec';

Вот цитата из хелпа:
The CreateProcess function is used to run a new program.
The WinExec and LoadModule functions are still available,
but they are implemented as calls to CreateProcess.

Складываем 2 + 2, получаем что WinExec - функция API в которой
вызывается CreateProcess - так же функция API, т.е. WinExec и на
ассемблере будет вызывать CreateProcess.

Держи прогу с помощью которой я запускаю Bat + MyGate (кривовата
прога, но работает):

program RunBat;
uses
Windows, Messages;
var hProcess: THandle;

function RunAppAndWait(CmdLine, WorkDir: string; Wait: boolean): THandle;
var SI: TStartupInfo;
PI : TProcessInformation;
Bool: boolean;
begin
Result := 0;
ZeroMemory(@SI, SizeOf(SI));
SI.cb := SizeOf(SI);
if not Wait then
begin
SI.dwFlags := STARTF_USESHOWWINDOW;
SI.wShowWindow := SW_SHOWMINNOACTIVE;
end;
Bool := CreateProcess(nil, PChar(CmdLine), nil, nil, false, 0,
nil, PChar(WorkDir), SI, PI);
if Bool then
begin
CloseHandle(PI.hThread);
if Wait then WaitForSingleObject(PI.hProcess, INFINITE);
Result := PI.dwProcessId;
CloseHandle(PI.hProcess)
end;
end;

begin
hProcess := RunAppAndWait('C:\Program Files\MyGate\MyGate.exe', 'C:\Program
Files\MyGate', false);
RunAppAndWait('C:\Program Files\The Bat!\thebat.exe', 'C:\Program Files\The
Bat!', true);
TerminateProcess(OpenProcess(PROCESS_ALL_ACCESS,false,hProcess),1);
end.

Delphi 5:
procedure TForm1.Button1Click(Sender: TObject);
begin
WinExec('c:\winnt\notepad.exe', SW_SHOW);
end;

Builder 5:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
WinExec("c:\\winnt\\notepad.exe", SW_SHOW);
}

Или так:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
char* CmdLine1;
CmdLine1 = "c:\\winnt\\notepad.exe";
WinExec(CmdLine1, SW_SHOW);
}

Ничего не глючит. Приведи свой код - станет понятней.

PS: Кстати в Delphi можно так:

Bool := CreateProcess(nil, PChar(CmdLine), nil, nil, false, 0,
^^^ ^^^^^^^^^^^^^^
nil, PChar(WorkDir), SI, PI);

и так:

Bool := CreateProcess(PChar(CmdLine), nil, nil, nil, false, 0,
^^^^^^^^^^^^^^ ^^^
nil, PChar(WorkDir), SI, PI);

А в Buildere можно только так:

Bool = CreateProcess(CmdLine1, "", NULL, NULL, false, 0,
^^^^^^^^ ^^
NULL, WorkDir, &SI, &PI);

А вот так не запускается CmdLine1:

Bool = CreateProcess("", CmdLine1, NULL, NULL, false, 0,
^^ ^^^^^^^^
NULL, WorkDir, &SI, &PI);

т.е. одна и та же API вызывается по разному?

--
Никогда больше не буду говорить афоризмами. Да, кстати, запишите мою последнюю
фразу

Ответить   Томилов Александр Fri, 12 Mar 2004 17:05:51 +0500 (#101745)

 

Hello Томилов,

Friday, March 12, 2004, 3:05:51 PM, you wrote:

Surin_bp>>> Тема: Cpp Builder | Delphi WinExec

Surin_bp>>> Всегда лучше использовать CreateProcess - не
Surin_bp>>> интересовался в Builder'e, но в
Surin_bp>>> Delphi все равно идет вызов CreateProcess

Лучше использовать ShellExecute - работает всегда и проблем никаких.
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);

есть еще ShellExecuteEx - совсем навороченная, но с ней я не работал.

Ответить   Sat, 13 Mar 2004 10:10:39 +0300 (#101900)

 

Здарова, Ghost!

13 марта 2004 г., суббота, 12:10:39 (GMT+05:00), ты намылил:

Видали мы таких навороченных ;)
Код я привожу не свой. Мне вся мощь ShellExecuteEx не нужна была.
Пример из форума.

function StartWithShell(Prog, Par, Verz: string; var hProcess: THandle): DWORD;
var exInfo: TShellExecuteInfo;
begin
hProcess := 0;
FillChar(exInfo, Sizeof(exInfo), 0);
with exInfo do
begin
cbSize := Sizeof(exInfo);
fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
Wnd := 0;
lpVerb := 'open';
lpParameters := PChar(par);
lpFile := Pchar(prog);
nShow := SW_SHOW;//HIDE;
end;
Result := ERROR_SUCCESS;
if ShellExecuteEx(@exInfo) then hProcess := exinfo.hProcess
else Result := GetLastError;
end;

function StartProgramm: Boolean;
var r: DWORD;
ExitCode: DWORD;
err: string;
hProcess: THandle;
begin
Result := False;
r := StartWithShell('c:\progra~1\winrar\rar.exe', '', 'c:\winnt\system32',
hProcess);
if r = ERROR_SUCCESS then
begin
repeat
Application.ProcessMessages;
GetExitCodeProcess(hProcess, ExitCode);
until (ExitCode <> STILL_ACTIVE);
result := true;
end
else
begin
case r of
ERROR_FILE_NOT_FOUND : err:='The specified file was not found.';
ERROR_PATH_NOT_FOUND : err:='The specified path was not found.';
ERROR_DDE_FAIL : err:='The DDE transaction failed.';
ERROR_NO_ASSOCIATION : err:='There is no application associated with
the given filename extension.';
ERROR_ACCESS_DENIED : err:='Access denied';
ERROR_DLL_NOT_FOUND : err:='DLL not found';
ERROR_CANCELLED : err:='The function prompted the user for the location
of the application, but the user cancelled the request.';
ERROR_NOT_ENOUGH_MEMORY: err:='Not enough memory';
ERROR_SHARING_VIOLATION: err:='A sharing violation occurred.';
else err:='Unknown';
end;
MessageDlg('Error: ' + err, mtError, [mbOk], 0);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if StartProgramm then ShowMessage('cool');
end;

А вообще ShellExecuteEx много чего умеет при разных lpVerb
lpVerb := 'open';
lpVerb := 'properties';
lpVerb := 'print';
lpVerb := 'explore';
и т.д. Полный список я не нашел (да и не особо искал ;)

А этот код из LsFileExplorer28.pas

procedure ShowProperties(FName: string); //862 >>
var
sei: SHELLEXECUTEINFO;
err: longint;
begin
try
ZeroMemory(addr(sei),sizeof(sei));
sei.cbSize := sizeof(sei);
sei.lpFile := pchar(FName);
sei.lpVerb := 'properties';
sei.fMask := SEE_MASK_INVOKEIDLIST;
ShellExecuteEx(addr(sei));
except
err:=getlasterror;
case err of
ERROR_FILE_NOT_FOUND: showmessage('The specified file was not found.');
ERROR_PATH_NOT_FOUND: showmessage('The specified path was not found.');
ERROR_DDE_FAIL: showmessage('The DDE transaction failed.');
ERROR_NO_ASSOCIATION: showmessage(
'There is no application associated with the given filename extension.');
ERROR_ACCESS_DENIED: showmessage('Access denied');
ERROR_DLL_NOT_FOUND : showmessage('DLL not found');
ERROR_CANCELLED : showmessage('The function prompted the user for the '
+
'location of the application, but the user cancelled the request.');
ERROR_NOT_ENOUGH_MEMORY: showmessage('Not enough memory for this operation');
ERROR_SHARING_VIOLATION: showmessage('Sharing violation');
end;
end;
end; {ShowFileProperties} //862 <<

--
Никогда больше не буду говорить афоризмами. Да, кстати, запишите мою последнюю
фразу

Ответить   Томилов Александр Sat, 13 Mar 2004 15:41:50 +0500 (#102382)

 

==-==-=-Привета!10 марта 2004 г. (среда 20:41:01) -=BorMaN=- (E-Mail: <BormanSubscri***@u*****.net>)
в мессаге <<Cpp Builder | Delphi WinExec>> накрапал

-=BorMaN=-> Дрова!

-=BorMaN=-> Есть такая API'шная функция
-=BorMaN=-> UINT WinExec(LPCSTR lpCmdLine, // address of command line
-=BorMaN=-> UINT uCmdShow // window style for new application
-=BorMaN=-> );
-=BorMaN=-> Дык когда я ее юзаю под Delphi - все ОК, а
-=BorMaN=-> вот под Cpp Builder выдает значение
-=BorMaN=-> 0 (The system is out of memory or resources)
-=BorMaN=-> [все на 100% идентично, т.е. копируем
-=BorMaN=-> из Дельфа и вставляем в Срр]

-=BorMaN=-> Что делать? И в чем вся фигня???

Спасибо всем!!! Особенно Александру (Томилову)!!!
В С++ вся суть была в следующем:
Срр: WinExec("c:\\winnt\\notepad.exe", SW_SHOW);
Delphi: WinExec('c:\winnt\notepad.exe', SW_SHOW);
[\\-CPP|\-Delphi]

Ответить   -=BorMaN=- Sat, 13 Mar 2004 02:44:46 +0200 (#101819)