【问题标题】:c# update form from another processc# 从另一个进程更新表单
【发布时间】:2017-10-04 14:20:27
【问题描述】:

我需要从不是第一个启动的进程中访问 GUI FORM 的完整属性和方法。

   [MTAThread]
    static void Main(string[] args)
    {

        //check if the app is already running
        running = Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location)).Length > 1;
        Console.WriteLine("ALready running? " + running);

        if (running) // not first process
        {

            MessageBox.Show("Application already running in background!!!");
            closing = false;

            // HERE I NEED TO ACCESS TO gui-form defined by the first process and call some methods, modify properties ...
        }
        else { //first process
            if (!closing)// there are no process active
            {
                string selected = null;

                if (args.Length == 1) //apertura da context menu
                {
                    selected = args[0];
                    pathSend = selected;
                }
                Console.WriteLine("ALready running: opening " + pathSend);
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);

                //create userManagerUnit
                umu = new UserManagerUnit();

                //create a ManualResetEvent used from Server's Threads
                // true -> server start work  ||  false -> server stop work
                mre = new ManualResetEvent(true);

                // create Server istance
                //  active server
                server = new Server();
                serverThread = new Thread(server.EntryPoint) { Name = "serverThread" };
                serverThread.IsBackground = true;
                serverThread.Start();

                //create new client
                client = new Client();

                // create gui istance
                gui = new GUI(selected);

                //run application
                Application.Run(gui);


            }
        }    
    }

我尝试过委托,但我无法委托存在于另一个进程中的某些内容。 我的应用程序是从 .exe/右键菜单(在文件/目录上)启动的 所以我可以启动它 N 次,每次我需要用不同的参数重新加载我的 gui,但我不需要创建 N gui,只需更新第一次创建的那个。 谢谢

【问题讨论】:

标签: c# process


【解决方案1】:

一种方法是使用 Windows 消息。像这样的:

[DllImport("user32.dll")]
static extern uint RegisterWindowMessage(string lpString);

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

private uint msgId = RegisterWindowMessage("notification");

// Transmitter
private void button1_Click(object sender, EventArgs e)
{
    Process[] myInstances = Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location));

    if (myInstances.Length == 0) return;

    foreach (Process instance in myInstances)
    {
        IntPtr handle = instance.MainWindowHandle;
        SendMessage(handle, (int)msgId, IntPtr.Zero, IntPtr.Zero);
    }            
}

// Receiver
protected override void WndProc(ref Message msg)
{
    if (msg.Msg == msgId) MessageBox.Show("well, notification is here now.");
    base.WndProc(ref msg);
}

这会向应用程序的所有实例发送“通知”消息,包括它自己。

【讨论】:

    【解决方案2】:

    我已经用 MemoryMappedFile 解决了!!! 基本上 1)主进程创建文件; 2)其他进程写入文件的第一行: (int32)length + 包含要传递我的 gui 的标签的缓冲区 3)在gui中我从内存映射文件中读取并检索要更新的标签

        [MTAThread]
        static void Main(string[] args)
        {
    
            //check if the app is already running
            running = Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location)).Length > 1;
            Console.WriteLine("ALready running? " + running);
    
            if (running)
            {
    
                string selected = null;
    
                if (args.Length == 1) //apertura da context menu
                {
                    selected = args[0];
                    pathSend = selected;
                }
                // open the memory-mapped 
                MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("myMappedFile");
                // declare accessor to write on file
                MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor();
                if (selected != null)
                {
                    //write in the file: Length|Path
                    //4 offset cause length is on 32 bit
                    byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(selected);
                    accessor.Write(0, Buffer.Length);
                    accessor.Flush();
                    accessor.WriteArray(4, Buffer, 0, Buffer.Length);
                    accessor.Flush();
                    //write path in the memory mapped file
                }
                else
                {
                    //write in the file: Lenght|Path
                    accessor.Write(0, 0);
                }
    
                //MessageBox.Show("Application already running in background!!!");
                closing = false;
    
            }
            else {
                if (!closing)// there are no process active
                {
                    // create a memory-mapped file of length 1000 bytes and give it a 'map name' of 'test'
                    MemoryMappedFile mmf = MemoryMappedFile.CreateNew("myMappedFile", 1000);
    
                    string selected = null;
    
                    if (args.Length == 1) //apertura da context menu
                    {
                        selected = args[0];
                        pathSend = selected;
                    }
                    Console.WriteLine("ALready running: opening " + pathSend);
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
    
                    //create userManagerUnit
                    umu = new UserManagerUnit();
    
                    //create a ManualResetEvent used from Server's Threads
                    // true -> server start work  ||  false -> server stop work
                    mre = new ManualResetEvent(true);
    
                    // create Server istance
                    //  active server
                    server = new Server();
                    serverThread = new Thread(server.EntryPoint) { Name =   "serverThread" };
                    serverThread.IsBackground = true;
                    serverThread.Start();
    
                    //create new client
                    client = new Client();
    
                    // create gui istance
                    gui = new GUI(selected);
    
                    //run application
                    Application.Run(gui);
    
    
                }
            }    
        }
    

    .... GUI 表单部分: (在定期调用更新的函数中) ... //如果用户通过右键单击与新文件/目录交互,则使用新路径发送 GUI //....

                // read the integer value at position 500
                MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor();
                int l = accessor.ReadInt32(0);
                accessor.Flush();
                // print it to the console
                //Console.WriteLine("The memory mapped value is {0}", l);
                if (l != 0)
                {
                    //get path as bytes
                    byte[] Buffer = new byte[l];
                    accessor.ReadArray(4, Buffer, 0, Buffer.Length);
                    accessor.Flush();
                    //convert bytes to string
                    string newPath = ASCIIEncoding.ASCII.GetString(Buffer);
                   // Console.WriteLine("The newPath is " + newPath);
    
                    if (newPath.CompareTo(LANSharingApp.pathSend) != 0)// it's a new path
                    {
                        LANSharingApp.pathSend = newPath;
                        this.pathBox.Text = newPath;
                        LANSharingApp.umu.clearMetroButtons();
                        base.SetVisibleCore(true);
                        this.WindowState = FormWindowState.Normal;
                    }
                }
    

    ....

    非常感谢

    【讨论】:

      猜你喜欢
      • 2011-08-12
      • 2013-07-10
      • 2012-06-08
      • 1970-01-01
      • 1970-01-01
      • 2015-10-30
      • 1970-01-01
      • 2012-04-27
      • 1970-01-01
      相关资源
      最近更新 更多