سؤال

لدي تطبيق VB6 الذي يفتح الملفات مع التطبيق المرتبط باستخدام:

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

هذا يعمل تماما.

الآن حصلت على عميل (تشغيل XP باستخدام Adobe Reader) الذي لا يستطيع فتح أي ملف PDF باستخدام الأمر أعلاه. ولكن يتم فتح نفس الملف دون أي مشاكل عند النقر المزدوج فوقه من مستكشف Windows. كما اختبرت مجموعة اسم الملف / -Path على جهازي لاستبعاد هذا النوع من المشاكل.

أنا أبحث عن أي تلميحات على ما يمكن أن تحقق للتأكد ShellExecute يعمل. أو ما الذي يمكن أن يسبب shelllexecute لفشل بهذه الطريقة؟

هل كانت مفيدة؟

المحلول

ما هي قيمة العودة من shelllexecute؟ إذا كان 0x0000001F (== 31، معنى SE_ERR_NOASSOC)، من وفقا ل shellapi.h "لا يوجد تطبيق مرتبط بملحق اسم الملف معين.", ، مما يعني أنه ضائع تسجيل ملحق ملف .pdf. إعادة تثبيت Adobe Reader قد تساعد.

نصائح أخرى

أبعد إلى توماس إجابه, ، إليك بعض الثوابت 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. '

لديك "فتح" كفعل، لا تفعل ذلك، استخدم VBNullstring حيث يعني الفعل ("فتح" الفعل المفتوح، وهو لا معنى له الفعل الافتراضي (إذا لم يقم المستخدم بتعيين افتراضي معين، فستفتح الافتراضي، إذا لم يكن هناك فعل مفتوح لهذا الملف، يستخدم shellExecute الفعل الأول الذي يجده))

إلقاء نظرة على قيمة العودة الخاص بك ShellExecute يتصل. من MSDN.:

إذا نجحت الوظيفة، فإنها ترجع قيمة أكبر من 32. إذا فشلت الوظيفة، فإنها ترجع قيمة خطأ تشير إلى سبب الفشل. يتم وضع قيمة الإرجاع كعناية للتوافق مع تطبيقات Windows ذات 16 بت. انها ليست هينستانس حقيقي. يمكن أن يلقي فقط إلى int ومقارنة مع أي 32 أو رموز الخطأ التالية أدناه.

0: نظام التشغيل خارج الذاكرة أو الموارد.

ERROR_FILE_NOT_FOUND: لم يتم العثور على الملف المحدد.

ERROR_PATH_NOT_FOUND: لم يتم العثور على المسار المحدد

(...)

بدلا من استخدام 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

إذا كنت تستخدم

CoInitializeEx(NULL, COINIT_MULTITHREADED)

في التعليمات البرمجية الخاصة بك، سيتعين عليك إنشاء مؤشر ترابط منفصل لتنفيذه عبر Shelllexecute. رؤية المزيد هنا: استدعاء وظائف شل واجهات من شقة متعددة مراحل

  1. إلغاء تثبيت وإعادة تثبيت قارئ Acrobat.
  2. ضمن "المستندات والإعدادات"، قم بإعادة تسمية "اسم المستخدم" إلى "usernamex" (يجب تسجيل الدخول باستخدام مستخدم مسؤول مختلف).
  3. relogin كمستخدم ويقوم بإنشاء مجلد جديد "اسم المستخدم" مع سجل مستخدم جديد.
  4. الآن يجب أن تعمل.

يمكنك نسخ الملفات من مجلد Usernamex إلى مجلد اسم المستخدم الجديد (سطح المكتب، المستندات، إلخ)

لقد تلقيت نفس المشكلة ولم يكن من الممكن تغيير رمز VB6. لذلك اضطررت إلى إيجاد حل آخر ...

في حالتي، كان ملف تمديد ".xyz"، ولكن في الواقع كان ملف ل Microsoft Word، مثل ملف .doc.

عند doubleclicking لأول مرة، يسأل Windows Programm لفتح الملف به. بعد ذلك عملت Doubleclick بشكل جيد. لكن shelllexecute لم يفعل ذلك. المشكلة هي أن shellExecute ينفذ "انقر بزر الماوس الأيمن" -> "فتح" على الملف، و "فتح" لم يكن موجودا في قائمة السياق على ملف .xyz الخاص بي. كان هناك مجرد "تحرير" ... لذلك عمل shellExecute مع "تحرير"، ولكن ليس مع "فتح" كمعلمة ثانية.

ولأنني لم أتمكن من تغيير رمز VB6، فتحت التسجيل باستخدام Regedit. في المسار "HKEY_CLASSES_ROOT .DOC" كانت القيمة القياسية "Word.Document.8"، في "HKEY_CLASSES_ROOT .XYZ" كان هناك فقط "xyz_auto_file". لذلك قمت بتغيير هذه القيمة فقط إلى "Word.Document.8"، وكل شيء يعمل تماما. الآن لدي نفس قائمة السياق كما هو الحال مع ملف .doc، عندما انقر بزر الماوس الأيمن فوق ملف .xyz الخاص بي.

وأيضا يعمل shellexecute تماما ...

كان لدي نفس المشكلة مع برنامج موجود يستخدم الفعل open بدلاً من NULL عند الاتصال shellexecute. وظيفة. كنت قادرا على حل المشكلة عن طريق إضافة open الفعل مثل الموصوف هنا باستخدام محرر التسجيل في .pdf معالج (كان لي في HKEY_CLASSES_ROOT\pdf_auto_file). أعتقد أن هذه مشكلة داخل برنامج Adobe Reader Installer الذي لا يضيف أحيانا open الفعل أثناء التثبيت.

فيما يلي تصدير قيم التسجيل التي أضفتها:

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

واجهت نفس المشكلة مثل OP ضمن تطبيق Visual FoxPro 9 مرئي مسبقا بعد التحديث من W7X64 إلى إصدار عام W10.

لدي Adobe Acrobat مثبتة بالإضافة إلى Adobe Reader. تغيير جمعية .PDF الافتراضية من القارئ إلى Acrobat ... كل شيء يعمل! تغيير مرة أخرى للقارئ مع الفشل الأصلي (رمز الخطأ 31 - "لا يوجد تطبيق مرتبط بملحق اسم الملف معين."). يدقني، ولكن لحسن الحظ، لا داعي للقلق. أنا أكبر من الرعاية وسأطلب جميع المواقع البقاء مع W7.

أي جمعية تعمل من مستكشف الملفات

استدعاء إصدار Unicode (shellexecutew) من أمر يدعم فقط ANSII، من ذوي الخبرة مع نسخة حديثة من إينو الإعداد. وبعد عمل shellolexecutew لبعض حجج سلسلة ANSII ولكن في هذه الحالة ليست واحدة مطلوبة، والعودة 2 (انظر أقل).
كمسألة مصلحة، في ANSII أو Unicode، وظيفة Inno الداخلية شيلسيك فشل أيضا برمز 5 لسبب ما زالت عملية تجميع مقبض مفتوح للملف.

إليك دالة تترجم أرقام خطأ 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

جرب هذا. يجب عليك ربط ملف PDF بأي برنامج (مثل Acrobat X) لقراءة ملف PDF، ثم يمكنك فتح ملفات PDF باستخدام Shelllexecute.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top