13

次を使用して、関連するアプリケーションでファイルを開くVB6アプリケーションがあります。

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

これは完全に機能します。

現在、上記のコマンドを使用して PDF ファイルを開くことができない (Adobe Reader で XP を実行している) 顧客がいます。しかし、Windows エクスプローラーからダブルクリックすると、同じファイルが問題なく開かれています。また、この種の問題を排除するために、自分のマシンでファイル名とパスの組み合わせをテストしました。

機能していることを確認するために確認できることについてのヒントを探してShellExecuteいます。または、ShellExecute がこのように失敗する原因は何ですか?

4

13 に答える 13

10

ShellExecuteの戻り値は何ですか?それが0x0000001f(== 31、意味SE_ERR_NOASSOC)の場合、shellapi.hによると「指定されたファイル名拡張子に関連付けられたアプリケーションはありません。」、これは、どういうわけか.pdfファイル拡張子の登録が失われたことを意味します。AdobeReaderを再インストールすると役立つ場合があります。

于 2009-07-28T13:02:51.463 に答える
10

Thomas's answerに加えて、 ShellExecuteの可能な戻り値のいくつかの VB6 定数と、考えられる説明を示します (もともとこれらは 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. '
于 2009-07-28T13:10:47.940 に答える
5

動詞として「開く」がありますが、そうしないでください。動詞として vbNullString を使用してください (「開く」は開く動詞を意味し、NULL はデフォルトの動詞を意味します (ユーザーが特定のデフォルトを設定していない場合、デフォルトは開く、そのファイルタイプの open 動詞がない場合、ShellExecute は最初に見つかった動詞を使用します))

于 2009-07-28T14:03:18.750 に答える
3

ShellExecuteを使用してPDFファイルを「実行」する代わりに、FindExecutableAPIを使用します。

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
于 2009-07-30T20:07:37.343 に答える
3

ShellExecute呼び出しの戻り値を見てください。MSDNから:

関数が成功すると、32 より大きい値が返されます。関数が失敗すると、失敗の原因を示すエラー値が返されます。戻り値は、16 ビット Windows アプリケーションとの下位互換性のために HINSTANCE としてキャストされます。ただし、これは真の HINSTANCE ではありません。int にのみキャストでき、32 または以下のエラー コードと比較できます。

0: オペレーティング システムのメモリまたはリソースが不足しています。

ERROR_FILE_NOT_FOUND: 指定されたファイルが見つかりませんでした。

ERROR_PATH_NOT_FOUND: 指定されたパスが見つかりませんでした

(...)

于 2009-07-28T13:09:48.610 に答える
2

使用している場合

CoInitializeEx(NULL, COINIT_MULTITHREADED)

コードで、ShellExecuteを介して実行するための別のスレッドを作成する必要があります。詳細はこちら:マルチスレッドアパートメントからのシェル関数とインターフェイスの呼び出し

于 2010-02-19T12:46:20.037 に答える
1

W7x64 から W10 パブリック リリースに更新した後、コンパイルされた Visual Foxpro 9 アプリケーション内で OP と同じ問題が発生しました。

Adobe Acrobat と Adob​​e Reader がインストールされています。デフォルトの .pdf 関連付けを Reader から Acrobat に変更すると... すべてうまくいきます。元のエラー (エラー コード 31 - 「指定されたファイル名拡張子に関連付けられたアプリケーションはありません。」) を使用して Reader に戻します。私を打ちのめしますが、幸いなことに心配する必要はありません。私は年を取りすぎているため、すべてのサイトで W7 を使用する必要があります。

どちらの関連​​付けもファイル エクスプローラーから機能します

于 2015-09-02T21:04:46.390 に答える
1

私は同じ問題を抱えており、VB6 コードを変更することはできませんでした。だから私は別の解決策を見つけなければなりませんでした...

私の場合は「.xyz」という拡張子のファイルでしたが、実際には .doc ファイルのような Microsoft Word 用のファイルでした。

初めてダブルクリックすると、Windows はファイルを開くプログラムを要求します。その後、ダブルクリックは正常に機能しました。しかし、ShellExecute はそうではありませんでした。問題は、ShellExecute がファイルに対して "右クリック" -> "開く" を実行し、.xyz ファイルのコンテキスト メニューに "開く" が存在しないことです。「編集」だけがありました...したがって、ShellExecuteは「編集」で機能しましたが、2番目のパラメーターとして「開く」では機能しませんでした。

VB6 コードを変更できなかったので、regedit でレジストリを開きました。パス "HKEY_CLASSES_ROOT\.doc" では、標準値は "Word.Document.8" であり、"HKEY_CLASSES_ROOT\.xyz" では "xyz_auto_file" だけでした。したがって、この値だけを「Word.Document.8」に変更すると、すべてが完全に機能しました。.xyz ファイルを右クリックすると、.doc ファイルと同じコンテキスト メニューが表示されるようになりました。

また、ShellExecute は完全に機能します...

于 2014-09-10T11:48:33.463 に答える
1
  1. Acrobat Reader をアンインストールして再インストールします。
  2. 「Documents and Settings」の下で、「username」フォルダーの名前を「usernamex」に変更します (別の管理者ユーザーでログインする必要があります)。
  3. ユーザーとして再ログインすると、新しいユーザー レジストリを持つ新しい「username」フォルダーが作成されます。
  4. これで動作するはずです。

usernamex フォルダーから新しいユーザー名フォルダー (デスクトップ、ドキュメントなど) にファイルをコピーできます。

于 2009-11-25T07:56:02.400 に答える
1

Inno Setupの最近のバージョンで経験した、ANSII のみをサポートするコマンドから Unicode バージョン (ShellExecuteW) を呼び出す。ShellExecuteW は一部の ANSII 文字列引数に対して機能しましたが、この場合は必須の引数ではなく、2 を返しました (以下を参照)。
興味深いことに、ANSII または Unicode のいずれかで、Inno の内部関数ShellExecもコード 5 で失敗しました。これは、コンパイル プロセスがまだファイルへのオープン ハンドルを持っているためです。

于 2017-06-26T17:50:25.510 に答える
0

これは、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
于 2009-11-25T13:18:33.683 に答える
-1

これを試して。PDF ファイルを読み取るには、PDF ファイルを任意のプログラム (Acrobat x など) に関連付ける必要があります。その後、ShellExecute で PDF ファイルを開くことができます。

于 2012-05-10T14:24:21.437 に答える