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