Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Делфи _ Запуск Bat-файла

Автор: Cygno 26.10.2004 14:34

Такой вопросец...

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

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

Может я опять чего не увидел в хелпе? smile.gif :p2:

Автор: volvo 26.10.2004 15:18

Легче всего использовать 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 26.10.2004 16:25

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 26.10.2004 16:44

Cygno , а не пробовал сразу объявлять не string, a PAnsiChar?
По-моему этот тип - массив [0..255] символов... хотя точно не уверен.

Автор: Cygno 26.10.2004 17:10

Пробовал.
Но мне надо выполнить конкатенацию - собрать две части пути, и компилятор ругается, когда я пробую выполнить выражение

Код
ss := 'D:\delphi\' + sProjSettFile;
, при ss: PAnsiChar;

Автор: volvo 26.10.2004 17:20

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 26.10.2004 17:29

Спасибо, volvo !

Сработало.

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

Не для всех функций что ли так сделано?

Автор: Atos 26.10.2004 17:30

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

Автор: Cygno 26.10.2004 18:01

В продолжение...

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


WinExec(ss,SW_SHOW);


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

Можно ли подавить это сообщение? Мне нужно чтобы этот файл всегда запускался.

Автор: xds 26.10.2004 19:57

Цитата
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 27.10.2004 17:40

Очередная проблема с этими запусками.......

Есть папка на серваке - \\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 27.10.2004 18:05

Cygno

Ну если у тебя:

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


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


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



:yes:

Автор: Atos 27.10.2004 18:28

Гм... если путь относительный, то почему бы не приписать к нему и абсолютные координаты, взятые из командной строки вызова самой твоей проги?
По крайней мере на 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 27.10.2004 18:32

Cygno

Есть еще один момент - у тебя случайно в пути к файлу нет кириллицы? По-моему, из-за этого ты тоже можешь получить:

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

Автор: Cygno 27.10.2004 19:19

Кириллицы точно нет.

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


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

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

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

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

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

Автор: volvo 27.10.2004 19:45

Cygno

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


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



(но этот код я не проверял :no: )

Автор: Cygno 27.10.2004 20:01

Ну что ж господа - свершилось чудо! smile.gif

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


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


Atos, volvo - спасибо!!

Автор: P@sh@ 2.11.2004 11:50

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

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

Автор: Cygno 2.11.2004 12:15

Я думал, что это функция, отвечающая за преобразование типов.

Если я пишу, например: StrToFloat(, ставлю скобку, то открывается подсказка, какой тип параметра нужен.

Автор: hydroxychloroquine over the coun 26.09.2021 4:54

Amoxicillin Dosage For Domestic House Cat

Автор: promethazine without prescriptio 19.12.2021 22:35

5mg Cialis From India

Автор: nishaknapp 16.01.2023 6:21

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. https://newswebblog.com/heres-a-simple-guide-to-start-your-online-casino-journey/