2010-07-30 1 views
2

В одной из моих программ я использую rundll32.exe url.dll,FileProtocolHandler c:\path\to\a.file, чтобы открыть файлы. Я хотел бы обрабатывать ошибки в случае, если этот файл не может быть открыт, но я не могу понять, как узнать, была ли ошибка или нет. Вот мой код:Есть ли способ получить errorlevel из FileProtocolHandler или url.dll?

QProcess::startDetached(QString("rundll32.exe url.dll,FileProtocolHandler " + p_target_path)); 

startDetached() теперь всегда возвращает истину, потому что это всегда успешным в открытии процесса, содержащего rundll32.exe. Итак, как я могу узнать, может ли мой файл быть найден/открыт или нет?

Я пробовал errorlevel-вещи в * .bat файле для тестирования.

rundll32.exe url.dll,FileProtocolHandler c:\not_existing.exe >nul || echo Could not open file. 

Но нет ничего эха. Я также попытался прочитать% ERRORLEVEL%, но даже если файл не существует, уровень ошибок остается 0.

Кто-нибудь знает способ узнать, как с этим справиться?

ответ

2

Мне кажется, что rundll32.exe действительно не возвращает erorlevel. Вы смотрите на http://support.microsoft.com/kb/164787, вы можете видеть, что интерфейс Rundll32 не имеет определенного способа возврата ошибки.

VOID CALLBACK FileProtocolHandler (
    __in HWND hwnd, 
    __in HINSTANCE ModuleHandle, 
    __in PCTSTR pszCmdLineBuffer, 
    __in INT nCmdShow 
); 

Кстати, вы можете вызвать функцию FileProtocolHandler экспортируемой Url.dll непосредственно без запуска rundll32.exe. Как pszCmdLineBuffer вы можете дать p_target_path. Тем не менее вы не получите никакой информации об ошибке.

ОБНОВЛЕНО: Кстати, если вы используете rundll32.exe url.dll,FileProtocolHandler открывать файлы только и не URL, чем вы можете использовать ShellExecute или ShellExecuteEx вместо с глаголом «открыть» или NULL (см http://msdn.microsoft.com/en-us/library/bb776886.aspx). В простейшем случае код может выглядит следующим образом

HINSTANCE hInst = ShellExecute (NULL, TEXT ("Открыть"), TEXT ("C: \ путь \ к \ a.file"), NULL, NULL, 0);

Вы можете проверить hInst для ошибок (см Возвращаемого значения в http://msdn.microsoft.com/en-us/library/bb762153.aspx)

+0

Thx для вашей помощи это выглядит так, как если бы это могло быть решение ... Но как я могу использовать ShellExecute и значение hInst вместе с startDetached()? И как передать var в третий параметр в ShellExecute? TEXT (p_target_path) не будет работать, потому что макрос добавит L в начале ... – Exa

+0

Я немного отлаживал и тестировал код, который вы опубликовали. При предоставлении c: \ windows \ system32 \ cmd.exe в ShellExecute, hInst - «0x0000002a» ... Но cmd не открывается ... – Exa

+0

Я тестировал другие программы, и они отлично работали, но hInst по-прежнему 0x0000002a. .. – Exa

2

Да, даже прежде, чем Вы написали свой комментарий, я начал читать документацию должным образом и в менее чем за 2 минуты я имел решение:

void main_window::open_test(QString p_target_path) 
{ 
    p_target_path = p_target_path.remove("\""); 

    HINSTANCE res = ShellExecute(NULL, TEXT("open"), (LPCWSTR) p_target_path.utf16(), NULL, NULL, SW_SHOWNORMAL); 

    QString err_str = ""; 

    int res_code = (int) res; 

    switch(res_code) 
    { 
    case 0: 
     err_str = "Your operating system is out of memory or resources."; 
     break; 
    case ERROR_FILE_NOT_FOUND: 
     err_str = "The specified file was not found."; 
     break; 
    case ERROR_PATH_NOT_FOUND: 
     err_str = "The specified path was not found."; 
     break; 
    case ERROR_BAD_FORMAT: 
     err_str = "The .exe file is invalid (non-Win32 .exe or error in .exe image)."; 
     break; 
    case SE_ERR_ACCESSDENIED: 
     err_str = "Your operating system denied access to the specified file."; 
     break; 
    case SE_ERR_ASSOCINCOMPLETE: 
     err_str = "The file name association is incomplete or invalid."; 
     break; 
    case SE_ERR_DDEBUSY: 
     err_str = "The DDE transaction could not be completed because other DDE transactions were being processed."; 
     break; 
    case SE_ERR_DDEFAIL: 
     err_str = "The DDE transaction failed."; 
     break; 
    case SE_ERR_DDETIMEOUT: 
     err_str = "The DDE transaction could not be completed because the request timed out."; 
     break; 
    case SE_ERR_DLLNOTFOUND: 
     err_str = "The specified DLL was not found."; 
     break; 
    case SE_ERR_NOASSOC: 
     err_str = "There is no application associated with the given file name extension.\nThis error will also be returned if you attempt to print a file that is not printable."; 
     break; 
    case SE_ERR_OOM: 
     err_str = "There was not enough memory to complete the operation."; 
     break; 
    case SE_ERR_SHARE: 
     err_str = "A sharing violation occurred."; 
     break; 
    default: 
     return; 
    } 

    QMessageBox::warning(this, "Error", err_str); 
} 
Смежные вопросы