假设我有一个程序a.exe,关联文档为.dat,现在运行a.exe,然后双击一个b.dat文档,结果又打开一个a.exe程序。如何才能使b.dat在已打开的a.exe中运行而不另打开一个a.exe?只能用进程间的通信吗?这稍复杂了些,有没有更简单的方法?

解决方案 »

  1.   

    你打开了a.exe之后,打开关联文档的时候。也就是说你的a.exe要这样的功能,不能同时开两个以上,一旦打开了一个,打开另一个的时候就自动关闭,而且在关闭之前发送一个信息给另一个进程就可以了。
      

  2.   

    http://expert.csdn.net/Expert/topic/2130/2130008.xml?temp=.276684
      

  3.   

    ' 也不用上面链接中的那么麻烦。
    ' 在工程中添加一个Form1(窗体)和一个Module1(模块)' 在标准模块中添加如下代码就行了,编译后运行看看,无论你把.exe拷到哪,都不会运行多次' 标准模块:Option Explicit
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
    Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
    Private Const SW_RESTORE = 9Private Sub Main()
    If App.PrevInstance = True Then             ' 如果本程序已经运行, 则将其从任务栏还原
        ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE
        SetForegroundWindow FindWindow("ThunderRT6FormDC", "Form1")
    Else
        Form1.Show
    End If
    End Sub
      

  4.   

    http://expert.csdn.net/Expert/topic/2130/2130008.xml?temp=.276684中
    hisofty(瘦马) 的代码在跨平台使用时可能会出现问题vb提供了DDE支持,用DDE实现吧
      

  5.   

    关于 goodname008(卢培培,LPP Software) 的方法,不想说太多,可是有一点要注意:那就是无法传递command获得的参数
      

  6.   

    关于DDE的实现,可以参考:
    用DDE实现窗体防止运行多个实例并传递命令 
    http://wlbookwl.myrice.com/jck/1027dde.htm
      

  7.   

    我的方法没有考虑获得参数的情况。   :)
    不过在适当的位置用Command函数获得一下然后再判断就完美了。to rainstormmaster(rainstormmaster) :
    //那就是无法传递command获得的参数
    是说我的代码没有考虑到传递参数的情况还是在模块中无法传递Command获得的参数?
    我试了试,模块可以用Command获得参数啊?   :(
      

  8.   

    to goodname008(卢培培,LPP Software) :
    //我的方法没有考虑获得参数的情况。   :)
    不过在适当的位置用Command函数获得一下然后再判断就完美了。用什么事件?恐怕只能在Timer控件的Timer事件进行处理,可是,你考虑过系统性能吗?也许,你有什么好的方法,欢迎交流:)这个问题我曾经花过两个月的时间进行研究,尝试过许多种方案,在基于安全、稳定、效率的原则下,我最终选择了dde另外:
    ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE
    如果有相同标题的vb程序怎么办,哪怕几率只有亿分之一,是不是也要考虑一下
      

  9.   

    to rainstormmaster(rainstormmaster):
    我的办法就是启动时用Command获得一下参数啊。
    Private Sub Main()
    If App.PrevInstance = True Then             ' 如果本程序已经运行, 则将其从任务栏还原
        ' 用Command判断一下参数.........
        ' ..............................
        ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE
        SetForegroundWindow FindWindow("ThunderRT6FormDC", "Form1")
    Else[
    ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE
    如果有相同标题的vb程序怎么办,哪怕几率只有亿分之一,是不是也要考虑一下
    ]
    有理,用我的这个办法确实无法避免这个问题,虽说机率很低吧,但也是应该考虑的。  :)
        Form1.Show
    End If
    End Sub
      

  10.   

    to goodname008(卢培培,LPP Software): 
    //我的办法就是启动时用Command获得一下参数啊你试试看参数能传递给副本吗?
      

  11.   

    If App.PrevInstance = True Then 
     ……
    end if
    这个比较简单,不过缺点是如果程序目录改变了,就不起作用了
      

  12.   

    可是rainstormmaster(rainstormmaster)的办法也无法防止改变目录.
    得想个好办法了.
    想ing..........................
      

  13.   

    我觉得还是用tainstormmaster的方法比较规范一些。至少一些其他的程序都是这样运行的
      

  14.   

    没关系,我的id太长了,没办法,rainstorm被人抢注了
      

  15.   

    呜呜,我上次就rainstormmaster兄和goodname008(卢培培,LPP Software)兄的留言发表了一大通话,居然没了!谢谢热心的多位大侠。
    我当时想的是进程间传递信息用COPY_DATA,但涉及到改写窗体默认过程和传递字符串的指针(传递数字还好一点),很烦,而且很容易崩溃。看来DDE方法确实很好,比COPY_DATA强。
    众位讨论的改变程序运行目录后App.PrevInstance就会失效,我确实还未考虑。看来大家考虑的比我还多,呵呵。实在不行可以将FindWindow和App.PrevInstance结合起来用(用互斥体是不是很杂,涉及到内存映射吧,我还不大了解)。只能帮窗体起一个重复机率很小的标题了,一般来说名字起特别些且长一点重名的很少,而且要同时运行,电脑同时运行的程序不会太多的。在App.PrevInstance=false的情况下,只要FindWindow找到窗体,就认为程序已运行,传递相关信息,如文件名等,然后已经运行的程序收到信息后再传递一个接收到的标志给后打开的程序,收到确认后标志后副本就可关闭。这样就应该没什么问题了吧,因为如果传递到窗体标题相同的其它应用程序,就不会收到确认标志。
        以上只是我的一些想法,不当之处还请指正!
      

  16.   

    //(用互斥体是不是很杂,涉及到内存映射吧,我还不大了解)。看http://expert.csdn.net/Expert/topic/2130/2130008.xml?temp=.276684中
    hisofty(瘦马) 的代码