Подтвердить что ты не робот

Какие причины могут привести к отказу ShellExecute?

У меня есть приложение VB6, которое открывает файлы со своим приложением, используя:

ShellExecute(0, "open", filename, params, vbNullString, vbNormalFocus)

Это прекрасно работает.

Теперь у меня есть клиент (работает XP с Adobe Reader), который не может открыть какой-либо файл PDF, используя указанную выше команду. Но тот же файл открывается без проблем при двойном щелчке по нему из проводника Windows. Я также проверил комбинацию filename/-path на моей машине, чтобы исключить эти проблемы.

Я ищу любые подсказки о том, что я могу проверить, чтобы убедиться, что ShellExecute работает. Или что может вызвать отказ ShellExecute таким образом?

4b9b3361

Ответ 1

Какое возвращаемое значение ShellExecute? Если это 0x0000001f (== 31, что означает SE_ERR_NOASSOC), чем согласно shellapi.h "Нет приложения, связанного с данное расширение имени файла. ", что означает, что как-то потеряла регистрацию .pdf файла. Возможно, потребуется переустановка Adobe Reader.

Ответ 2

В дополнение к Thomas answer, здесь некоторые константы VB6 для возможных возвращаемых значений ShellExecute, с возможными объяснениями (я думаю, что я изначально взял их из MSDN страница, поле возвращаемого значения). Возвращаемое значение 32 или менее означает, что вызов завершился неудачно. Возвращаемое значение указывает, что пошло не так.

Const ERROR_BAD_FORMAT = 11&
Const ERROR_FILE_NOT_FOUND = 2&          
Const ERROR_PATH_NOT_FOUND = 3&          ' The specified path was not found. '
Const SE_ERR_ACCESSDENIED = 5            ' The operating system denied access to the specified file. '
Const SE_ERR_ASSOCINCOMPLETE = 27        ' The file name association is incomplete or invalid. '
Const SE_ERR_DDEBUSY = 30                ' The Dynamic Data Exchange (DDE) transaction could not be completed because other DDE transactions were being processed. '
Const SE_ERR_DDEFAIL = 29                ' The DDE transaction failed. '
Const SE_ERR_DDETIMEOUT = 28             ' The DDE transaction could not be completed because the request timed out. '
Const SE_ERR_DLLNOTFOUND = 32            ' The specified dynamic-link library (DLL) was not found. '
Const SE_ERR_FNF = 2                     ' The specified file was not found. '
Const SE_ERR_NOASSOC = 31                ' There is no application associated with the given file name extension. '
Const SE_ERR_OOM = 8                     '  out of memory '
Const SE_ERR_PNF = 3                     '  path not found '
Const SE_ERR_SHARE = 26                  ' A sharing violation occurred. '

Ответ 3

У вас есть "открытый" в качестве глагола, не делайте этого, используйте vbNullString в качестве глагола ( "Открыть" означает открытый глагол, NULL означает глагол по умолчанию (если пользователь не установил конкретный по умолчанию, по умолчанию открыто, если нет открытого глагола для этого типа файлов, ShellExecute использует первый найденный глагол))

Ответ 4

Посмотрите на возвращаемое значение вашего вызова ShellExecute. Из MSDN:

Если функция завершается успешно, она возвращает значение больше 32. Если функция не работает, она возвращает значение ошибки, указывающее причину сбоя. Возвращаемое значение отображается как HINSTANCE для обратной совместимости с 16-разрядными приложениями Windows. Однако это не правда, HINSTANCE. Его можно отличить только от int и сравнить с 32 или следующими кодами ошибок ниже.

0: операционная система не имеет памяти или ресурсов.

ERROR_FILE_NOT_FOUND: указанный файл не найден.

ERROR_PATH_NOT_FOUND: указанный путь не найден

(...)

Ответ 5

Вместо использования ShellExecute для "выполнения" файла PDF я использую API-интерфейс FindExecutable:

Private Const ERROR_FILE_NO_ASSOCIATION     As Long = 31
Private Const ERROR_FILE_NOT_FOUND          As Long = 2
Private Const ERROR_PATH_NOT_FOUND          As Long = 3
Private Const ERROR_FILE_SUCCESS            As Long = 32 
Private Const ERROR_BAD_FORMAT              As Long = 11

Private Declare Function FindExecutable Lib "shell32.dll" _
   Alias "FindExecutableA" _
  (ByVal lpFile As String, _
   ByVal lpDirectory As String, _
   ByVal sResult As String) As Long


Private Sub OpenDocument(sFile as string, sPath as string)
     Dim sResult As String
     Dim lSuccess As Long, lPos as long

     sResult = Space$(MAX_PATH)
     lSuccess = FindExecutable(sFile, sPath), sResult)
     Select Case lSuccess
        Case ERROR_FILE_NO_ASSOCIATION
            If Right$(sFile, 3) = "pdf" Then
                MsgBox "You must have a PDF viewer such as Acrobat Reader to view pdf files."
            Else
                MsgBox "There is no registered program to open the selected file." & vbCrLf & sFile
            End If
        Case ERROR_FILE_NOT_FOUND: MsgBox "File not found: " & sFile
        Case ERROR_PATH_NOT_FOUND: MsgBox "Path not found: " & sPath
        Case ERROR_BAD_FORMAT:     MsgBox "Bad format."
        Case Is >= ERROR_FILE_SUCCESS:
           lPos = InStr(sResult, Chr$(0))
           If lPos Then sResult = Left$(sResult, lPos - 1)
           Shell sResult & " " & sPath & sFile, True), vbMaximizedFocus
    End Select

End Sub

Ответ 6

  • Удалите и переустановите Acrobat Reader.
  • В разделе "Документы и настройки" переименуйте папку "username" в "usernamex" (вы должны войти в систему с другим пользователем администратора).
  • Relogin как пользователь и создает новую папку "имя пользователя" с новым реестром пользователя.
  • Теперь это должно сработать.

Вы можете скопировать файлы из папки usernamex в новую папку имени пользователя (Рабочий стол, Документы и т.д.).

Ответ 8

У меня была та же проблема, и изменить VB6-код было невозможно. Поэтому мне пришлось найти другое решение...

В моем случае это был файл с расширением ".xyz", но на самом деле это был файл для Microsoft Word, такой как .doc файл.

При двойном щелчке в первый раз Windows запрашивает программу для открытия файла. После этого двойной клик работал нормально. Но ShellExecute этого не сделал. Проблема заключается в том, что ShellExecute выполняет "правый щелчок" → "открыть" в файле, а "open" не существует в контекстном меню моего .xyz файла. Было только "редактирование"... Итак, ShellExecute работал с "edit", но не с "open" в качестве второго параметра.

И поскольку я не смог изменить VB6-код, я открыл реестр с помощью regedit. В пути "HKEY_CLASSES_ROOT \.doc" стандартное значение было "Word.Document.8", в "HKEY_CLASSES_ROOT \.xyz" был только "xyz_auto_file". Поэтому я изменил это значение на "Word.Document.8", и все сработало отлично. Теперь у меня такое же контекстное меню, как и с .doc файлом, когда я нажимаю правой кнопкой мыши на мой .xyz файл.

И также ShellExecute отлично работает...

Ответ 9

У меня была такая же проблема с существующей программой, которая использует вместо NULL глагол open при вызове функции ShellExecute. Я смог решить проблему, добавив глагол open, например описанный здесь, используя редактор реестра в обработчик .pdf (мой был у HKEY_CLASSES_ROOT\pdf_auto_file). Я думаю, что это проблема в установщике Adobe Reader, которая иногда не добавляет глагол open во время установки.

Вот экспорт значений реестра, которые я добавил:

[HKEY_CLASSES_ROOT\pdf_auto_file\shell\Open\command]
@="\"C:\\Program Files\\Adobe\\Reader 11.0\\Reader\\AcroRd32.exe\" \"%1\""

Ответ 10

Я столкнулся с той же проблемой, что и OP в скомпилированном приложении Visual Foxpro 9 после обновления с публичного выпуска W7x64 до W10.

У меня установлен Adobe Acrobat, а также Adobe Reader. Изменение связи по умолчанию .pdf от Reader до Acrobat и... Все это работает! Переход к считывателю с оригинальной ошибкой (код ошибки 31 - "Нет приложения, связанного с данным расширением имени файла".). Меня бьет, но, к счастью, мне не нужно беспокоиться. Я слишком стар, чтобы заботиться, и мне потребуются все сайты, чтобы остаться с W7.

Любая ассоциация работает с файловым проводником

Ответ 11

Вызов версии Unicode (ShellExecuteW) из команды, которая поддерживает только ANSII, с новой версией Inno Setup. ShellExecuteW работал для некоторых аргументов строки ANSII, но в этом случае не был необходим, возвращая 2 (см. ниже).
Интересно, что в ANSII или Unicode внутренняя функция Inno ShellExec также не удалась с кодом 5 по той причине, что процесс компиляции все еще был открыт дескриптор файла.

Ответ 12

Здесь функция, которая преобразует номера ошибок Windows в текст. Вы можете использовать возвращаемое значение в качестве параметра и вернуть более дружественное сообщение.

Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" _
    (ByVal dwFlags As Long, lpSource As Long, ByVal dwMessageId As Long, _
    ByVal dwLanguageId As Long, ByVal lpBuffer As String, _
    ByVal nSize As Long, ByVal Arguments As Any) As Long

Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Private Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200
Private Const MAX_PATH = 260

Function TranslateDLLError(ByVal lngErrNum As Long) As String
   Dim sRtrnCode As String * MAX_PATH
   Dim lRet As Long

   On Error GoTo errTranslateDLLError(

   sRtrnCode = Space$(256)
   lRet = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, 0&, lngErrNum, 0&, sRtrnCode, Len(sRtrnCode), 0&)
   If lRet > 0 Then
      Translate_DLL_Error = Replace$(Left(sRtrnCode, lRet), vbCrLf, "")
   Else
      Translate_DLL_Error = "Error not found."
   End If

   Exit Function

errTranslateDLLError(:
   TranslateDLLError( = "Unable to translate system error: " & CStr(lngErrNum)

End Function

Ответ 13

Попробуйте это. Вам необходимо связать файл PDF с любой программой (например, Acrobat x) для чтения PDF файлов, затем вы можете открыть PDF файлы с помощью ShellExecute.