Есть ли способ получить уровень ошибки от FileProtocolHandler или url.dll? - PullRequest
2 голосов
/ 30 июля 2010

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

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

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

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 02 августа 2010

Да, еще до того, как вы написали ваш комментарий, я начал правильно читать документацию, и менее чем через 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 );
}
2 голосов
/ 30 июля 2010

Мне кажется, что rundll32.exe действительно не возвращает уровень ошибки. Если вы посмотрите на 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 с глаголом "open" или NULL (см. http://msdn.microsoft.com/en-us/library/bb776886.aspx). В простейшем случае код может выглядеть следующим образом

HINSTANCE hInst = ShellExecute (NULL, TEXT ("open"), TEXT ("c: \ path \ to \ a.file"), NULL, NULL, 0);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...