Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Проблема с связкой GetPathName() и ShellExecute()


Автор: RaP1D 13.10.2008, 20:13
Пишу оболочку для кодировщика, по принципу запуска консольного приложения с параметрами:

Смысл в следующем:
1) Нажимаем кнопку Обзор и указываем файл:
Код

void CMainDlg::OnButton1Clicked() //Обзор
{
    CFileDialog fileDialog(TRUE,NULL,_T("*.*"),NULL,_T("Все файлы (*.*)|*.*|"));
    if(fileDialog.DoModal() == IDOK)
    {
        //m_edit1 - название контрола формы
        m_edit1.SetWindowText(fileDialog.GetPathName());
    }
}

2) Нажимаем кнопку Старт:
Код

void CMainDlg::OnButton2Clicked() //Старт
{
    ParadoxStart();
}

void CMainDlg::ParadoxStart()
{
    m_edit1.GetWindowText(fileName); //Записать путь к файлу в переменную
    fileName += " out.txt -s 3"; //приписать параметры

    //fileName - является списком параметров
    //paradox.exe - название кодировщика
    ShellExecute(NULL, _T("open"), _T("paradox.exe"), fileName, NULL, SW_SHOWNORMAL);
}


Другими словами: сначала указываем файл, этот файл записывается в текстовую форму, затем данные из текстовой формы записываются в переменную fileName и к ним добавляются параметры, затем происходит запуск paradox.exe, при этом fileName - параметры запуска для него.

Почему-то ShellExecute отказывается вообще запускать paradox.exe с параметрами fileName.
Странно, ведь fileName имеет тип CString и fileDialog.GetPathName() тоже возращает CString.

Если же делать вызов так:
Код

ShellExecute(NULL, _T("open"), _T("paradox.exe"), _T("D:\in.txt out.txt -s 3)", NULL, SW_SHOWNORMAL);

Все ПУЧКОМ!!!

Если делать так:
Код

CString aaa;
aaa = _T("D:\in.txt out.txt -s 3)";
ShellExecute(NULL, _T("open"), _T("paradox.exe"), aaa, NULL, SW_SHOWNORMAL);

Тоже работает на УРА!!!

Проходил дебаггером, вроде в fileName вписывается тоже самое, что и в aaa. Но не пашет!

Также я пробывал без вывода в текстовое поле, т.е.:

Код

fileName = fileDialog.GetPathName();
fileName += " out.txt -s 3"; //приписать параметры
ShellExecute(NULL, _T("open"), _T("paradox.exe"), fileName, NULL, SW_SHOWNORMAL);


Но не пашет! Я думаю ошибка именно в fileDialog.GetPathName()... Как её решить???

А и еще, если fileName использовать не для параметров, я для имени файла (вместо _T("paradox.exe")), то все ОК!!!

Автор: RaP1D 13.10.2008, 20:57
Теперь я уверен, что ошибка в fileDialog.GetPathName()

Пробовал запускать так:

Код

SHELLEXECUTEINFO info;
info.fMask = SEE_MASK_NOCLOSEPROCESS;
info.hwnd = NULL;
info.lpVerb = _T("open");
info.lpFile = _T("paradox.exe");
info.lpParameters = fileName;
info.lpDirectory = NULL;
info.nShow = SW_SHOWNORMAL;
HINSTANCE__ hnd;
info.hInstApp = &hnd;
info.cbSize = sizeof(info);

ShellExecuteEx(&info);


Так, если параметры вписать вручную, то все ОК.
Если кнопкой Обзор, т при Старте пишет, что файл paradox.exe не найден...
Это как?

Можно ли заменить
CFileDialog fileDialog(TRUE,NULL,_T("*.*"),NULL,_T("Все файлы (*.*)|*.*|"));
на что то другое, чтобы пахало?

Автор: Rickert 14.10.2008, 03:39
RaP1D
Есть такой параметр, как текущая рабочая папка. В ParadoxStart, перед ShellExecute, вставьте код:
Код
const DWORD bufLen = 2048;
wchar_t buf[bufLen] = {0};

GetCurrentDirectory(bufLen, buf);

И посмотрите, соответствует ли указанный путь папке, где лежит "paradox.exe"?

Добавлено через 1 минуту и 25 секунд
И прошу вас, занесите весь код в тэги, чтобы удобно было читать.

Автор: RaP1D 14.10.2008, 08:47
Хоть убей, не работает! Вот кусок кода:

Код

const DWORD bufLen = 2048;
wchar_t buf[bufLen] = {0};
GetCurrentDirectory(bufLen, buf);
AfxMessageBox(buf);

m_edit1.GetWindowText(fileName); //Записать путь к файлу в переменную
fileName += " out.txt -s 3";

//ShellExecute(NULL, _T("open"), _T("paradox.exe"), fileName, buf, SW_SHOWNORMAL);

SHELLEXECUTEINFO info;
info.fMask = SEE_MASK_NOCLOSEPROCESS;
info.hwnd = NULL;
info.lpVerb = _T("open");
info.lpFile = _T("paradox.exe");
info.lpParameters = fileName;
info.lpDirectory = buf;
info.nShow = SW_SHOWNORMAL;
HINSTANCE__ hnd;
info.hInstApp = &hnd;
info.cbSize = sizeof(info);

ShellExecuteEx(&info);


Если без кнопки Обзор, то все ОК, если же нажать кнопку Обзор, а затем Старт (параметры из текстового поля заносятся в fileName), то paradox.exe не найден!!! Проверял дебагом, в buf лежит нужный путь, но paradox.exe он не видит (и где он его только ищет?)!!!

Автор: RaP1D 14.10.2008, 09:23
Ура нашел проблему!!!

При использовании CFileDialog fileDialog(TRUE,NULL,_T("*.*"),NULL,_T("Все файлы (*.*)|*.*|")) слетает текущая папка на ту, которую указываешь там...

Т.е. в buf помещается левая папка... Следовательно туда нужно занести переменную до того, как нажата кнопка Обзор.

Вопрос: как заполнить buf в OnInit, чтобы переменная была доступной в другой функции? 

Автор: Rickert 14.10.2008, 09:41
Обычно, при инициализации приложения, куда-нибудь записывается рабочая папка, и потом, при необходимости, используется для SetCurrentDirectory.

Автор: RaP1D 14.10.2008, 16:18
Все! Получилось! Работает!

Другой вопрос:
Как остановить выполнение функции? Допустим посреди ф-ции есть if и если он не выполняется функция останавливается (вырубается)...

Автор: Rickert 14.10.2008, 16:56
RaP1D
Код
void func()
{
...
  if (<expression>)
  {...}
  else
    return;
...
}

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