c#从另一个进程更新表单

时间:2017-10-04 14:20:28

标签: c# process

我需要从不是第一个启动的进程中访问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,只需更新最初创建的那个。 感谢

2 个答案:

答案 0 :(得分:0)

一种方法是使用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);
}

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

答案 1 :(得分:0)

我已经解决了MemoryMappedFile !!! 基本上 1)主进程创建文件; 2)在第一行文件中写入其他进程: (int32)length + buffer包含传递我的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表单部分: (在定期调用以进行更新的函数中) ...          //如果用户与新文件/ DIRECTORIES一起点击它们,则与新路径一起发送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;
                }
            }

...

非常感谢