文号
t50835
阅读
9121
回复
15
收藏
10
求助XXXXXX应用程序之间传递字符串的最简单方法
2012/09/25
IP:澳大利亚
最近本人在搞个程序,一个小功能是需要在程序开始时判断是否有已存在的实例在运行,如果有就告诉那个实例去打开文件(传递个字符串过去)然后结束当前实例.功能就是自动在一个MDI窗口中打开多个文档.
最开始我设想用DDE实现,忽然发现VB2010已经舍弃DDE了,大悲
后来又想到用写文件和注册表的方法,一想效率太低,用socket在没网卡的机子上就是个悲剧,而且这个程序和网络没关系,用socket容易触发防火墙的提示
然后我又用Sendmessage函数+Windows消息+内存映射文件,终于成功了,问题是现在需要.Net4.0支持,很多学校电脑只有.Net3.5,我演示的时候会悲剧......现在求助各位,如何用Sendmessage传递个字符串参数?wParam和lParam都是数字类型的,没法传递字符串,我试过传递指针和结构,都悲剧....

这是我的程序:



Public Class Form1
    <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Unicode, entrypoint:="SendMessageW")> _
    Public Shared Function SendMessage(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As Integer) As Integer
    End Function
    Protected Overrides Sub DefWndProc(ByRef m As System.Windows.Forms.Message)
        Select Case m.Msg
            Case &H400
                If m.WParam = 3180 Then
                    Dim s As New IO.StreamReader(IO.MemoryMappedFiles.MemoryMappedFile.CreateOrOpen("asdn.open", 1024).CreateViewStream())
                    openfile(s.ReadToEnd)
                End If
            Case Else
                MyBase.DefWndProc(m)
        End Select
    End Sub

    Sub openfile(f)
        Text = f
    End Sub
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        If My.Application.CommandLineArgs.Count = 1 Then
            Dim Proc_List As Process() = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName)
            If Proc_List.Length > 1 Then
                For Each i As Process In Proc_List
                    If XXXX <> Process.GetCurrentProcess().Id Then
                        Dim s As New IO.StreamWriter(IO.MemoryMappedFiles.MemoryMappedFile.CreateOrOpen("asdn.open", 1024).CreateViewStream())
                        s.Write(My.Application.CommandLineArgs(0))
                        s.Flush()
                        s.Close()
                        SendMessage(i.MainWindowHandle, &H400, 3180, 0)
                    End If
                Next
                Me.Close()
            Else
                openfile(My.Application.CommandLineArgs(0))
            End If
        End If
    End Sub
End Class

14年3个月前IP:未同步
454580
1楼
回 楼主(金坷居士) 的帖子
低效一点的方法:共享内存
引用
评论
14年3个月前IP:未同步
454581
2楼
额没看清楚。。。。
可以试试调试API,直接控制EIP。
引用
评论
14年3个月前IP:未同步
454582
3楼
回 楼主(金坷居士) 的帖子
低效一点的方法:共享内存
引用
评论
14年3个月前IP:未同步
454638
4楼
把消息设置成WM_COPYDATA试试?
引用
评论
14年3个月前IP:未同步
454650
5楼
回 3楼(phpskycn) 的帖子
各种蛋疼方法都是过了
最后采用一种叫做独立存储文件的东东
实际测试,效率不错,打开文件时察觉不到延时
引用
评论
14年3个月前IP:未同步
454686
6楼
文件 +1
文件 +1
文件 +1
引用
评论
14年3个月前IP:未同步
454896
7楼
回 楼主(金坷居士) 的帖子
只是传递字符串的话LZ可以试下剪切板
引用
评论
14年3个月前IP:未同步
454900
8楼
古老经典的方法是用管道
引用
评论
14年3个月前IP:未同步
455171
9楼
楼上正解,用邮槽也不错[s:178]
引用
评论
14年3个月前IP:未同步
455181
10楼
管道不错,可能换了个名字,但是还是差不多
引用
评论
14年3个月前IP:未同步
456395
11楼
楼主来说一下,可以传递数字,为何不能传递指针……

另外调用winAPI的语法不需要那么复杂

declare function SendMessage lib "user32" alias "SendMessageW" (byval something as whatever...
引用
评论
14年3个月前IP:未同步
456419
12楼
引用
评论
14年3个月前IP:未同步
458687
13楼
既然都用XXXXXX的了,可以试试.Net中的Remoting技术,不过好像也需要打开防火墙,能常情况下多还是用Socket的比较多。
引用
评论
14年3个月前IP:未同步
459119
14楼
'重载窗口消息处理,接收线程同步消息
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

        Select Case (m.Msg)
            Case WM_COPYDATA
                Dim mystr As COPYDATASTRUCT = New COPYDATASTRUCT
                Dim mytype As Type = mystr.GetType
                mystr = CType(m.GetLParam(mytype), COPYDATASTRUCT)

                console.writeline (mystr.lpdata)
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的