Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Вопрос про ShellExecute


Автор: Salatovec 29.9.2010, 19:38
Доброго всем времени суток, имеется такой кусочек кода:

Код

...
AnsiString PathOfProg = ExtractFilePath(Application->ExeName)+"DFILFtr//Prog.exe";
ShellExecute(Handle, "open", PathOfProg.c_str(), NULL, NULL, SW_SHOWNORMAL);
Memo1->LoadFromFile(Test.txt");
...


который запускает на исполнение программу Prog.exe, результатом работы которой является файл Test.txt, который я пытаюсь подгрузить в Мемо. Проблема в следующем: Prog работает достаточно долго, а моя программапытается подгрузить файлик в мемо сразу же после запуска Prog, на что компилятор ругается, что файл занят другой программой. Как сделать так, чтобы программа ждала пока Prog.exe не завершит свою работу? Заранее спасибо!

Автор: smoke_man 29.9.2010, 21:24
Можно попробывать  system().

Автор: Salatovec 30.9.2010, 11:01
smoke_man, уважаемый, а можно поподробнее  smile 

Автор: smoke_man 30.9.2010, 11:28
Описание system http://www.cplusplus.com/reference/clibrary/cstdlib/system/
В твоем случае:
Код

AnsiString PathOfProg = ExtractFilePath(Application->ExeName)+"DFILFtr//Prog.exe";
system(PathOfProg.c_str());
Memo1->LoadFromFile(Test.txt");

Автор: aleks88 10.11.2011, 14:36
Работаю с FibPlus.
Данная строка возвращает данные, записанные в определенном столбце БД FireBird, а данном случае это путь к файлу.

Dataset1->FieldByName("LINKFILE")->AsString;

Путь имеет обычный формат: D:\papka\file.dox (к примеру).
Необходимо открыть этот файл. Подскажите, как передать функции ShellExecute путь до файла, если она восрринимает путь, с двойным слэшэм  ? Каким образом сделать преобразование ? Или есть другой вариант, может другая функция ?

Автор: xvr 10.11.2011, 16:30
Цитата(aleks88 @  10.11.2011,  14:36 Найти цитируемый пост)
Или есть другой вариант,

Есть - передавайте путь как есть. Двойные слеши нужны только при записи символьного литерала, run-time там будут обычные одинарные обратные слэши

Автор: aleks88 11.11.2011, 10:03
Так то работает, попробовал открыть D:/1.txt
Но у меня предполагается, что файлы будут располагаться где то в сети, тога путь будет примерно
\\CMP27\Users\1.txt

В таком же виде они и будут храниться в базе, в текстовом варианте VARCHAR.
Путь до файла возвращается компонентом OpenDialog. Может хранить нужно как по другому ? 
Подскажите как с этим быть ?

Автор: ZVano 11.11.2011, 10:43
Можно просто дождаться завершения запущеного процесса.
Код

UnicodeString runCommand = "c:\\myProg.exe c:\\out.txt";//Формируем строку запуска
PROCESS_INFORMATION processInfo;

STARTUPINFOW startupInfo;
ZeroMemory(&startupInfo, sizeof(STARTUPINFOW)); // обнулить
startupInfo.cb = sizeof(STARTUPINFOW);
GetStartupInfoW(&startupInfo);

CreateProcessW(
  NULL
  , runCommand.w_str()
  , NULL //&securityProcess
  , NULL //&securityThread
  , false //inheritHandles
  , 0 //creationFlags
  , 0 //environment
  , NULL //directory.w_str()
  , &startupInfo
  , &processInfo // << Сюда будет записана информация о запущеном процессе
);

// В цикле ожидаем завершения процесса
while (true){
  DWORD exitCode = 0;
  iGetExitCodeProcess(processInfo.hProcess, &exitCode))
  if(exitCode != STILL_ACTIVE){
    break;
  }
  Application->ProcessMessages();
    Sleep(500);  
}


PS: Если задача состоит в том, чтобы время от времени брать по сети небольшие блоки данных, то лучше воспользоваться mailslots.
Очень удобная штука.

Автор: xvr 11.11.2011, 11:51
Цитата(aleks88 @  11.11.2011,  10:03 Найти цитируемый пост)
Но у меня предполагается, что файлы будут располагаться где то в сети, тога путь будет примерно
\\CMP27\Users\1.txt

Нормальный путь. Должно работать

Автор: aleks88 11.11.2011, 13:19
Не работает, работает только при D:/1.txt и D:\\1.txt :(

Автор: xvr 11.11.2011, 14:54
Цитата(aleks88 @ 11.11.2011,  13:19)
Не работает, работает только при D:/1.txt и D:\\1.txt :(

Должно работать, покажите код.

Автор: aleks88 11.11.2011, 19:08
Работает
Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
ShellExecute(NULL, "open", "D:\\1.txt", NULL, NULL, SW_SHOWNORMAL);
}


Тоже работает
Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
ShellExecute(NULL, "open", "D:/1.txt", NULL, NULL, SW_SHOWNORMAL);
}


предположим, путь \\имя компьютера\папка\1.txt
в каком виде передать его функции ?

Автор: xvr 11.11.2011, 19:40
Цитата(aleks88 @  11.11.2011,  19:08 Найти цитируемый пост)
предположим, путь \\имя компьютера\папка\1.txt

Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
ShellExecute(NULL, "open", "\\\\имя компьютера\\имя шары\\папка\\1.txt", NULL, NULL, SW_SHOWNORMAL);
}

Автор: aleks88 11.11.2011, 20:14
Большое спасибо, я 3 слэша ставил smile
Теперь осталось понять, как передать такой путь в функцию, если в базе он хранится как \\Имя компьютера\папка\1.txt
т.е. как преобразовать строку, добавив слэши...

Автор: xvr 13.11.2011, 10:32
Цитата(aleks88 @  11.11.2011,  20:14 Найти цитируемый пост)
Теперь осталось понять, как передать такой путь в функцию, если в базе он хранится как \\Имя компьютера\папка\1.txt
т.е. как преобразовать строку, добавив слэши... 

Еще раз повторяю - удваивать слэши нужно только когда вы записываете строку в кавычках в исходном тексте программы. Компилятор автоматически удаляет по одному слешу из такой стоки, когда компилирует программу в исполняемый код. Так что в ShellExecute во время исполнения приходит строка \\имя компьютера\имя шары\папка\1.txt
Так что если эта строка извлекается из базы данных, то ничего в ней менять не надо - слэши там такие, какие должны быть

Автор: aleks88 13.11.2011, 11:45
Спасибо.
Но почему вот это не работает ?

Код

AnsiString link1=Form1->Dataset1->FieldByName("LINKFILE")->AsString;
ShowMessage(link1);
ShellExecute(NULL,"open", link1, NULL, NULL,SW_SHOWNORMAL);


Так тоже не хочет :(
Код

const char * link1=Form1->Dataset1->FieldByName("LINKFILE")->AsString.c_str();
ShowMessage(link1);
ShellExecute(NULL,"open", link1, NULL, NULL, SW_SHOWNORMAL);


Подскажите пожалуйста :(

Автор: borisbn 13.11.2011, 13:12
Цитата(aleks88 @  13.11.2011,  11:45 Найти цитируемый пост)
Но почему вот это не работает ?

Цитата(aleks88 @  13.11.2011,  11:45 Найти цитируемый пост)
ShellExecute(NULL,"open", link1, NULL, NULL,SW_SHOWNORMAL);

ShellExecute требует char *, а ты даёшь ему AnsiString

Цитата(aleks88 @  13.11.2011,  11:45 Найти цитируемый пост)
const char * link1=Form1->Dataset1->FieldByName("LINKFILE")->AsString.c_str();

здесь ты запоминаешь указатель на строку временного объекта AsString. После этой строки указатель link1 невалидный (указывает в никуда)

Правильно будет так
Код

AnsiString link1=Form1->Dataset1->FieldByName("LINKFILE")->AsString;
ShellExecute(NULL,"open", link1.c_str(), NULL, NULL,SW_SHOWNORMAL);

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