协议处理程序

6
需求: 我们想通过一个按钮或链接从网页启动外部比较工具(如BeyondCompare或WinMerge)。应该在启动时将文本文件路径传递给该工具,因此它可以理解并在左侧和右侧比较面板中打开它们。 尝试的解决方案:
1)使用JavaScript的ActiveXObject:用户只需单击按钮/链接,即可启动安装在其计算机上的比较工具。但它仅在Internet Explorer中有效,所以我们不能采用这种方法。
参考:How to run an external program, e.g. notepad, using hyperlink? 2)使用Java Applet:由于安全原因,在浏览器中嵌入的applet不被允许访问本地文件系统,并且会抛出“Access Control Exception”。因此,我们也无法采用这种方法。
参考:Why is my applet throwing an AccessControlException? 3)使用协议处理程序:我们可以设置自定义URL协议来触发程序。就像我们使用"mailto:user@email.com"语法创建电子邮件链接一样,这将自动在Windows上启动Outlook。 "mailto"是Windows注册表中预定义的协议。
同样,我们在注册表中创建了自己的协议,比如"launchCompareTool",并能够启动任何应用程序,如WinMerge或BeyondCompare。然而,我们无法实现将左侧和右侧文件路径作为参数传递给应用程序。可能需要启动的应用程序希望接收这些参数。
参考:http://www.dreamincode.net/forums/topic/220444-run-program-from-server-on-client-computer/ http://msdn.microsoft.com/en-us/library/aa767914%28v=vs.85%29.aspx#app_reg 与"mailto"协议不同,它具有"body"和"subject"参数,可以传递给邮件客户端(如Outlook),后者可以理解它们。这些比较工具没有此类参数,可以从协议传递。
还有其他方法可以满足这个要求吗?
谢谢, Abdul
5个回答

2
最近出现了另一种执行相同操作的方法。基本上,这种新方法依赖于创建一个 Handler 应用程序,它只是一个基于 Windows 控制台的 ClickOnce 应用程序。ClickOnce Handler 应用程序将充当主机(网页或 Outlook 或任何可以嵌入链接的东西)和目标应用程序(如 WinMerge 或 Beyond Compare)之间的拦截器。在主机应用程序中单击嵌入的链接时,将调用 Handler 应用程序。链接只是一个 http url,其中包含查询字符串参数中的信息。由于处理程序应用程序是 ClickOnce 部署的,因此它允许自己发布到 Web 服务器。嵌入的链接(HTTP URL)将调用处理程序应用程序,然后处理程序应用程序将解析接收到的查询字符串参数,并最终调用相关的目标应用程序。处理程序应用程序可以被视为一个 Click Once 部署的解析器应用程序。以下是详细的文章和代码示例:Custom-HyperLinks-Using-a-Generic-Protocol-Handler

1
定制的URL可以调用DOS批处理文件或VBScript,解析参数然后调用WinMerge。

0

首先,我会介绍需求。

然后,我将向您展示如何满足每个需求。

需求:

  1. 创建一个小的命令行应用程序,它将以目标应用程序路径作为参数,并在“?”后使用目标应用程序的参数。
  2. 创建一个包含自定义URL注册信息的.reg文件。
  3. 在网页上创建具有自定义URL的应用程序链接。

让我们开始:

  1. 创建命令行应用程序: 步骤:
    1. 打开Microsoft Visual Studio,并选择使用Visual Basic模板创建新的控制台应用程序。我们将其称为“MyLauncher”。
    2. 在项目属性>>应用程序中将目标框架版本设置为.NET 2.0,以确保任何人都能使用此应用程序。 C. 添加对项目的引用 - System.Windows.Forms D. 将Module1.vb文件中的所有默认代码覆盖为以下内容:

代码:

 Imports System.IO
 Imports System.Threading
 Imports System
 Imports System.Windows.Forms


  Module Module1

Dim array As String()

Sub Main()

    Dim origCommand As String = ""
    Dim sCommand As String = Command().ToString

    If String.IsNullOrEmpty(sCommand) Then
        Application.Exit()
    End If

    origCommand = sCommand
    origCommand = origCommand.Substring(origCommand.IndexOf(":") + 1)
    origCommand = origCommand.Split("""")(0)

    execProgram(origCommand)

End Sub


Private Sub execProgram(ByVal sComm As String)
    Try

        Dim myPath As String = Nothing
        Dim MyArgs As String = Nothing
        Dim hasArgs As Boolean

        If sComm.Contains("""") Then
            sComm = sComm.Replace("""", "").Trim()
        End If

        If sComm.EndsWith("?") Or sComm.Contains("?") Then
            hasArgs = True
            MyArgs = sComm.Substring(sComm.IndexOf("?") + 1)
            myPath = sComm.Substring(0, sComm.IndexOf("?"))
        Else
            myPath = sComm
        End If

        If hasArgs Then
            startProg(myPath, MyArgs)
        Else
            startProg(myPath)
        End If

    Catch ex As Exception
        Dim errMsg As String = sComm & vbCrLf & vbCrLf & "The program you are trying to launch was not found on the local computer" & vbCrLf & vbCrLf & vbCrLf &
      "Possible solutions:" & vbCrLf & vbCrLf &
     "If the program doesn;t exist on the computer, please install it. " & vbCrLf & vbCrLf &
     "If you did install the program, please make sure you used the provided default path for istallation. " & vbCrLf & vbCrLf &
      "If none of the avove is relevant, please call support" & vbCrLf & vbCrLf

        If ex.Message.Contains("The system cannot find the file specified") Then

            MessageBox.Show(errMsg, "System Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
        Else
            MessageBox.Show(ex.Message, "Default Error", MessageBoxButtons.OK)
        End If
    End Try

End Sub

Private Sub startProg(myPath As String, Optional MyArgs As String = "")
    Try
        Dim proc As Process
        If Not String.IsNullOrEmpty(MyArgs) Then
            proc = New Process()
            proc.EnableRaisingEvents = False
            proc.StartInfo.FileName = myPath
            proc.StartInfo.Arguments = MyArgs
            proc.Start()
        Else
            proc = New Process()
            proc.EnableRaisingEvents = False
            proc.StartInfo.FileName = myPath
            proc.Start()
        End If
    Catch ex As Exception

    End Try

End Sub

End Module

E. 编译程序并在本地测试后,将其放置在一个集中的位置,最好是每个人都可以访问的网络驱动器上。

2. 创建一个包含以下代码的 .reg 文件:
Code:

      Windows Registry Editor Version 5.00

     [HKEY_CLASSES_ROOT\mylauncher]
     "URL Protocol"="\"\""
     @="\"URL: mylauncher Protocol\""

     [HKEY_CLASSES_ROOT\mylauncher\shell]

     [HKEY_CLASSES_ROOT\mylauncher\shell\open]

     [HKEY_CLASSES_ROOT\mylauncher\shell\open\Command]

     ;example path to the launcher is presented below. Put your own and mind the escape characters that are required.
     @="\"\\\\nt_sever1\\Tools\\Launcher\\BIN\\mylauncher.exe\" \"%1\""

A. 通过您的系统管理员中心分发注册表密钥或在每台计算机上启动.reg文件。
B. 用法:
mylauncher:AppYouWantToLaunchPathGoesHere?ArgumentsGoHere

  • 在您的网页上创建超链接:
    代码:

     <!doctype html>
     <html>
     <head>
    
      </head>
      <body>
    
       <div class="test-container">
          <a href='mylauncher:C:\Program Files\IBM\Client Access\Emulator\pcsfe.exe?U=MyUserName' >测试</a>
       </div>
    
    
       </body>
        </html>
    


    如果有什么问题,请写信给我。我会帮助你的。
    祝你好运,朋友。


  • 0

    我有一个类似的需求,需要从浏览器应用程序与桌面客户端进行通信。我采用的方法是Java Applet。

    很快我遇到了你提到的完全相同的问题,即由于安全原因而导致的“访问控制异常”。正确处理此问题的方法是对Applet进行签名,然后您就可以继续操作了。以下是我签署我的Applet所采取的步骤:

    javac MyClient.java
    jar cvf MyClient.jar MyClient.class
    keytool -genkey -validity 3650 -keystore pKeyStore -alias keyName
    keytool -selfcert -keystore pKeyStore -alias keyName -validity 3650
    jarsigner -keystore pKeyStore MyClient.jar keyName
    

    0

    是的,您可以通过这种方式传递参数。 在HTML代码中执行以下操作

    "<a href='alert:\"Hello World\"'>this link</a>"

    这将生成HTML如下:

    <a href="alert:"Hello World"">this link</a>

    它将传递两个参数给您的exe,即"alert:Hello"和"World"。 我仍在寻找如何使第一个参数仅为“Hello”,而无需进行任何解析。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接