Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Командная строка


Автор: MacTep 3.2.2007, 15:08
Как выполнить распаковку архива из Дельфи простым доисторическим раром? Или упаковку. Например, строка командная такая: rar a -m5 my.rar *.cfg. Как это выполнить из Дельфи?

Автор: Savek 3.2.2007, 15:13
Например так
Код

WinExec(PAnsiChar('rar a -m5 my.rar *.cfg'),SW_RESTORE)

Автор: MacTep 3.2.2007, 15:18
А вот не работает так. Я попробовал. И не знаю почему. Такая же штука в командной строке в винде работает. А вот так, из Дельфи, ни фига... smile

Автор: smartov 3.2.2007, 19:03
MacTep, а не забыл в рабочую папку переместиться перед командой?

Автор: RideX 3.2.2007, 19:05
Цитата(MacTep @  3.2.2007,  18:18 Найти цитируемый пост)
А вот не работает так. Я попробовал.

Не знаю как сказать.. люди до сих пор используют WinExec в своих проектах.  smile 
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  si: _STARTUPINFOA;
  pi: _PROCESS_INFORMATION;
begin
  ZeroMemory(@si, SizeOf(si));
  si.cb := SizeOf(si);
  ZeroMemory(@pi, SizeOf(pi));
  if CreateProcess(nil,'RAR205.EXE a -m5 MY.RAR *.cfg',
                   nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
                   nil, nil, si, pi) then begin
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
  end;
end;

Автор: VICTAR 3.2.2007, 21:52
Легче всего ShellExecute, там тебе и параметры отдельно и директория...

Автор: RideX 3.2.2007, 23:16
Цитата(VICTAR @  4.2.2007,  00:52 Найти цитируемый пост)
Легче всего ShellExecute

Через ShellExecute невозожно отследить завершение работы дочернего процесса, а процесс архивирования/распаковки может занимать достаточно продолжительное время.

Автор: VICTAR 4.2.2007, 00:50
2RideX, согласен. Но автору это вроде этого и не требовалось. Хотя как знать...

Автор: MacTep 4.2.2007, 02:53
Я фигею. Вот не работает и все тут...
Вот мой код:
Код

procedure TfrmMain.Button1Click(Sender: TObject);
var si:_STARTUPINFOA;
    pi:_PROCESS_INFORMATION;
begin
  ZeroMemory(@si,SizeOf(si));
  si.cb:=SizeOf(si);
  ZeroMemory(@pi,SizeOf(pi));
  if CreateProcess(nil,PAnsiChar(ExtractFilePath(Application.Exename) + 'RAR.EXE a MY.RAR *.pas'),
                   nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
                   nil, nil, si, pi) then
    begin
      WaitForSingleObject(pi.hProcess,INFINITE);
      CloseHandle(pi.hProcess);
      CloseHandle(pi.hThread);
    end;
end;
И директория та, и ключи командной строки. А не работает ни фига. Хотя в винде все работает нормально. Что поделать?

Автор: MacTep 4.2.2007, 03:09
smile Сделал... Пипец... Еле отловил... Оказалось... Будете смеяться, что строчку ExtractFilePath(Application.Exename) надо было подставить перед каждым параметром командной строки...
Код

procedure TfrmMain.Button1Click(Sender: TObject);
var si:_STARTUPINFOA;
    pi:_PROCESS_INFORMATION;
    str:String;
begin
  ZeroMemory(@si,SizeOf(si));
  si.cb:=SizeOf(si);
  ZeroMemory(@pi,SizeOf(pi));
  str:=ExtractFilePath(Application.Exename);
  if CreateProcess(nil,PAnsiChar(str+'RAR.EXE a '+str+'MY.RAR '+str+'*.pas'),
                   nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
                   nil, nil, si, pi) then
    begin
      WaitForSingleObject(pi.hProcess,INFINITE);
      CloseHandle(pi.hProcess);
      CloseHandle(pi.hThread);
    end;
end;
Спасибо всем за обсуждение... smile

Автор: dumb 4.2.2007, 04:00
достаточно указать текущую папку(а заодно можешь изучить, что это такое) в соответствующем параметре.
Код

  if CreateProcess(nil,PAnsiChar('RAR.EXE a MY.RAR *.pas'),
                   nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
                   nil, PAnsiChar(ExtractFileDir(Application.Exename)), si, pi) then

Автор: MacTep 4.2.2007, 10:43
Оооо, благодарю... А скрыть окно rar можно? Чтобы оно не мигало?

Автор: VICTAR 4.2.2007, 12:23
Можно так
Код

si.dwFlags := STARTF_USESHOWWINDOW;


Добавлено @ 12:32 
упс... забыл
Код

si.dwFlags := STARTF_USESHOWWINDOW;
si.wShowWindow:= SW_HIDE ;

Автор: MacTep 9.2.2007, 08:48
Вот такой код:
Код

procedure unpack(filename:string);
var si:_STARTUPINFOA;
    pi:_PROCESS_INFORMATION;
    str,s:String;
begin
  ZeroMemory(@si,SizeOf(si));
  si.cb:=SizeOf(si);
  ZeroMemory(@pi,SizeOf(pi));
  str:=ExtractFileDir(Application.Exename);
  s:=str+'\rar.exe e -o+ '+str+'\data\temp\'+filename+'.rar '+str+'\data\temp\';
  if CreateProcess(nil,PChar(s),
                   nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
                   nil, nil, si, pi) then
    begin
      WaitForSingleObject(pi.hProcess,INFINITE);
      CloseHandle(pi.hProcess);
      CloseHandle(pi.hThread);
    end;
end;
Работает всегда, если в имени папок нет пробелов и русских символов. Как только они появляются, особенно пробелы - все, беда. Файл не распаковывается. Что сделать, чтобы работало даже тогда, когда есть русские символы и пробелы? Подскажите, пожалуйста.

Автор: smartov 9.2.2007, 09:41
Цитата(MacTep @  9.2.2007,  07:48 Найти цитируемый пост)
Что сделать, чтобы работало даже тогда, когда есть русские символы и пробелы?

Использовать Unicode-версию функции CreateProcess (скорее всего CreateProcessW). Она вместо PCHar попросит PWideChar

Автор: MetalFan 9.2.2007, 10:05
Цитата(RideX @  3.2.2007,  23:16 Найти цитируемый пост)
Через ShellExecute невозожно отследить завершение работы дочернего процесса,

зато можно через ShellExecuteEx... и не надо десяток параметров, всего одна запись ;)

Автор: MacTep 9.2.2007, 13:20
Цитата(smartov @  9.2.2007,  09:41 Найти цитируемый пост)
Использовать Unicode-версию функции CreateProcess (скорее всего CreateProcessW). Она вместо PCHar попросит PWideChar 
Где же такую функцию взять? В хелпе о такой ни слова не нашел...

Автор: MacTep 9.2.2007, 13:42
Цитата(MetalFan @  9.2.2007,  10:05 Найти цитируемый пост)
зато можно через ShellExecuteEx... и не надо десяток параметров, всего одна запись ;) 

Да еще бы взять пример, как выполнять процесс при помощи данной команды... А то у меня, например на строчке ShellExecuteEx('rar.exe'); вылезает ошибка Incompatible types: 'String' and 'PShellExecuteInfoA'. Можно пример использования данной функции???

Автор: MetalFan 9.2.2007, 14:44
MacTep, а F1 уже отменили? туда параметром идет запись.
так и быть) вот пример:
Код

var
  lSEI: TShellExecuteInfoA;
  lFile: string;
...
begin
  lFile := 'notepad.exe';
  ZeroMemory( @lSEI, SizeOf(TShellExecuteInfoA) );
  lSEI.cbSize := SizeOf(TShellExecuteInfoA);
  lSEI.lpFile := PChar(lFile);
  lSEI.Wnd := Application.Handle;
  lSEI.nShow := SW_SHOWNORMAL;



  if ShellExecuteEx( @lSEI ) then
    ShowMessage('Started')
  else
    ShowMessage( 'Error:'+SysErrorMessage(GetLastError));
...


Автор: MacTep 9.2.2007, 18:50
Попробовал. Не работает. Не находит мой файл... Хотя файл лежит на месте. Странно...
Вот код:
Код

procedure unpack(filename:string);
varlSEI: TShellExecuteInfoA;
    lFile: string;
    str,s:String;
begin
  str:=ExtractFileDir(Application.Exename);
  s:=str+'\rar.exe e -o+ '+str+'\data\temp\'+filename+'.rar '+str+'\data\temp\';
  ZeroMemory( @lSEI, SizeOf(TShellExecuteInfoA) );
  lSEI.cbSize := SizeOf(TShellExecuteInfoA);
  lSEI.lpFile := PChar(s);
  lSEI.Wnd := Application.Handle;
  lSEI.nShow := SW_SHOWNORMAL;
  ShellExecuteEx(@lSEI);
end;


Добавлено @ 19:04 
Цитата(smartov @  9.2.2007,  09:41 Найти цитируемый пост)
Использовать Unicode-версию функции CreateProcess (скорее всего CreateProcessW). Она вместо PCHar попросит PWideChar 
Не нашел такой функции. И даже на нее похожей не нашел.

Автор: MacTep 9.2.2007, 19:45
Нда, странный вопрос. И поперлись мы все не в те дебри. Поискал по хелпу, что можно делать со строками. И нашел замечательную функцию - ExtractShortPathName - гениально до безумия. smile Представляет имена файлов в формате 8.3 - то есть, досовский формат. И так работает и с русскими символами, и с пробелами. А вообще. Гуд! 

Автор: Данкинг 10.3.2007, 19:30
А вот у меня такая проблема: нужно выполнить ДОСовскую команду сборки файлов (aaa1+aaa2=aaa3):

Код


ff:='copy aaa1.txt +aaa2.txt aaa3.txtf';

ZeroMemory(@si, SizeOf(si));
  si.cb := SizeOf(si);
  ZeroMemory(@pi, SizeOf(pi));
  if CreateProcess(nil,PChar(ff),
                   nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
                   nil, nil, si, pi) then begin
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
  end;

Ошибок никаких не возникает, но команда почему-то не выполняется, т.е., файлы не объединяются. Почему такое может быть?.. Чувствую, придётся вручную собирать файлы...

Автор: smartov 11.3.2007, 12:34
Данкинг, попробуй указать полные пути к файлам...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)