Reputation: 963
I am creating app domain in my winform application using this code in program.cs file
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
[STAThread]
static void Main(string[] args)
{
string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
// unique id for global mutex - Global prefix means it is global to the machine
string mutexId = string.Format("Global\\{{{0}}}", appGuid);
using (var mutex = new Mutex(false, mutexId))
{
var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(allowEveryoneRule);
mutex.SetAccessControl(securitySettings);
if (mutex.WaitOne(TimeSpan.Zero, true) || (args.Length > 0 && string.Compare(args[0], "secondary", true) == 0))
{
ErrorHandler errorHandler = new ErrorHandler();
DffEnvironment.Default.AppErrorHandler = errorHandler;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(errorHandler.Application_ErrorHandler);
MainForm mainForm = new MainForm();
DffEnvironment.Default.MainForm = mainForm;
if (args.Length > 0)
{
MessageBox.Show(" CurrentDomain" + AppDomain.CurrentDomain.FriendlyName);
}
Application.Run(mainForm);
}
else
{
// send our Win32 message to make the currently running instance
// Add new app domain
NativeMethods.PostMessage(
(IntPtr)NativeMethods.HWND_BROADCAST,
NativeMethods.WM_SHOWME,
IntPtr.Zero,
IntPtr.Zero);
}
}
}
}
and in my MainForm (Form) I override the code WndProc method and wrote this
static int procNumber=0;
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg == NativeMethods.WM_SHOWME)
{
try
{
procNumber++;
AppDomain appDomain = AppDomain.CreateDomain("MyAppDomainApplication" + procNumber.ToString(), null, setupInfo);
string[] arguments = { "secondary" };
appDomain.ExecuteAssembly("MyAppDomainApplication.exe", null, arguments);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
base.WndProc(ref m);
}
It is working fine, it creates another app domain in the same process already running when I try to open my application.
My first question is can I create app domain of the same process in already running from other user, for example
John is working on this app and having two app domains and one process. And Steve logged in on the same machine and tried to open this application and application should not create process and it should add new app domain in already running process by John.
I detected the process running in another user by prefixing the name of the mutex with "Global\". as mentioned here
and second question is here when I edit the following code in program.cs
NativeMethods.PostMessage(
(IntPtr)NativeMethods.HWND_BROADCAST,
NativeMethods.WM_SHOWME,
IntPtr.Zero,
IntPtr.Zero);
to
try
{
procNumber++;
AppDomain appDomain = AppDomain.CreateDomain("MyAppDomainApplication" + procNumber.ToString(), null, setupInfo);
string[] arguments = { "secondary" };
appDomain.ExecuteAssembly("MyAppDomainApplication.exe", null, arguments);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
It creates another process why it is not working in Program.cs file, why should I have to send message to my Form and do the same thing in WndProc method
Upvotes: 1
Views: 4245
Reputation: 3419
I'll answer to your second question.
Application domains are isolated environments inside process. Here you have two processes and they both have their own application domains. You must send a message from one process to another if you want to command the other process to create a new application domain. That is why you have to send the message.
I also suspect that the code does not work in the way you have intended. The ExecuteAssembly() is run in the same thread as the main user interface. If the executed assembly begins a new message loop, your call stack will grow after every WM_SHOWME message and you will eventually get stack overflow exception.
In that case your call stack will look more or less like this:
at Application.Run()
at Main()
at AppDomain.ExecuteAssembly()
...
at Application.Run()
at Main()
at AppDomain.ExecuteAssembly()
at Application.Run()
at Main()
Upvotes: 1