Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.03.04;
Скачать: CL | DM;

Вниз

ShellAPI. ShellExecute, не уверен что срабатывает.   Найти похожие ветки 

 
UrbanRider   (2007-02-08 01:07) [0]

Доброго времени суток.
У меня стоит Delphi 2005 aka Delphi 9.

Проблема такова: пытаюсь из своего приложения запустить другое с передачей параметров, посредством ShellExecute.

В результате запуска побочной проги должен создаться файл(мое приложение и побочное приложение находятся в одной папке, файл должен быть создан там же).

Но, как говорится, должен, но не делает.

Делаю я так:


procedure TForm1.BDecryptClick(Sender: TObject);
Var
Param: Pchar;
begin
Param:=Pchar(Edit1.Text);  //в Edit1 лежат параметры для предачи в l2endec, присваиваем их переменной Param
ShellExecute(Handle,"open","l2endec.exe", Param, NIL, SW_SHOWNORMAL);//запуск приложения l2endec
end;


скажите что может быть не так?

Если несовсем понятно что к чему, я дам полный текст программы.


 
UrbanRider   (2007-02-08 01:11) [1]

Ах да чуть не забыл, если параметров не передавать, то я вижу как открывается и быстро закрывается окно l2endec, т.к. нет параметров для дальнейшей работы(l2endec-консольное приложение).

А когда параметры передаю, то я не наблюдаю никаких действий.


 
UrbanRider   (2007-02-08 01:17) [2]

и еще, если вместо ShellExecute(Handle,"open","l2endec.exe", Param, NIL, SW_SHOWNORMAL);
написать ShellExecute(Handle,"open","l2endec.exe", "-l systemmsg-e.dat", NIL, SW_SHOWNORMAL);
то все начинает работать, однако второй параметр(systemmsg-e.dat) динамический и поэтому такая работа меня не устраивает.


 
UrbanRider   (2007-02-08 01:39) [3]

нашел еще одну странную вещь:

после выполнения этого кода(код1):
procedure TForm1.BOpenFileClick(Sender: TObject);
var
AppDir: Pchar;
FName: Pchar;
FName2: Pchar;
EFName2: Pchar;
begin
OpenDialog1.Execute;
AppDir:=Pchar(ExtractFilePath(Application.ExeName));
FName:=Pchar(OpenDialog1.FileName);
EFName2:=Pchar(ExtractFileName(OpenDialog1.FileName));
FName2:=Pchar(AppDir+""+EFName2);
Edit1.Text:="";
Edit1.Text :="-l"+" "+EFName2;
if FileExists(FName) then
if CopyFile(FName,FName2,true) then
 ShowMessage("Файл успешно скопирован и готов к дальнейшей обработке!")
end;


даже ранее рабочий код(2):
ShellExecute(Handle,"open","l2endec.exe","-l systemmsg-e.dat", NIL, SW_SHOWNORMAL);
НЕ РАБОТАЕТ.

странно очень, но если скопировать файл в папку программы самостоятельно и пропустить (КОД1), то (КОД2) выполняется нормально, в чем беда?


 
umbra ©   (2007-02-08 11:33) [4]

приводите строку к PChar прямо в вызове ShellExecute, а не раньше.

var
 params: string;
{..............}
ShellExecute(Handle,"open","l2endec.exe",PChar(params), NIL, SW_SHOWNORMAL);


 
TRUNK ©   (2007-02-08 11:43) [5]

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

procedure TForm1.BDecryptClick(Sender: TObject);
begin
ShellExecute(Handle,"open","l2endec.exe", Pchar(Edit1.Text), NIL, SW_SHOWNORMAL);//запуск приложения l2endec
end;

или на крайний случай так:

procedure TForm1.BDecryptClick(Sender: TObject);
var
Param: PChar;
begin
GetMem(Param,Length(Edit1.Text)+1); // под строку PChar надо сначала выделить память
StrCopy(Param,PChar(Edit1.Text)) ;
ShellExecute(Handle,"open","l2endec.exe", Param, NIL, SW_SHOWNORMAL);//запуск приложения l2endec
FreeMem(Param);
end;


 
UrbanRider   (2007-02-08 13:12) [6]

Ребят, не помогло :(

вот полностью код программы(уже немного модифицирован):


unit main;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, XPMan, StdCtrls, AeroGlass, shellapi;

type
 TForm1 = class(TForm)
   BOpenFile: TButton;
   BDecrypt: TButton;
   BToTXT: TButton;
   BEncrypt: TButton;
   XPManifest1: TXPManifest;
   OpenDialog1: TOpenDialog;
   BEdit: TButton;
   Edit1: TEdit;
   procedure BToTXTClick(Sender: TObject);
   procedure BDecryptClick(Sender: TObject);
   procedure BOpenFileClick(Sender: TObject);
 private
   { Private declarations }
 public
   FName: string; //сделал переменные общедоступными
   AppDir: String;
   FName2: String;
   EFName2: String;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BOpenFileClick(Sender: TObject);
begin
OpenDialog1.Execute;
AppDir:=ExtractFilePath(Application.ExeName);//переменным задается нужный вид
FName:=OpenDialog1.FileName;
EFName2:=ExtractFileName(OpenDialog1.FileName);
FName2:=AppDir+""+EFName2;
Edit1.Text:="";
Edit1.Text :="-l "+EFName2;//задается строка параметров
CopyFile(Pchar(FName),Pchar(FName2),false);//копируется файл в папку с программой
end;

procedure TForm1.BDecryptClick(Sender: TObject);
begin
ShellExecute(Handle,"open","l2endec.exe",Pchar(Edit1.Text), NIL, SW_SHOWNORMAL);//ну собственно вызов сторонней программы.
end;
end.


Суть не в том, что что-то неправильно я подставил в ShellExecute, так как если
не вызывать TForm1.BOpenFileClick, а написать параметры вручную в Edit1 и запустить TForm1.BDecryptClick, то все работает.

Такое чувство, что после копирования файла ShellExecute колбасить начинает.

Может после функции копирования файла что-то нужно дописать(высвободить память например?)


 
Elen ©   (2007-02-08 13:15) [7]


> UrbanRider  

А что WinExec не устраивает?


 
UrbanRider   (2007-02-08 13:19) [8]

Щас погляжу... я даже не знал о ее существовании.


 
TRUNK ©   (2007-02-08 13:25) [9]


> Elen ©   (08.02.07 13:15) [7]
> А что WinExec не устраивает?

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


 
UrbanRider   (2007-02-08 13:46) [10]

тоже самое: если не вызывать обработку где копируются файлы, задаются переменные, а вписать параметры в Edit вручную, а потом запустить
WinExec(PChar("l2endec.exe "+Edit1.Text), SW_ShowNormal);
то все работает, а если делать так как нужно, то вроде консольное окно сторонней программы открывается, однако результат не появляется.

Проблема остается открытой....


 
UrbanRider   (2007-02-08 13:47) [11]

2TRUNK щас и твой вариант попробую.


 
Elen ©   (2007-02-08 13:49) [12]


> то все работает

Ну так и работай с WinExec . кстати кроме open в Shellexecute можно еще и explore попробовать. Ну и CreateProcess, имхо :)


 
UrbanRider   (2007-02-08 14:12) [13]

с CreateProcess не удалось разобраться параметров куча, не смог написать строку нормально, чтоб Delphi ее скомпилировал.


> Ну так и работай с WinExec

Объясню еще раз:

Это код №1:

procedure TForm1.BOpenFileClick(Sender: TObject);
begin
OpenDialog1.Execute;
AppDir:=ExtractFilePath(Application.ExeName);//переменным задается нужный вид
FName:=OpenDialog1.FileName;
EFName2:=ExtractFileName(OpenDialog1.FileName);
FName2:=AppDir+""+EFName2;
Edit1.Text:="";
Edit1.Text :="-l "+EFName2;//задается строка параметров
CopyFile(Pchar(FName),Pchar(FName2),false);//копируется файл в папку с программой
end;


Он обрабатывает выбранный в OpenDialog1 файл и копирует его в папку с программой и задает параметры для запуска стороннего приложения в зависимости от имени выбранного файла.(заносит их в Edit1)

Это Код №2:

procedure TForm1.BDecryptClick(Sender: TObject);
begin
WinExec(PChar("l2endec.exe "+Edit1.Text), SW_ShowNormal);
end;


Этот код запускает стороннюю программу с параметрами, содержащимися в Edit1, но есть один нюанс:

Код №2 не корректно работает, если был запущен Код №1.

И для нормальной работы приходиться Код №1 выполнять в ручную(копировать файл в папку с приложением, вручную писать параметры в Edit1).

Если все сделать руками, то Код №2 запускается и работает как надо.

Но для меня это неприемлемо, не буду же я пользователя заставлять руками копировать файл в папку программы и писать параметры запуска декодировщика.

Вопрос на данный момент: почему после исполнения Кода №1, Код №2 некорректно работает?


 
sergeyst ©   (2007-02-08 14:24) [14]


> UrbanRider   (08.02.07 14:12) [13]


> FName2:=AppDir+""+EFName2;

А зачем тут "" ?


 
UrbanRider   (2007-02-08 15:16) [15]

можно и убрать роли не играет вообще, просто я туда раньше дописывал поддиректорию... это не существенно...


 
clickmaker ©   (2007-02-08 15:23) [16]


> почему после исполнения Кода №1, Код №2 некорректно работает?

может потому что OpenDialog меняет текущую папку, в коде №2 только имя без пути?


 
UrbanRider   (2007-02-08 15:25) [17]

Мастера, неужели я как-то не так задаю вопрос?
вы скажите что именно вам не ясно в данной ситуации, я попытаюсь ее описать лучше.

Вопросом остается одно: почему если все делать вручную WinExec работает нормально, а если теже действия выполняются программно, и потом попытаться запустить Winexec, то запускаемое приложение работает некорректно(не записывает результат работы в файл).


 
ASoft   (2007-02-08 15:45) [18]


> UrbanRider   (08.02.07 15:25) [17]

Как я понял, в Edit1 у тебя параметры, а в sellexecute запуск консольной чужой проги с параметрами Edit1..
Проверь, имеются ли пути с пробелами или русскими символами, заключи в двойные кавычки, если что.. Ну, я вообще-то не знаю цели выполнения l2endec.exe, но что-то мне подсказывает, что CreateProcess подошел лучше в твоем случае..


 
UrbanRider   (2007-02-08 17:30) [19]

Вот вся система проекта:

проект предназначается для расшифровки *.dat файла игры LineAge2

вот как это должно происходить
на форме 2 кнопке и спрятанный Edit(Visible:=False),
при нажатии на 1ю кнопку открывается диалог открытия файла, после выбора файла в диалоговом окне он копируется в папку с приложением,
и в Edit1 записываются параметры расшифровки, которые передаются позднее в l2endec.

procedure TForm1.BOpenFileClick(Sender: TObject);
begin
OpenDialog1.Execute;
AppDir:=ExtractFilePath(Application.ExeName);//переменным задается нужный вид
FName:=OpenDialog1.FileName;
EFName2:=ExtractFileName(OpenDialog1.FileName);
FName2:=AppDir+""+EFName2;
Edit1.Text:="";
Edit1.Text :="-l "+EFName2;//задается строка параметров
CopyFile(Pchar(FName),Pchar(FName2),false);//копируется файл в папку с программой
end;


при нажатии на 2ю кнопку(Декодировать) вызывается консольное приложение l2endec.exe -l <filename>

procedure TForm1.BDecryptClick(Sender: TObject);
begin
WinExec(PChar("l2endec.exe "+Edit1.Text), SW_ShowNormal);
end;


для откладки я сейчас поставил Edit1.Visible:=True;

система вся в том что после нажатия на 1ю кнопку, действия 1й кнопки выполняются на УРА. Однако если нажать на 2ю кнопку, то l2endec.exe работает неверно, хотя параметры в Edit1 сформированы верно.

Еслиже действия 1й кнопки сделать самостоятельно, а потом нажать 2ю кнопку, то все действия 2й кнопки выполняются на ура(l2endec.exe запускается с теми же параметрами, однако появляется результат ее действия, т.е. появляется декодированный файл, чего не происходит в 1м случае)

что делать?


 
ASoft   (2007-02-08 18:59) [20]

Файл действительно копируется при CopyFile()?
Проверь пошагово, какие значения принимают все переменные до Edit1.text:=


 
TRUNK ©   (2007-02-08 19:48) [21]


> после выбора файла в диалоговом окне он копируется в папку
> с приложением

С каким приложением ? Твоим или l2endec.exe ?


 
UrbanRider   (2007-02-09 01:07) [22]

2ASoft: копируется я слежу за этим в папке он появляется... с переменными все ок, я выводил их в Showmessage

2TRUNK: l2endec лежит в папке с моим приложением, сюда же и копируется *.dat файл


 
Германн ©   (2007-02-09 01:19) [23]


>
> система вся в том что после нажатия на 1ю кнопку, действия
> 1й кнопки выполняются на УРА. Однако если нажать на 2ю кнопку,
>  то l2endec.exe работает неверно, хотя параметры в Edit1
> сформированы верно.
>
> Еслиже действия 1й кнопки сделать самостоятельно, а потом
> нажать 2ю кнопку, то все действия 2й кнопки выполняются
> на ура(l2endec.exe запускается с теми же параметрами, однако
> появляется результат ее действия, т.е. появляется декодированный
> файл, чего не происходит в 1м случае)
>
> что делать?
>


Читать ответы думая при этом головой. Тебе же уже сказали всё

> clickmaker ©   (08.02.07 15:23) [16]
>
> > почему после исполнения Кода №1, Код №2 некорректно работает?
>
> может потому что OpenDialog меняет текущую папку, в коде
> №2 только имя без пути?


 
GrayFace ©   (2007-02-09 01:45) [24]

И папку для программы ты не задаешь.

Вместо "open" обычно лучше указывать nil. "open" - не всегда действие по умолчанию.


 
UrbanRider   (2007-02-09 15:05) [25]

2GrayFace: AppDir:=ExtractFilePath(Application.ExeName); //это разве не строка где  я задаю в переменной папку своего приложения?


 
UrbanRider   (2007-02-09 15:13) [26]

FName2:=AppDir+""+EFName2; - имя с путем как видно, а вот в коде 2 я действительно к l2endec задаю имя без пути и скорее всего в этом ошибка...

спасибо за мысль Герман.

Встречный вопрос: что лучше сделать папку приложения текущей(как?) или просто в вызов стороннего приложения, добавить путь к  l2endec.exe?


 
UrbanRider   (2007-02-09 15:26) [27]

ах да, я вот задумался о путях...

если пользователь установит программу далеко от корня диска, и будут встречаться русские символы в именах папок будет ли ошибка?

Если да то нужно преобразовать путь в короткий, типа D:\Progra~1\...

как этого добится?


 
Германн ©   (2007-02-09 15:33) [28]

Лучше добавить путь к l2endec.exe, и взять всё в кавычки.


 
UrbanRider   (2007-02-09 15:36) [29]

Герман когда я все беру в "кавычки" двойные мой делфи 9 начинает ругатся и не дает компилировать проект... может я не так делаю?

покажи как реализовать это на примере проекта...

у меня ведь путь к файлу строится из нескольких частей.

1 переменная путь
2 имя файла


 
UrbanRider   (2007-02-09 15:50) [30]

вот как сделал я:

Edit1.Text :="-l ""+FName2+""";

WinExec(PChar("""+ExtractFilePath(Application.ExeName)+"l2endec.exe" "+Edit1.Text), SW_ShowNormal);


 
Германн ©   (2007-02-09 15:50) [31]

Типа так
ShellExecute(Handle,"open",""путь"+"имя файла"",Pchar(Edit1.Text), NIL, SW_SHOWNORMAL);


 
UrbanRider   (2007-02-09 15:51) [32]

при таком раскладе запускается вроде нормально, l2endec запускается, а работу не делает :(


 
Германн ©   (2007-02-09 16:01) [33]

PChar() забыл :(
ShellExecute(Handle,"open",PChar(""путь"+"имя файла""),Pchar(Edit1.Text), NIL, SW_SHOWNORMAL);


 
UrbanRider   (2007-02-09 21:13) [34]

блин всеравно не работает... бю :(

че я такой невезучий... как всякие шутки да чаты писать, так гений, а как поставленную задачу для себя решить нормальную, так ппц :(


 
UrbanRider   (2007-02-09 21:20) [35]

вот кстати как у меня получилось:

ShellExecute(Handle,"open",PChar("""+AppDir+"l2endec.exe""),Pchar(Edit1.Text), NIL, SW_SHOWNORMAL);


 
UrbanRider   (2007-02-09 22:54) [36]

Ладно ребят я решил проблемы подругому...

получаю параметры и пишу бат файл, после чего запускаю его и все...

обратно кодирую также...

хотелось конечно все культурнее сделать, однако придется так...

хотя юзеру какая разница как, лишь работало нормально, нетакли?


 
Германн ©   (2007-02-10 00:52) [37]

2 UrbanRider   (09.02.07 22:54) [36]
Как тебя понимать, Саид?
То ты пишешь
> UrbanRider   (09.02.07 21:20) [35]
>
> вот кстати как у меня получилось:
>
> ShellExecute(Handle,"open",PChar("""+AppDir+"l2endec.exe""),
> Pchar(Edit1.Text), NIL, SW_SHOWNORMAL);

То
> UrbanRider   (09.02.07 22:54) [36]
> Ладно ребят я решил проблемы подругому...
>
> получаю параметры и пишу бат файл, после чего запускаю его
> и все...

Так что же всё-таки получилось, а что нет?
Через ShellExecute всё должно нормально работать.


 
UrbanRider   (2007-02-10 01:16) [38]

нет напрямую l2endec Через ShellExecute не работает.

я немного кода добавил.

теперь создаю бат файл, который запускает l2endec.exe, хотя он тоже тупо сначала работал...

попозже попробую адреса править этой функцией, мож тогда Через ShellExecute заработает.


function sfn(const LongName: String): String;
var i :Integer;
begin
 SetLength(Result,Length(LongName));
 i := GetShortPathName(pChar(LongName),pChar(Result),Length(Result));
 if  i > Length(Result)  then begin
   SetLength(Result,i);
   i := GetShortPathName(pChar(LongName),pChar(Result),Length(Result));
 end;
 SetLength(Result,i);
end;


У меня еще вопрос. Из-за него не хочу новую тему поднимать...

вот код для переименовывания файла:

procedure TForm1.BPreToTxtClick(Sender: TObject);
var
  oldName, newName : string;
begin
  oldName := sfn(AppDir)+"dec-"+EFName2;
  newName := sfn(FName2);
  if RenameFile(oldName, newName)
  then ShowMessage(oldName+" renamed OK")
  else ShowMessage(oldName+" rename failed with error : "+ IntToStr(GetLastError));


GetLastError в сообщении дает код ошибки 3... в дурацкой помощи Borland® Developer Studio 2005 есть всякой дребедятины, а кодов ошибок че-то нет :(


 
GrayFace ©   (2007-02-10 08:14) [39]

UrbanRider   (09.02.07 15:05) [25]
2GrayFace: AppDir:=ExtractFilePath(Application.ExeName); //это разве не строка где  я задаю в переменной папку своего приложения?

Я о параметре lpDirectory у ShellExecute.

UrbanRider   (10.02.07 1:16) [38]
А потому и нет, что не нужны. Напиши
Win32Check(RenameFile(oldName, newName));
или
if not RenameFile(oldName, newName) then  RaiseLastOSError;


 
UrbanRider   (2007-02-10 14:49) [40]

благодарю вас всех, с этим всем разобрался...

чувствую скоро проблемы с UNICODE<>ANSI будут :)



Страницы: 1 2 вся ветка

Текущий архив: 2007.03.04;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.05 c
4-1161152894
mxc
2006-10-18 10:28
2007.03.04
как генерировать GUID


1-1168789959
TStas
2007-01-14 18:52
2007.03.04
Как получить список возможных значений Size для шрифта FontName?


15-1168802470
Moholith
2007-01-14 22:21
2007.03.04
Клиент - Сервер; Запрос - Ответ;


11-1150290707
AndreyRus
2006-06-14 17:11
2007.03.04
PopUpMenu.Enabled:= false; // Bug!


15-1170615438
DrPass
2007-02-04 21:57
2007.03.04
Илья Кормильцев умер :(