【问题标题】:How to know if there is any PDF reader on the client PC如何知道客户端 PC 上是否有 PDF 阅读器
【发布时间】:2010-02-12 17:55:41
【问题描述】:

我需要知道是否有任何方法可以使用 VB6 在客户端 PC (Windows) 中检测任何 PDF 阅读器(Adobe Reader、Foxit Reader...)和。 NET (C#)。

我不能通过读取Windows注册表来做到这一点,因为用户可能没有权限读取它。

谢谢。

【问题讨论】:

  • 如果用户可以用 pdf 阅读器双击打开一个文件,那么他/她也可以读取注册表项,告诉 shell 在扩展名为 double 的文件时要做什么-点击。 shell 使用与用户相同的安全令牌运行,因为它只是一个由用户产生的进程。如果您在注册表中查找 .pdf 注册时遇到安全错误,请忽略它并继续您的搜索算法。如果最后您只遇到安全错误,则表示该用户没有可用的 pdf 查看器。
  • 同意,受限用户将拥有 HKCR\.pdf 的只读权限。否则,她将无法启动 PDF 阅读器。
  • 好的,我去测试发送给我的回复,然后我的工作效果最好。我还看到了@David Gladfelter 的评论

标签: .net pdf vb6 pdf-reader


【解决方案1】:

基于 Jerry Coffin 建议使用 FindExecutable 的示例(基于 this article):

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】:

    创建一个扩展名为“.pdf”的临时文件,然后将FindExectuable 用于您的临时文件。请注意,即使只有扩展名真的很重要,FindExecutable 仍然需要一个真实的文件,而不仅仅是具有正确扩展名的名称。

    【讨论】:

    • @divo:感谢您添加链接。
    【解决方案3】:

    此 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
    

    【讨论】:

      【解决方案4】:

      我知道这个问题是针对 VB 的,但是在 C#here 中找到了 FindExecutable 的一个不错的实现:

      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);
            }
          }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-26
        相关资源
        最近更新 更多