Текущий архив: 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