Помощь - Поиск - Пользователи - Календарь
Полная версия: Запуск Bat-файла
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Делфи
Cygno
Такой вопросец...

Как средствами Delphi 7 организовать запуск bat-файла (да и вообще любого внешнего файла? Чт оза функция управляет этиим? И нужно ли чего подключать, в Uses
(есть только имя файла с путем к нему, какие еще параметры нужны?)

Когда пишу ShellExecuteEx - мне не выдает параметров, как будто такой функции нет..

Может я опять чего не увидел в хелпе? smile.gif :p2:
volvo
Легче всего использовать WinExec. При обращении к WinExec необходимо задать полный путь к программе или имя EXE файла, расположенного в пути поиска, а также способ отображения программы (константы SW_HIDE, SW_SHOW,
SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE? SW_SHOWNA, SW_SHOWNORMAL).

Если вызов функции произошел успешно, то WinExec вернет дескриптор новой
программы (который не может быть меньше 32, т.е. если WinExec возвращает число меньше 32, то вызов привел к ошибке...

Еще один простой вызов это - ShellExecute. Этот вызов во многом напоминает WinExec, однако он поддерживает обработку типов файлов, зарегистрированных в Windows. Например, если вы с помощью ShellExecute вы попробуете запустить файл с расширением .BMP, то буде запущена программа Paint или любая другая, которая использует для просмотра графических файлов. В качестве аргументов ShellExecute принимает дескриптор окна (если есть необходимость в сообщениях об ошибках), строку, такую как open (открыть), print (напечатать) и explore (исследовать), можно в качестве этой строки передать NULL, тогда файл указанный вами будет открыт (open). Так же ShellExecute необходимо сообщить имя файла и любые параметры командной строки (чаще всего NULL), и оставшиеся два аргумента это текущий каталог и константа функции ShowWindow (как и в WinExec).

Значение, которое возвращает ShellExecute такое же, как и у WinExec. Функцию ShellExecute можно использовать, например, для открытия корневого каталога диска С:
Код

ShellExecute(hWnd, 'open', 'c:\', nil, nil, SW_SHOWNORMAL);


Вы можете заменить строку "open" на "explore" и в качестве третьего параметра указать любой каталог, в этом случае указанная вами папка откроется в Проводнике (Explorer).

Так же существует системный вызов ShellExecuteEx, который фактически является полным аналогом ShellExecute, однако в качестве аргумента он принимает указатель на структуру, поля которой во многом совпадают с аргументами ShellExecute. Кроме этого после завершения своей работы ShellExecuteEx помещает в одно из полей этой структуры дескриптор запущенной программы.
Применение этих вызовов довольно просто. Пример программы использующей WinExec и ShellExecute:

Код

uses ShellAPI;

var
 h: hwnd;
begin
// Используем ShellExecute
 if ShellExecute(h, 'open', 'readme.txt', nil, nil, SW_SHOW) < 32 then
   begin
     ShowMessage('Немогу выполнить ShellExecute !')
   end;
// Используем WinExec
 if WinExec('Notepad c:\config.sys', SW_SHOW) < 32 then
   begin
     ShowMessage('Немогу выполнить WinExec !')
   end;
end;


(Взято из Delphi Russian Knowledge Base 2.0)
Cygno
volvo
Благодарю, сейчас попробуем.

Добавлено (26.10.04 11:31):

Код
procedure TfrmPPG.btnRunClick(Sender: TObject);
var
 iDelim: integer;
 sProjSettFile, ss: string;
begin

  iDelim := Pos(' ',frmPPG.lstProjects.Items.Strings[frmPPG.lstProjects.ItemIndex]);
  sProjSettFile := Copy(frmPPG.lstProjects.Items.Strings[frmPPG.lstProjects.ItemIndex],1,iDelim-1) + '_settings.bat';

  ss := 'D:\delphi\' + sProjSettFile;

  WinExec(ss,SW_SHOW);

end;


При запуске...
Цитата
Incopatible types "String" and "PAnsiChar"


Ругается на переменную ss, которая тип-String, однако, как переконвертировать String в PAnsiChar?

Или вообще, так как я делаю - неправильно в корне?

ss содержит путь и имя файла, который надо запускать. Вычисляется программно, не из формы.
Atos
Cygno , а не пробовал сразу объявлять не string, a PAnsiChar?
По-моему этот тип - массив [0..255] символов... хотя точно не уверен.
Cygno
Пробовал.
Но мне надо выполнить конкатенацию - собрать две части пути, и компилятор ругается, когда я пробую выполнить выражение
Код
ss := 'D:\delphi\' + sProjSettFile;
, при ss: PAnsiChar;
volvo
Cygno

Попробуй так:


procedure TfrmPPG.btnRunClick(Sender: TObject);
var
 iDelim: integer;
 sProjSettFile: string
 ss: PAnsiChar;
begin
iDelim := Pos(' ',frmPPG.lstProjects.Items.Strings[frmPPG.lstProjects.ItemIndex]);
sProjSettFile := Copy(frmPPG.lstProjects.Items.Strings[frmPPG.lstProjects.ItemIndex],1,iDelim-1) + '_settings.bat';

ss := PAnsiChar('D:\delphi\' + sProjSettFile);
WinExec(ss,SW_SHOW);

end;

Cygno
Спасибо, volvo !

Сработало.

Только вот почему, когда я пишу функцию в окне кода, например
PAnsiChar( - ставлю открывающую скобку, а мне ничего не выдается, типа списка параметров?

Не для всех функций что ли так сделано?
Atos
Ага, я опоздал, volvo уже и текст привёл... smile.gif
Кстати, спасибо за рассказ о ShellExecute, я тоже не знал. А откуда была эта информация?
Cygno
В продолжение...

При выполнение команды


WinExec(ss,SW_SHOW);


виндоуз ХР выдает приглашение об открытии, сохранении этого файла (безопасность smile.gif )

Можно ли подавить это сообщение? Мне нужно чтобы этот файл всегда запускался.
xds
Цитата
The WinExec function runs the specified application.

This function is provided for compatibility with earlier versions of Windows. For Win32-based applications, use the CreateProcess function.


Код
procedure TMainForm.btLaunchClick(Sender: TObject);
var
 pi: TProcessInformation;
 si: StartupInfo;
begin
 FillChar(si, SizeOf(si), 0);
 si.cb := SizeOf(si);
 if not CreateProcess(nil, 'code.bat', nil, nil, False, 0, nil, nil, si, pi) then
   Application.MessageBox('Unable to execute "code.bat"', 'Error', MB_OK or MB_ICONERROR);
end;
Cygno
Очередная проблема с этими запусками.......

Есть папка на серваке - \\servername\folder\

В этой папке лежит мое приложение (exe-шник), два файла, типа конфигурационных к нему
и батник, который в результате работы должен быть запущен.

Все пути к файлам, которые читает прога - относительные
то есть без указания полного пути..

Конфиг-файлы, прога видит нормально.
Пример из кода:
Код
AssignFile(fProjConfig,'file.cfg');
Reset(fProjConfig);


Батник, этот несчастный, прописан также относительно и лежит там же.

Код
WinExec('batfile.bat',SW_SHOW);



Однако, при запуске выдается ошибка:

Цитата
"\\servername\folder"
Указанный путь был использован при запуске cmd.exe в качестве текущей папки. CMD.exe не поддерживает пути UNC. По умолчанию выбрана системная папка Windows. Системе не удается найти указанный путь.



Что за фигня, не понимаю?
Почему он так преобразует путь?

С места, то есть просто двойным щелчком, батник запускается нормально.
Из Пуск--Выполнить--\\servername\folder\batfile.bat --- тоже
Из CMD - C:\>\\servername\folder\batfile.bat - тоже нормально.

В чем дело не пойму

Может кто подскажет?
volvo
Cygno

Ну если у тебя:
Цитата
Из CMD - C:\>\\servername\folder\batfile.bat - тоже нормально.


так почему не сделать так:


WinExec('cmd.exe \\servername\folder\' + 'batfile.bat',SW_SHOW);



:yes:
Atos
Гм... если путь относительный, то почему бы не приписать к нему и абсолютные координаты, взятые из командной строки вызова самой твоей проги?
По крайней мере на TP это выглядело бы примерно так:

  Dir:DirStr;
  Name:NameStr;
  Ext:extstr;
  s:PathStr;

begin
s:=ParamStr(0);
FSplit(s,Dir,Name,Ext); Dir - имя нужной директории
assign(f,Dir+'batfile.bat');

volvo
Cygno

Есть еще один момент - у тебя случайно в пути к файлу нет кириллицы? По-моему, из-за этого ты тоже можешь получить:
Цитата
Указанный путь был использован при запуске cmd.exe в качестве текущей папки. CMD.exe не поддерживает пути UNC. По умолчанию выбрана системная папка Windows. Системе не удается найти указанный путь.
Cygno
Кириллицы точно нет.

Цитата
так почему не сделать так:
WinExec('cmd.exe \\servername\folder\' + 'batfile.bat',SW_SHOW);


Так не хочу, потому что всегда разные пути будут до сервера и папки, в зависимости, от того куда программа будет установлена..

И не получилось так . Такая же ошибка sad.gif

Добавлено (27.10.04 14:21):

Цитата
assign(f,Dir+'batfile.bat');

Но мне не нужно делать Assign. Мне нужно запустить на выполнение из известного места.
volvo
Cygno

А ведь Atos прав - лучше всего запускать батник из той же директории, где находится exe - файл. Что-то типа этого:


 WinExec(ExtractFilePath(Application.ExeName) + 'batfile.bat',SW_SHOW);



(но этот код я не проверял :no: )
Cygno
Ну что ж господа - свершилось чудо! smile.gif

Цитата
WinExec(ExtractFilePath(Application.ExeName) + 'batfile.bat',SW_SHOW);


Это сработало. Хоть та же ошибка и выдается, но по крайней мере батники запускаются.


Atos, volvo - спасибо!!
P@sh@
Cygno
Только вот почему, когда я пишу функцию в окне кода, например
PAnsiChar( - ставлю открывающую скобку, а мне ничего не выдается, типа списка параметров?

это ведь не функция, это тип...
а выражение type(var) - не что иное как явное преобразование типов (в С оно, кстати, записывается наоборот - (type)var )
Cygno
Я думал, что это функция, отвечающая за преобразование типов.

Если я пишу, например: StrToFloat(, ставлю скобку, то открывается подсказка, какой тип параметра нужен.
hydroxychloroquine over the coun
Amoxicillin Dosage For Domestic House Cat
promethazine without prescriptio
5mg Cialis From India
nishaknapp
Why not settling on games that is fun and at the same time your earning. Well it'll make suspense because the game is well but dude just try it and it gave me hope while pandemic is real rn. Here’s a Simple Guide to Start Your Online Casino Journey
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.