从Web应用程序控制Winforms应用程序

3

之前有类似的问题被提出,链接在这里

...但我的问题与众不同,我只需要从网页控制一个winforms应用程序(非双向)。当用户在Web应用程序中点击链接时,我只需要告诉WinForms应用程序打开窗口等操作。

这都是在安全的公司环境下进行的,所以没有真正的安全问题。

我看到了两种可能的解决方案:

1)创建一个ActiveX "shim",它可以轻松地嵌入到网页中

2)在WinForms应用程序中托管WCF服务,监听(REST-ful类型)命令

是否有我错过的非常简单的解决方案?还有其他选择吗?


你的Windows应用程序有多个用户在使用吗?如果是这样,你需要一个集中式服务来将命令分发到每个客户端Windows应用程序。 - Sergey
5个回答

1

根据从网页到WinForms应用程序可以发出的“命令”的复杂性,您可以简单地向Web浏览器注册一个自定义URI方案,以调用您的应用程序。例如,mailto: 调用您的电子邮件程序,或者 itms: 调用iTunes音乐商店。

然后,您的应用程序将识别已经运行的实例,并将参数传递给正在运行的实例。


0

我想要为程序注册一个扩展名。你知道,当你点击xls文件时,会启动带有xls文件url的参数的Excel,当你点击播放列表文件时,它会启动你的媒体播放器。

你可以为(例如)".fro"文件注册一个扩展名,它可以打开你的程序并将.fro文件作为参数传递。

如果你的程序已经在运行,它就会获取参数,否则它会启动程序并传递参数。你的程序读取文件并按照文件中的命令执行。

因此,例如,如果你的Web应用程序中有一个链接,该链接应使你的窗体程序打开某个客户并显示客户详细信息,则可以使你的Web应用程序具有链接<a href="opencustomer.fro">打开客户</a>,文件opencustomer.fro可以是动态创建或静态的。

  1. 注册文件扩展名“.fro”以打开您的.Net程序。(以下是示例)

  2. 使网站使用其中的命令创建.fro文件。

  3. 按照此教程(http://visualstudiomagazine.com/articles/2007/11/01/simplify-application-instancing.aspx)将您的.Net程序设置为单实例应用程序。因此,如果启动第二个实例,则通过命名管道将命令发送到第一个实例。

  4. 使您的.Net程序下载.fro文件并解释文件中的命令。这可能只包含一个客户编号以打开。

我找到了这个关于注册文件类型的VB.NET示例,转换或搜索其C#版本不难:http://bytes.com/topic/net/answers/519230-vb-net-associate-file-program

Public Class Example 

    Public Sub RegisterType() 
        Dim fileReg As New FileTypeRegistrar 

        With fileReg 
            .FullPath = Path_To_Executable 
            .FileExtension = Extension_To_Register 
            .ContentType = "application/" & Your_Description 
            .IconIndex = Icon_Index_In_Application 
            .IconPath = Path_To_Executable 
            .ProperName = Name_Of_Executable 
            .CreateType() 
        End With 

    End Sub 

End Class 

Public Class FileTypeRegistrar 

#Region "Properties & Property Variables" 
    Private _ProperName As String 
    Public Property ProperName() As String 
        Get 
            Return _ProperName 
        End Get 
        Set(ByVal Value As String) 
            _ProperName = Value 
        End Set 
    End Property 

    Private _ContentType As String 
    Public Property ContentType() As String 
        Get 
            Return _ContentType 
        End Get 
        Set(ByVal Value As String) 
            _ContentType = Value 
        End Set 
    End Property 

    Private _FullPath As String 
    Public Property FullPath() As String 
        Get 
            Return _FullPath 
        End Get 
        Set(ByVal Value As String) 
            _FullPath = Value 
        End Set 
    End Property 

    Private _FileExtension As String 
    Public Property FileExtension() As String 
        Get 
            Return _FileExtension 
        End Get 
        Set(ByVal Value As String) 
            _FileExtension = Value.Replace(".", "") 
        End Set 
    End Property 

    Private _IconPath As String 
    Public Property IconPath() As String 
        Get 
            Return _IconPath 
        End Get 
        Set(ByVal Value As String) 
            _IconPath = Value 
        End Set 
    End Property 

    Private _IconIndex As Integer 
    Public Property IconIndex() As Integer 
        Get 
            Return _IconIndex 
        End Get 
        Set(ByVal Value As Integer) 
            _IconIndex = Value 
        End Set 
    End Property 
#End Region 

#Region "Public Methods" 
    Public Sub CreateType() 
        Dim fileName As String = Path.GetFileNameWithoutExtension(FullPath) 
        Dim Ext As String = "." & FileExtension.ToLower 
        Dim extKey As RegistryKey = Registry.ClassesRoot.CreateSubKey(Ext) 

        extKey.SetValue("", fileName) 
        extKey.SetValue("Content Type", ContentType) 
        extKey.Close() 

        Dim mainKey As RegistryKey = Registry.ClassesRoot.CreateSubKey(fileName) 
        Dim defIconKey As RegistryKey = mainKey.CreateSubKey("DefaultIcon") 

        defIconKey.SetValue("", IconPath & ", " & IconIndex) 
        defIconKey.Close() 

        Dim shellKey As RegistryKey = mainKey.CreateSubKey("shell") 
        Dim OpenKey As RegistryKey = shellKey.CreateSubKey("Open") 
        Dim cmdKey As RegistryKey = OpenKey.CreateSubKey("command") 

        cmdKey.SetValue("", """" & FullPath & " %1""") 
        cmdKey.Close() 
        OpenKey.Close() 
        shellKey.Close() 
        mainKey.Close() 

    End Sub 

    Public Sub DeleteType() 
        Dim fileName As String = Path.GetFileNameWithoutExtension(FullPath) 
        Dim Ext As String = "." & FileExtension.ToLower 

        Registry.ClassesRoot.DeleteSubKey(Ext) 
        Registry.ClassesRoot.DeleteSubKey(fileName) 

    End Sub 
#End Region 

End Class 

0
另一种控制winform客户端的方法是在网站上添加web服务,并让您的客户端每2-4秒轮询web服务,以查看是否存在等待执行的特定客户端的命令。
向数据库添加一个表clientid、command、ClientDone。
当已登录用户在Web应用程序中单击应该控制winform客户端的链接时,请在表中添加带有clientid和commmand的行。
如果客户端在winform程序中登录,则winform程序将轮询新存储的命令以供该客户端使用。当客户端执行完命令后,将其标记为完成(或者只需从数据库中删除该行)。
这将假定网站上已登录的用户在winform程序中登录时具有相同的clientid/userid。

0

既然您处于企业环境中,那么使用的浏览器范围可能非常有限。您是否考虑编写一个精简的Firefox插件,与您的网站进行接口交互,并将所有命令转发到WinForms应用程序中?


0
2) 在WinForms应用程序中托管一个WCF服务,该服务监听(REST-ful类型)命令。
这非常简单...我会选择这个。

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