近来写了个简单的音乐播放器, 每次双击音乐文件, 都会再次运行一个实例, 觉得不太方便, 只需一个运行着的实例即可, 因此着手解决这个问题.
    最常用的方法, 当然是在查找当前相同的进程名称, 如果有,则退出, 没有则初始化本实例. 方法比较简单,但有效.
private static bool FoundRunningInstance()
{
 Process currentProcess = Process.GetCurrentProcess();
 Process[] procList = Process.GetProcessesByName(currentProcess.ProcessName);

foreach (Process proc in procList)
 {
  if (proc.Id != currentProcess.Id)
  {
   return true;
  }
 }
 return false;
}

public static void Main(string[] args)
{
 if (args.Length == 0)
  Application.Run(new MainForm());
 if (args.Length == 1)
 {
  if (!FoundRunningInstance())
   Application.Run(new MainForm(args[0]));
  else
   Environment.Exit(0);
 }
}
    这样运行起来是OK了, 但问题也随之而来, 如果已经运行了一个实例, 再双击一个音乐文件, 虽然不再运行新的实例, 但双击的音乐, 也没有预想的那样想起来. 后来想到微软的媒体播放器作为默认的播放器时, 每次双击新的音乐文件, 已经运行的实例会播放选定的音乐.
    如果实现这个效果呢?
    要让已经运行的实例接受新的音乐文件路径, 只有在双击后初始化新的实例前给running instance一个参数. 由此, 涉及到了进程间的通信. 实现进程间通信最常用的是使用windows API SendMessage函数. SendMessage函数的定义:
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
在四个参数中,全是整型的, 但这里需要传送的是一个字符串. 使用SendMessage是无法直接传送字符串的, 但可以通过发送WM_COPYDATA消息, 发送自定义只读数据, 这个自定义的数据, 在C#中使用struct实现.
public struct ProcessCopyDataStruct
{
 public int dwData;  // 或许自己需要的四字节标识
 public int cbData;
 [MarshalAs(UnmanagedType.LPStr)]  // lpData字符串的长度
        public string lpData;  // 需要传送的字符串
}
到这里, SendMessage函数定义也需要重新改一下了.
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref ProcessCopyDataStruct lParam);
Msg要传送的消息WM_COPYDATA的定义数值: public const int WM_COPYDATA = 0x004A;
    写到这里就要说说很多文章的不负责任了, 像WM_COPYDATA这类的变量, 虽说是API中使用, 可以查得到, 但对新手来说却是一头雾水, 把代码一套, 报错变量未定义, 就那么一个复制粘贴, 很多文章就是不把实际的值贴出来, 太不负责任了.
    定义好了结构, 就可以实现消息的发送了. 现在回头再修改一下FoundRunningInstance方法和Main方法.
    其中结构中dwData, 自己定义为:WM_QINGMUSIC = 0x8888;
private static bool FoundRunningInstance(string musicFile)
{
 Process currentProcess = Process.GetCurrentProcess();
 Process[] procList = Process.GetProcessesByName(currentProcess.ProcessName);

foreach (Process proc in procList)
 {
  if (proc.Id != currentProcess.Id)
  {
   if (musicFile == null) return true;
   ProcessCopyDataStruct copydata;
   copydata.dwData = WM_QINGMUSIC;
   copydata.lpData = musicFile;
   copydata.cbData = System.Text.Encoding.Default.GetBytes(musicFile).Length + 1;
   SendMessage(proc.MainWindowHandle, WM_COPYDATA, currentProcess.Handle, ref copydata);
   return true;
  }
 }
 return false;
}

public static void Main(string[] args)
{
 if (args.Length == 0)
 {
  if (!FoundRunningInstance(null))
   Application.Run(new MainForm());
  else
   Environment.Exit(0);
 }
 if (args.Length == 1)
 {
  if (!FoundRunningInstance(args[0]))
   Application.Run(new MainForm(args[0]));
  else
   Environment.Exit(0);
 }
}
    到这里发送消息就做好了, 剩下的就是要Running Instance接收发过来的消息. 这里要重载一个方法WndProc.
protected override void WndProc(ref Message m)
{
 if (m.Msg == WM_COPYDATA)
 {
  ProcessCopyDataStruct copydata = (ProcessCopyDataStruct) m.GetLParam(typeof(ProcessCopyDataStruct));
  PlayMusic(copydata.lpData); // 此处为播放传过来的音乐文件路径, 可自由处理.
 }
 base.WndProc(ref m); // 这一句还是不能忘了.
}
    进程间传送自定义结构数据, 就完成了. 其实本不复杂, 麻烦呢只能怪微软把个API弄得那么多, 让人记也记不住, 查也不好查.

进程间通信-字符串的传递相关推荐

  1. c语言解析字符串报文,传递字符串数组报文和解析

    1 .项目中,难免遇到两个系统平台数据的交互,此时就需要通过接口来完成了: 2.WebService 基于 HTTP 通信,它跨平台,使得易购平台能无缝衔接,将应用程序的逻辑和数据暴露,使得其他应用系 ...

  2. JavaScript使用url字符串拼接传递参数,截取参数

    getData(){// location中的search 就是传递过来的参数,首先先把最前的问号去掉// 再以参数传递的分割符分割字符串就得到了 'key=xx','key=xxx'一个数组//再对 ...

  3. c ajax传递多个参数,c# – 使用jQuery AJAX将字符串数组传递给具有可变参数数量的webmethod...

    修改后的服务器端代码: [WebMethod] public string Concat(List arr) { string result = ""; for (int i = ...

  4. linux syscall参数,SYSCALL: 传递字符串参数的系统调用

    目录 实践原理 用户空间可用通过系统调用可以将一个或多个字符串数据传递给内核空间.对于 字符串参数,用户空间必须通过指针的方式传到内核空间,由于这样的方式导致 内核空间不能直接访问用户空间的数据,会导 ...

  5. Android安全笔记-进程间通信基本概念(intent、bundle、Parcelable、parcel)

    进程间通信 进程间传递消息: 例如启动一个Activity,在Intent中设置传递参数及其他数据(字符串.整数.数组.对象) ·intent.putExtra 消息组织和传递:Intent.Bund ...

  6. 在页面之间传递信息--查询字符串

    在页面之间传递信息 ,有一个常用的方法就是在 URL中使用查询字符串. 例如: http://www.soso.com/q?unc=i400044&sc=web&bs=51cto&am ...

  7. JS对象和JSON字符串相互转化总结

    在web开发中,一般情况下需要前端和服务器的交换数据,我们一般使用JSON来完成数据的传输,JavaScript操作的对象是一般是变量:因此我们需要将JSON字符串转换为JS变量,下面总结JS对象和J ...

  8. JavaScript是如何工作的:JavaScript的共享传递和按值传递

    关于JavaScript如何将值传递给函数,在互联网上有很多误解和争论.大致认为,参数为原始数据类时使用按值传递,参数为数组.对象和函数等数据类型使用引用传递. 按值传递 和 引用传递参数 主要区别简 ...

  9. VB 字节数组和字符串的转换问题 (StringByte)

    VB 字节数组和字符串的转换问题 (String<>Byte) Posted by JiaJia 16 March,2009 (2)Comment 一. 前言 数据类型转换在编程中经常用到 ...

最新文章

  1. Eclipse复制或修改项目后,把项目部署后发现还是原来的项目名称
  2. 【网络流24题】I、 方格取数问题(二分图的最大独立集/最小割)
  3. ICLR 2019论文解读:量化神经网络
  4. SpringBoot中logback日志保存到mongoDB
  5. mac命令行ftp操作
  6. Fast R-CNN论文详解
  7. 变频器端子阻抗3k_PLC与变频器连接问题分析
  8. php提交表单处理,PHP表单处理
  9. QT程序启动画面问题
  10. nodejs前端跨域访问
  11. 超图(idesktop iserver10) 处理osgb倾斜摄影和tif并 发布 加载 ---1---连续更新
  12. Codeforces918 D. MADMAX(博弈,记忆化搜索)
  13. msfvenom生成后门程序及利用
  14. 珍贵数学文献(II)
  15. STM32之如何在ST官方网站下载资料
  16. 脚手架的logo字符图片生成
  17. iperf 网速测速
  18. matlab es2函数,zjdy doing的终极地狱完整版。可以说 这个版本在ES2架构中算首屈一指的,虽然他说自 matlab 238万源代码下载- www.pudn.com...
  19. word文档的目录、页码、引用出现乱码
  20. 无人机驾驶员培训学习记录(八)

热门文章

  1. 一文彻底搞懂字符串、字符串常量池原理
  2. 【SpringMVC框架】springmvc的基础知识
  3. 为什么Go中有的自定义error会导致内存溢出
  4. Java会话技术之 —— Spring Session
  5. 基于rocketMq实现分布式事务解决方案
  6. java循环 排序 查找
  7. Struts2 自定义验证器
  8. 2016全球可再生能源投资额为2416亿美元
  9. win7下wifi密码的保存路径
  10. 如何在没有tomcat情况下直接连接JMX监控JVM