c#怎么只启动一个例程?以及启动参数传递问题

时间:2022-06-01 19:08:16
我希望自己写的桌面应用程序只能启动一个例程。不希望它像QQ那样可以开很多个。
我希望实现这样的功能:
1、程序启动的时候检查,如果发现没有正在运行的例程则正常启动;
2、如果发现已经有例程在运行,则把那个启动的历程show出来,并向那个启动的例程传递一个参数。

我查了一下,如果只是第一个问题,比较好解决,关键是我的第二个问题……感觉完全没有思路。
希望大家帮帮忙!

15 个解决方案

#1


1、程序启动的时候检查,如果发现没有正在运行的例程则正常启动; 
2、如果发现已经有例程在运行,则把那个启动的历程show出来,并向那个启动的例程传递一个参数。


program入口项目不要任何其他DD,就是exe的入口

program调用facade.getInstance()单例获得facade项目下的facade类对象
facade.show()

show()方法有你控制你要显示的窗体,如果发现已经有例程在运行,则把那个启动的历程show出来,用 事件委托向那个启动的例程传递一个参数。

#2


在启动的时候,判断是否有程序实例在运行,有就show()一下,然后向程序对象传递参数。
帮楼主顶一下。

#3


能不能说具体一点呢……不是很明白你讲的。

#4


下贴3楼的代码,利用命名事件来发现第一个进程,并通过注册表来传递简单的参数给第一个进程: 
如何操作我的程序的另一个实例(进程)?

#5


防止多个进程运行可以用互斥体.
至于进程的通信...
可以重载WndProc后发消息.
也可以用管道.

#6


可以重载WndProc后发消息. 
具体怎么实现?

#7


static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if (System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName).Length > 1)
            {
                _MessageBox.ShowDiaLog(null,"已经有此程序在运行了!",FormStartPosition.CenterScreen);
                Application.Exit();
                return;
            }
            Application.Run(new Form1());
        }

#8


引用 7 楼 yuehuolong 的回复:
static void Main() 
        { 
            Application.EnableVisualStyles(); 
            Application.SetCompatibleTextRenderingDefault(false); 
            if (System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName).Length > 1) 
            { 
                _MessageBox.ShowDiaLog(null,"已经有此程序在运行了!",FormStartPosition.CenterScre…

这个值解决了第一个问题呵
关键是参数传递问题

#9


引用 5 楼 ChrisAK 的回复:
防止多个进程运行可以用互斥体. 
至于进程的通信... 
可以重载WndProc后发消息. 
也可以用管道.

我的问题就是说怎么用重载WndProc,以及发送自己的消息?
谢谢你。

#10


Program.cs里
  /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] arg)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            System.Diagnostics.Process[] _Process = System.Diagnostics.Process.GetProcessesByName("WindowsApplication1");
            for(int i=0;i!=_Process.Length;i++)
            {
                IntPtr _Text = System.Runtime.InteropServices.Marshal.StringToBSTR("中哦");
                Zgke.SysInfo.WindowsAPI.Win32API.SendMessage(_Process[i].MainWindowHandle, 500, 500, _Text);
            }
            Application.Run(new Form1());
            
        }


Form1里加

 private ControlMsg _Msg = new ControlMsg();
        private void Form1_Load(object sender, EventArgs e)
        {           
            _Msg.LoadMessage += new ControlMsg.Msg(_Msg_LoadMessage);
            _Msg.AssignHandle(this.Handle);
        }

        void _Msg_LoadMessage(ref Message p_Message, ref bool p_Run)
        {
            if (p_Message.Msg == 500)
            {
                this.Text = p_Message.WParam.ToInt32().ToString() + "_" + p_Message.LParam.ToInt32().ToString();
                string _Value=System.Runtime.InteropServices.Marshal.PtrToStringBSTR(p_Message.LParam);
                this.Text = _Value;
                p_Run = false;
            }
        }
        public class ControlMsg : NativeWindow
        {
            public delegate void Msg(ref Message p_Message, ref bool p_Run);
            public event Msg LoadMessage;

            protected override void WndProc(ref Message m)
            {
                bool p_Run = true;
                if (LoadMessage != null) LoadMessage(ref m, ref p_Run);
                if (p_Run) base.WndProc(ref m);
            }
        }     
      

#11


API声明放到Program.cs里...少给你了


[DllImport("user32.dll", CharSet = CharSet.Auto)]
        static public extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

#12


互斥最简单


using System.Threading;
            try
            {
                bool ret;
                System.Threading.Mutex mutex = new System.Threading.Mutex(true, Application.ProductName, out ret);
                if (ret)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    System.Windows.Forms.Application.Run(new FrmMain());
                    mutex.ReleaseMutex();
                }
                else
                {
                    MessageBox.Show(null, "请不要同时运行多个本程序。\n这个程序即将退出。", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    //   提示信息,可以删除。   
                    Application.Exit();//退出程序   
                }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.StackTrace);

            }
//这是我一个工程Program.cs里的代码,看一眼你就明白了.



System.Diagnostics.Process.Start(@"XXXX\\XXXX.exe", "-window");//后面的就是参数

#13


引用 9 楼 liudanking 的回复:
引用 5 楼 ChrisAK 的回复:
防止多个进程运行可以用互斥体. 
至于进程的通信... 
可以重载WndProc后发消息. 
也可以用管道. 
 
我的问题就是说怎么用重载WndProc,以及发送自己的消息? 
谢谢你。
重载WndProc很简单.
你做一个WinForm程序的时候vs都会自动从Form派生出一个
窗体类.在这个类里重载就行了;说白了就是在类里加一条函数:
protected override void WndProc(
ref Message m
){
}
这样就能处理自己的消息.
至于发消息...
参考楼上的声明,直接用SendMessage.
不过进程间的消息有个缺点就是你只能发
整型数据,而字符串之类的不能发.因为毕竟是在不同的进程控件.
所以如果要传送复杂参数的话首选的还是管道.
或者.net Remoting也不错.

#14


囧.
说错了.
如果是自己做的程序的SendMessage也可以
发一个字节缓冲区,只要使用WM_COPYDATA消
息即可,Windows系统会保证将缓冲区的数据复
制到对方的进程地址空间.

#15


有没有正确的答案啊

#1


1、程序启动的时候检查,如果发现没有正在运行的例程则正常启动; 
2、如果发现已经有例程在运行,则把那个启动的历程show出来,并向那个启动的例程传递一个参数。


program入口项目不要任何其他DD,就是exe的入口

program调用facade.getInstance()单例获得facade项目下的facade类对象
facade.show()

show()方法有你控制你要显示的窗体,如果发现已经有例程在运行,则把那个启动的历程show出来,用 事件委托向那个启动的例程传递一个参数。

#2


在启动的时候,判断是否有程序实例在运行,有就show()一下,然后向程序对象传递参数。
帮楼主顶一下。

#3


能不能说具体一点呢……不是很明白你讲的。

#4


下贴3楼的代码,利用命名事件来发现第一个进程,并通过注册表来传递简单的参数给第一个进程: 
如何操作我的程序的另一个实例(进程)?

#5


防止多个进程运行可以用互斥体.
至于进程的通信...
可以重载WndProc后发消息.
也可以用管道.

#6


可以重载WndProc后发消息. 
具体怎么实现?

#7


static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if (System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName).Length > 1)
            {
                _MessageBox.ShowDiaLog(null,"已经有此程序在运行了!",FormStartPosition.CenterScreen);
                Application.Exit();
                return;
            }
            Application.Run(new Form1());
        }

#8


引用 7 楼 yuehuolong 的回复:
static void Main() 
        { 
            Application.EnableVisualStyles(); 
            Application.SetCompatibleTextRenderingDefault(false); 
            if (System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName).Length > 1) 
            { 
                _MessageBox.ShowDiaLog(null,"已经有此程序在运行了!",FormStartPosition.CenterScre…

这个值解决了第一个问题呵
关键是参数传递问题

#9


引用 5 楼 ChrisAK 的回复:
防止多个进程运行可以用互斥体. 
至于进程的通信... 
可以重载WndProc后发消息. 
也可以用管道.

我的问题就是说怎么用重载WndProc,以及发送自己的消息?
谢谢你。

#10


Program.cs里
  /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] arg)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            System.Diagnostics.Process[] _Process = System.Diagnostics.Process.GetProcessesByName("WindowsApplication1");
            for(int i=0;i!=_Process.Length;i++)
            {
                IntPtr _Text = System.Runtime.InteropServices.Marshal.StringToBSTR("中哦");
                Zgke.SysInfo.WindowsAPI.Win32API.SendMessage(_Process[i].MainWindowHandle, 500, 500, _Text);
            }
            Application.Run(new Form1());
            
        }


Form1里加

 private ControlMsg _Msg = new ControlMsg();
        private void Form1_Load(object sender, EventArgs e)
        {           
            _Msg.LoadMessage += new ControlMsg.Msg(_Msg_LoadMessage);
            _Msg.AssignHandle(this.Handle);
        }

        void _Msg_LoadMessage(ref Message p_Message, ref bool p_Run)
        {
            if (p_Message.Msg == 500)
            {
                this.Text = p_Message.WParam.ToInt32().ToString() + "_" + p_Message.LParam.ToInt32().ToString();
                string _Value=System.Runtime.InteropServices.Marshal.PtrToStringBSTR(p_Message.LParam);
                this.Text = _Value;
                p_Run = false;
            }
        }
        public class ControlMsg : NativeWindow
        {
            public delegate void Msg(ref Message p_Message, ref bool p_Run);
            public event Msg LoadMessage;

            protected override void WndProc(ref Message m)
            {
                bool p_Run = true;
                if (LoadMessage != null) LoadMessage(ref m, ref p_Run);
                if (p_Run) base.WndProc(ref m);
            }
        }     
      

#11


API声明放到Program.cs里...少给你了


[DllImport("user32.dll", CharSet = CharSet.Auto)]
        static public extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

#12


互斥最简单


using System.Threading;
            try
            {
                bool ret;
                System.Threading.Mutex mutex = new System.Threading.Mutex(true, Application.ProductName, out ret);
                if (ret)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    System.Windows.Forms.Application.Run(new FrmMain());
                    mutex.ReleaseMutex();
                }
                else
                {
                    MessageBox.Show(null, "请不要同时运行多个本程序。\n这个程序即将退出。", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    //   提示信息,可以删除。   
                    Application.Exit();//退出程序   
                }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.StackTrace);

            }
//这是我一个工程Program.cs里的代码,看一眼你就明白了.



System.Diagnostics.Process.Start(@"XXXX\\XXXX.exe", "-window");//后面的就是参数

#13


引用 9 楼 liudanking 的回复:
引用 5 楼 ChrisAK 的回复:
防止多个进程运行可以用互斥体. 
至于进程的通信... 
可以重载WndProc后发消息. 
也可以用管道. 
 
我的问题就是说怎么用重载WndProc,以及发送自己的消息? 
谢谢你。
重载WndProc很简单.
你做一个WinForm程序的时候vs都会自动从Form派生出一个
窗体类.在这个类里重载就行了;说白了就是在类里加一条函数:
protected override void WndProc(
ref Message m
){
}
这样就能处理自己的消息.
至于发消息...
参考楼上的声明,直接用SendMessage.
不过进程间的消息有个缺点就是你只能发
整型数据,而字符串之类的不能发.因为毕竟是在不同的进程控件.
所以如果要传送复杂参数的话首选的还是管道.
或者.net Remoting也不错.

#14


囧.
说错了.
如果是自己做的程序的SendMessage也可以
发一个字节缓冲区,只要使用WM_COPYDATA消
息即可,Windows系统会保证将缓冲区的数据复
制到对方的进程地址空间.

#15


有没有正确的答案啊