Как узнать, есть ли на клиентском ПК программа для чтения PDF - PullRequest
0 голосов
/ 12 февраля 2010

Мне нужно знать, есть ли способ обнаружения на клиентском ПК (Windows) какого-либо устройства для чтения PDF (Adobe Reader, Foxit Reader, ...), используя VB6 и. NET (C #).

Я не могу это сделать, прочитав реестр Windows, поскольку у пользователя может не быть прав на его чтение.

Спасибо.

Ответы [ 4 ]

2 голосов
/ 12 февраля 2010

Образец, основанный на предложении Джерри Коффина использовать FindExecutable (на основе этой статьи ):

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

Private Declare Function lstrlen Lib "kernel32.dll" _
  Alias "lstrlenA" ( _
  ByVal lpString As Any) As Long

' FindExecutable Constants
Private Const ERROR_FILE_NOT_FOUND = 2&
Private Const ERROR_PATH_NOT_FOUND = 3&
Private Const ERROR_BAD_FORMAT = 11&

Private Sub Command1_Click()
  Dim Retval As Long, buffer As String

  ' init buffer 
  buffer = Space(256)

  Retval = FindExecutable("c:\windows\media\tada.wav", "", buffer)

  Select Case Retval
    Case 0
      Debug.Print "Not enough memory to execute this method." 
    Case 31
      Debug.Print "No file association found."
    Case ERROR_FILE_NOT_FOUND
      Debug.Print "File not found."
    Case ERROR_PATH_NOT_FOUND
      Debug.Print "Path not found."
    Case ERROR_BAD_FORMAT
      Debug.Print "The associated application is not a valid Win32 executable."
    Case Else
      Debug.Print "Associated application: " & Left$(buffer, lstrlen(buffer))
  End Select
End Sub
2 голосов
/ 12 февраля 2010

Создайте временный файл с расширением «.pdf», а затем используйте FindExectuable для вашего временного файла. Обратите внимание, что даже если действительно имеет значение только расширение, для FindExecutable все еще требуется настоящий файл, а не просто имя с правильным расширением.

1 голос
/ 12 февраля 2010

Эта подпрограмма VB получит исполняемый файл по умолчанию для расширения файла. Если исполняемого файла нет, то у пользователя нет программы, настроенной для обработки расширения.

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

Function GetAssociation(ByVal Path As String, ByVal FileName As String) As String
   Dim Result As String
   Dim x As Long
   Dim lngLenBuff

   lngLenBuff = 256
   Result = String(lngLenBuff, vbNullChar)
   x = FindExecutable(FileName, Path, Result)
   GetAssociation = Left$(Result, InStr(Result, Chr$(0)) - 1) 'get string to left of the null'
End Function
0 голосов
/ 11 марта 2010

Я знаю, что вопрос был для VB, но нашел достойную реализацию FindExecutable в C # здесь :

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace PaytonByrd {
public class Win32API
{
  [DllImport("shell32.dll", EntryPoint="FindExecutable")] 
  public static extern long FindExecutableA(
    string lpFile, string lpDirectory, StringBuilder lpResult);

  public static string FindExecutable(
    string pv_strFilename)
  {
    StringBuilder objResultBuffer = 
      new StringBuilder(1024);
    long lngResult = 0;

    lngResult = 
      FindExecutableA(pv_strFilename, 
        string.Empty, objResultBuffer);

    if(lngResult >= 32)
    {
        return objResultBuffer.ToString();
    }

    return string.Format(
      "Error: ({0})", lngResult);
  }
}}

Вот пример использования:

using System;
using System.Diagnostics;
using System.IO;
using PaytonByrd;

namespace CSharpFindExecutableTester
{
  class Class1
  {
    [STAThread]
    static void Main(string[] args)
    {
      foreach(string strFile in 
        Directory.GetFiles("c:\\"))
      {
        string strOutput = 
          string.Format(
            "{0} - Application: {1}",
            strFile, 
            Win32API.FindExecutable(
              strFile));

        Debug.WriteLine(strOutput);
      }
    }
  }
}
...