返回首页

问题
GotDotNet论坛,用户问"有没有办法支持一个"ddeexec'的功能在vb.net应用程序的文件关​​联,所以当应用程序已经在运行,一个文件双击从Windows资源管理器,应用程序可以处理呢?"。 DDE有没有被推荐的很长一段时间,。NET中不支持它。一个解决方案
就个人而言,我可能永远不会被人打扰得到DDE工作。相反,我用从旧vbAccelerator站点: 名称与具体到您的应用程序创建一个互斥; & #160; 如果互斥不存在,你的应用程序没有运行: 启动应用程序;& #160; 标记与属性,以使容易辨认(SetProp)的主要形式;  60; 子类的主要形式,并等待WM_COPYDATA消息。数据将包含从一个新的实例的命令行;  60; 如果互斥已经存在,你的应用程序已经运行: &# 160; 枚举所有的窗口,找到一个与你的财产(GetProp); 如果你没有找到它,进行第2步; 如果你找到它,它发送WM_COPYDATA消息,从这个实例的命令行;   ;
这可能看起来非常复杂,但App.PrevInstance财产并不总是可靠的,并没有提供任何方式将数据传输到其他实例。。NET
当我第一次看这个问题,我认为必须有一个更好的解决方案。NET中 - 这是很常见的一种应用,我是肯定的功能,将内置的。其中一些 - 如互斥锁 - 是。在System.Diagnostics类有些看起来非常有前途的的,但似乎并没有工作。举例来说,似乎没有一种方式从Process.MainWindowHandle NativeWindow对象 - FromHandle方法返回Nothing。有一个COPYDATASTRUCT System.Windows.Forms的,但尽管对象浏览器认为它是公共的,编译器认为它是私有的,所以不能使用。
最后,我不得不求助于我在VB6中使用了很多相同的Win32 API调用。子类是容易得多,VB.NET,和互斥对象的帮助,但我不能看到一个纯粹的托管代码解决这个问题。加端,Marshal类提供了一个非常简单的方法来管理对象和联合国的托管API之间的数据传输,虽然有些调用VB6的程序员可能并不明显。对象序列化也使人们有可能通过以及进程之间的对象。使用代码
要使用自己的代码,你将需要添加mMain.vb的文件添加到项目。设置启动对象,在本模块主要小组,并改变引用frmMain的,以反映您的应用程序的主要形式。您需要使您的主要形式实施mMain.SingleInstance.ISingleInstanceForm,使用下面的代码为例:


//

// frmMain.vb

//

...



Public Event WndProc2(ByVal m As System.Windows.Forms.Message, _

                      ByRef Cancel As Boolean) _

    Implements mMain.SingleInstance.ISingleInstanceForm.WndProc



'//Subclassing the form - so much easier than VB6! :)

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

    Dim bCancel As Boolean = False

    RaiseEvent WndProc2(m, bCancel)

    

    'If this message wasn't handled (i.e. WM_COPYDATA), pass it on

    If Not bCancel Then MyBase.WndProc(m)

End Sub



'//The reference to the handle is required for SetProp

Public ReadOnly Property hWnd() As System.IntPtr _

Implements mMain.SingleInstance.ISingleInstanceForm.Handle

        

    Get

        Return Handle

    End Get

End Property



'//This is where the string passed in the COPYDATASTRUCT is handled

'//In this case, we have a Base64 serialization of the CmdArgs() array

Public Sub HandleCommand(ByVal strCmd As String) _

    Implements mMain.SingleInstance.ISingleInstanceForm.HandleCommand

        

    Dim arrCmd() As String

    Try

        arrCmd = SerialHelper.DeserializeFromBase64String(strCmd)

            HandleCommand(arrCmd)

    Catch ex As Exception

        MsgBox(ex.ToString)

        HandleCommand(New String() {strCmd})

    Finally

        Erase arrCmd

    End Try

End Sub



'//This is where we handle the command-line arguments

'//In this sample, I simply add them to the list-box

'//You would probably want to open the files, etc.

Public Sub HandleCommand(ByVal strArgs() As String)

    Dim strCmd As String



    For Each strCmd In strArgs

        lstEvents.Items.Add("CMD: " & strCmd)

    Next

End Sub



...    

///

VB.NET和指针
这个代码的一个有趣的事情 - 我已经发现了如何处理与联合国管理的指针。例如,COPYDATASTRUC结构包含的lpData成员,这是一个字节数组的指针。如果成员是定义为一个IntPtr,结构不能被传递给一个API,所以它声明为一个整数。
有两个操作 - 设置lpData成员指向一个字符串,并从中检索一个String。在VB6中,你会使用VarPtr和RtlMoveMemory API(又名CopyMemory)做到这一点。在。NET,VarPtr不再存在,但Marshal类提供了更好的替代品。
要设置指针到一个字符串值:{C}
要检索一个String指针:完成了!
如果有人发现一个更好的办法做到这一点,或一种方式来获得Process.MainWindowHandle NativeWindow对象,请让我知道!积分
SerialHelper类是"借用"从

回答

评论会员:Jamesthebod 时间:2011/11/29
你用VB测试2005年的文章中,我试图下载,它没有转换,但现在行的错误:

公共事件WndProc2(#System.Windows.Forms.Message,为布尔的ByRef取消米)实现TestSingleInstance.mMain.SingleInstance.ISingleInstanceForm.WndProc

读取

"WndProc2"不能公开的基础委托类型"mMain.SingleInstance.ISingleInstanceForm._WndProc"的事件,它是通过类"frmMain的"的项目外实施。

在此,你能透露任何光线 - 没有其他错误标记{S0}
评论会员:理查德推定 时间:2011/11/29
最明显的解决方案将改变事件的声明,从公共朋友。

然而,VB.NET 2005年现在已经内置支持单实例应用程序,这是更容易使用:
{A4}

"看着这些人在我的灵魂深处,并指派我根据我加入的顺序的数字。" - 荷马
评论会员:djdidge 时间:2011/11/29
您好,
大文章,我从中学到了,但仍然需要学习更多!
我有一个系统有时会停留在一个循环的问题击中MainForm_WndProc

这是一个已知的问题?

的问候,
评论会员:理查德推定 时间:2011/11/29
如果您已设置WM_COPYDATA块(217至231行)在MainForm_WndProc程序之外的情况下一个突破点,你可能会停留在一个循环。每一条消息的形式发送的时间,程序被调用,并在调试器窗口被激活。这发出了一个停用消息的形式,再次调用过程。当您尝试切换回的形式,它就会被激活消息,切换到调试器再次

我会建议您切换到{A5},因为这是更可能是与2005年在VB中的新应用程序框架兼容。本文是一个非常简单的翻译,VB6的kludge,并应被视为已过时。

{A6}
{A7}

"看着这些人在我的灵魂深处,并指派我根据我加入的顺序的数字。" - 荷马
评论会员:。djdidge 时间:2011/11/29
感谢理查德,我会制定出微软解决方案

我已经尝试了多次得到解决MSDN文章你推荐我的头,但他们不来我很容易! {S1})

再次感谢。
评论会员:StijnCourtheyn 时间:2011/11/29
MSDN页面的链接都死了
你可以找到的文章,所以如果你想放置新的链接
评论会员:理查德推定 时间:2011/11/29
新的链接是:

第1部分:{A8}
第2部分:{A9}
然而,VB.NET V2现在已经内置支持单实例应用程序,这是更容易使用:
{A10}

"看着这些人在我的灵魂深处,并分配给我我加入的顺序为基础的数字。"
- 荷马
评论会员:StijnCourtheyn 时间:2011/11/29
感谢
我会看看在文件
评论会员:理查德推定 时间:2011/11/29
如果我有一个应用程序在后台运行时间和我点击exe文件..我怎么能有上首次应用的重点?
评论会员:Vitoto 时间:2011/11/29
。使用本文中的代码,HandleCommand方法将被调用的主要形式,当您尝试推出一个新的应用程序实例

随着{A11}],您将需要处理启动或StartupArguments UserApplicationContext派生的应用程序类的事件。

"看着这些人在我的灵魂深处,并指派我根据我加入的顺序的数字。" - 荷马
评论会员:。理查德推定 时间:2011/11/29
嗨,好文章

也许你可以帮助我。

我需要启动EXE程序,从我的VB.Net程序杀死进程时,我的VB.Net程序。EXE推出需要模具。

你有什么想法吗?

评论会员:Vitoto 时间:2011/11/29
启动其他程序,可以使用{A12}]类。要正常关闭过程中,使用{A13}]的方法。如果CloseMainWindow的/关闭不工作,您可以使用{A14}]的方法,这将迫使程序异常终止。

"看着这些人在我的灵魂深处,并指派我根据我加入的顺序的数字。" - 荷马
评论会员:。理查德推定 时间:2011/11/29
我Anticheat方案和工作需要依赖

我的计划推出​​game.exe时,我的计划是死亡或接近,那么我需要game.exe死。

问题是,当杀过程中,我的程序,我需要cheat.exe死得太。

任何想法?
评论会员:IcingDeath 时间:2011/11/29
如果父进程是可能被杀死,而不是退出优雅的,你将需要使用Windows 2000或更高C和作业内核对象,因为Windows不保持一个父/子关系流程。

{A15}

"看着这些人在我的灵魂深处,并指派我根据我加入的顺序的数字。" - 荷马:
| IcingDeath
评论会员:游客 时间:2011/11/29
我做了一个小程序,它位于系统托盘上,我的网络上的其他计算机发送文件。我不有形式造成我的代码开始这样的的SubMain()"等等等等application.run年底分所以,我怎样才能知道如果我的程序的另一个实例已在运行?
理查德推定
评论会员:游客 时间:2011/11/29
哎呀只是想到一个解决方案......和不完全的解决方案(跛脚同类),但因为我有我在一个特定的端口的应用程序li​​stenning,如果我跑第二次,它会崩溃,因为该端口将采取LOL)
科技小组委员会
评论会员:游客 时间:2011/11/29
"Mutex的选项仍然没有形成。另一种选择是使用远程,克里斯安德森的MSDN文章中所述:{A16}{A17}"看着这些人在我的灵魂深处,并指派我根据我加入的顺序的数字。"-荷马:|理查德推定
您好,

我还使用在我的程序的托盘图标,所以我最小化窗口时,程序从任务栏删除。
ShowInTaskbar =假
这意味着它也不能在Windows任务管理器(CTRL - ALT - DEL)的任务不再可见,但程序可以与多个实例opend,再次

任何想法如何解决这个问题?

谢谢!
评论会员:菲利普Hollmuller 时间:2011/11/29
代码可能无法找到你的主窗口句柄,所以它允许新的实例来运行

此问题不会发生在克里斯安德森的系列文章中所述的远程访问解决方案:

{A18}
{A19}

只要确保你阅读下面的线程可能的解决方法("{A20}")克里斯的代码中发现的问题,我。

"看着这些人在我的灵魂深处,并指派我根据我加入的顺序的数字。" - 荷马
评论会员:理查德推定 时间:2011/11/29
您好。我试着用单实例应用程序的命令行参数。它的工作原理以及在本地计算机上,但如果从网络上的其他地方开始的,它来自一个System.Security.securityException和应用程序退出。{BR​​}
有人可以帮助

在此先感谢。

菲利普

菲利普Hollmuller www.icam.ch
评论会员:JasonHo 时间:2011/11/29
从网络共享运行的应用程序的开发有一个更受限制的安全政策,即那些从本地机器上运行。您需要调整您的安全策略授予相关权限,您的应用程序。

最简单的方法做,这是与"信托的大会"管理工具"下的"向导 - > NET框架奇才。

"看着这些人在我的灵魂深处,并指派我根据我加入的顺序的数字。" - 荷马:
|理查德推定
评论会员:游客 时间:2011/11/29
您好,感谢您为您的伟大的代码。我发现的文件名,例如abc1234567890.jpg将被截断到如ABC123〜1.JPG"HandleCommand(BYVALstrArgs()作为字符串)"时,字符串参数。是否有可能得到完整的文件名,而不是截断的版本?非常感谢你!{S2}贾森何
michiganian
评论会员:游客 时间:2011/11/29
当您创建文件关联,你需要确保你有文件的参数加引号。该命令应该的样子:"您的应用程序路径]""%1"如果仍然不起作用,你可以P/Invoke的{A21}]功能得到完整的路径名。"看着这些人在我的灵魂深处,并指派我根据我加入的顺序的数字。"-荷马
!理查德推定
评论会员:游客 时间:2011/11/29
您好感谢您这样一个有用的文章!我有一个问题,虽然...我有关联的一个特定的文件扩展此应用程序(TestSingleInstance.exe)(XYZ)。双点击在Windows资源管理器中就可以了,当我打开第一个文件(one.xyz)时,一切看起来不错。但是当我双击第二个文件(two.xyz),的形式是不带入焦点。虽然它的更新列表框是。唯一的形式窗口是不能带到前面。这是由设计或错误?无论哪种方式,如何才能改变?提前感谢!