代码之家  ›  专栏  ›  技术社区  ›  MicSim

哪些原因会导致shellexecute失败?

  •  12
  • MicSim  · 技术社区  · 16 年前

    我有一个vb6应用程序,它使用以下方式打开与其关联的应用程序的文件:

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

    这很管用。

    现在我有一个客户(使用Adobe Reader运行XP)无法使用上述命令打开任何PDF文件。但是,当从Windows资源管理器双击同一文件时,它将毫无问题地被打开。我还在我的机器上测试了文件名/路径组合,以排除这些问题。

    我正在寻找我能查到的任何线索以确保 ShellExecute 正在工作。或者什么会导致shellexecute以这种方式失败?

    13 回复  |  直到 8 年前
        1
  •  9
  •   Thomas Freudenberg    9 年前

    ShellExecute的返回值是多少?如果是0x0000001F(=31,意思是 SE_ERR_NOASSOC 根据Shellapi.h “没有与关联的应用程序 给定的文件扩展名。“ 这意味着.pdf文件扩展名的注册不知何故丢失了。重新安装Adobe Reader可能会有所帮助。

        2
  •  9
  •   Community CDub    8 年前

    到托马斯家 answer ,这里是一些vb6常量,用于 ShellExecute 有可能的解释 page ,返回值部分)。返回值小于等于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
  •  4
  •   Anders    16 年前

    您将“open”作为动词,不要这样做,请使用vbNullString作为动词(“open”表示打开的动词,空表示默认的动词(如果用户没有设置特定的默认值,则默认值为open,如果该文件类型没有打开的动词,则ShellExecute使用找到的第一个动词)

        4
  •  3
  •   Treb    16 年前

    看看你的 ShellExecute 打电话。从 MSDN :

    如果函数成功,则返回大于32的值。如果函数失败,则返回一个错误值,该值指示失败的原因。返回值被转换为与16位Windows应用程序向后兼容的提示。然而,这并不是一个真正的暗示。它只能转换为int,并与下面的32或以下错误代码进行比较。

    0:操作系统内存或资源不足。

    ERROR_FILE_NOT_FOUND :找不到指定的文件。

    ERROR_PATH_NOT_FOUND :找不到指定的路径

    (…)

        5
  •  3
  •   C-Pound Guru    16 年前

    我使用findexecutable API,而不是使用shellexecute“执行”PDF文件:

    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
  •  1
  •   Mihaela    15 年前

    如果你在用

    CoInitializeEx(NULL, COINIT_MULTITHREADED)
    

    在代码中,则必须创建一个单独的线程,以便通过 ShellExecute。 在这里看到更多: Calling Shell Functions and Interfaces from a Multithreaded Apartment

        7
  •  1
  •   the Tin Man    12 年前
    1. 卸载并重新安装Acrobat Reader。
    2. 在“文档和设置”下,将“用户名”文件夹重命名为“用户名x”(应使用不同的管理用户登录)。
    3. 以用户身份重新登录,并用新的用户注册表创建一个新的“用户名”文件夹。
    4. 现在应该可以了。

    您可以将文件从usernamex文件夹复制到新的username文件夹(桌面、文档等)。

        8
  •  1
  •   user3256508    11 年前

    我也遇到了同样的问题,无法更改VB6代码。所以我必须找到另一个解决办法…

    在我的例子中,它是一个扩展名为“.xyz”的文件,但实际上它是一个用于Microsoft Word的文件,类似于.doc文件。

    当第一次双击时,Windows要求使用程序打开文件。在那之后,双击工作得很好。但ShellExecute没有。问题是,ShellExecute在文件上执行“右键单击”->“打开”,而在.xyz文件的上下文菜单中不存在“打开”。只有一个“编辑”…所以shellexecute使用“edit”,但不使用“open”作为第二个参数。

    因为我无法更改vb6代码,所以我用regedit打开了注册表。在路径“hkey_classes_root\.doc”中,标准值是“word.document.8”,在“hkey_classes_root\.xyz”中,只有“xyz_auto_file”。所以我把这个值改成了“word.document.8”,一切都很顺利。现在,当我右键单击.xyz文件时,我有了与.doc文件相同的上下文菜单。

    而且ShellExecute也能很好地工作…

        9
  •  1
  •   Martin    10 年前

    我对使用动词的现有程序也有同样的问题 open 而不是 NULL 当呼叫 ShellExecute 功能。我通过添加 打开 类动词 described here 使用注册表编辑器进入 .pdf 处理人(我的在 HKEY_CLASSES_ROOT\pdf_auto_file )我认为这是Adobe Reader安装程序中的一个问题,它有时不添加 打开 安装期间的动作。

    以下是我添加的注册表值的导出:

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

    在从w7x64更新到w10公共版本之后,我在编译的VisualFoxPro 9应用程序中遇到了与op相同的问题。

    我安装了Adobe Acrobat和Adobe Reader。将默认的.pdf关联从reader更改为acrobat,然后…一切正常!改回读卡器时出现原始故障(错误代码31-“没有与给定文件扩展名关联的应用程序。”)。比我强,但幸运的是我不用担心。我太老了,不关心,将要求所有网站留在W7。

    任何关联都可以从文件资源管理器工作

        11
  •  1
  •   Laurie Stearn    8 年前

    从只支持ansii的命令调用unicode版本(shellexecutew),该命令在最新版本的 Inno Setup .ShellExecutew为一些ansii字符串参数工作,但在本例中不是必需的参数,返回2(请参见 below )
    有趣的是,在ansii或unicode中,inno的内部函数 ShellExec 代码5也失败了,因为编译过程对该文件仍有打开的句柄。

        12
  •  0
  •   jac    15 年前

    下面是一个将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
  •  -1
  •   user Roman    13 年前

    试试这个。 您必须将PDF文件与任何程序(如Acrobat X)关联以读取PDF,然后您可以使用ShellExecute打开PDF文件。

    推荐文章