<p>So, I did search google and SO prior to asking this question. Basically I have a DLL that has a form compiled into it. The form will be used to display information to the screen. Eventually it will be asynchronous and expose a lot of customization in the dll. For now I just want it to display properly. The problem that I am having is that I use the dll by loading it in a Powershell session. So when I try to display the form and get it to come to the top and have focus, It has no problem with displaying over all the other apps, but I can't for the life of me get it to display over the Powershell window. Here is the code that I am currently using to try and get it to display. I am sure that the majority of it won't be required once I figure it out, this just represents all the things that I found via google.</p>

<pre><code>CLass Blah
{
        [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
        public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, uint pvParam, uint fWinIni);

        [DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("User32.dll", EntryPoint = "ShowWindowAsync")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
        private const int WS_SHOWNORMAL = 1;

    public void ShowMessage(string msg)
    {
            MessageForm msgFrm = new MessageForm();
            msgFrm.lblMessage.Text = "FOO";
            msgFrm.ShowDialog();
            msgFrm.BringToFront();
            msgFrm.TopMost = true;
            msgFrm.Activate();

            SystemParametersInfo((uint)0x2001, 0, 0, 0x0002 | 0x0001);
            ShowWindowAsync(msgFrm.Handle, WS_SHOWNORMAL);
            SetForegroundWindow(msgFrm.Handle);
            SystemParametersInfo((uint)0x2001, 200000, 200000, 0x0002 | 0x0001);
    }
}
</code></pre>

<p>As I say I'm sure that most of that is either not needed or even flat out wrong, I just wanted to show the things that I had tried. Also, as I mentioned, I plan to have this be asynchronously displayed at some point which I suspect will wind up requiring a separate thread. Would splitting the form out into it's own thread make it easier to cause it to get focus over the Powershell session? </p>

<hr>

<p>@Joel, thanks for the info. Here is what I tried based on your suggestion:</p>

<pre><code>msgFrm.ShowDialog();
msgFrm.BringToFront();
msgFrm.Focus();
Application.DoEvents();
</code></pre>

<p>The form still comes up <em>under</em> the Powershell session. I'll proceed with working out the threading. I've spawned threads before but never where the parent thread needed to talk to the child thread, so we'll see how it goes.</p>

<p>Thnks for all the ideas so far folks.</p>

<hr>

<p>Ok, threading it took care of the problem. @Quarrelsome, I did try both of those. Neither (nor both together) worked. I am curious as to what is evil about using threading? I am not using Application.Run and I have yet to have a problem. I am using a mediator class that both the parent thread and the child thread have access to. In that object I am using a ReaderWriterLock to lock one property that represents the message that I want displayed on the form that the child thread creates. The parent locks the property then writes what should be displayed. The child thread locks the property and reads what it should change the label on the form to. The child has to do this on a polling interval (I default it to 500ms) which I'm not real happy about, but I could not find an event driven way to let the child thread know that the proerty had changed, so I'm stuck with polling.</p>

[{'answer_id': 46092, 'author': 'Dean Hill', 'author_id': 3106, 'author_profile': 'https://Stackoverflow.com/users/3106', 'pm_score': 5, 'selected': True, 'text': '<p>I also had trouble activating and bringing a window to the foreground. Here is the code that eventually worked for me. I\'m not sure if it will solve your problem.</p>\n\n<p>Basically, call ShowWindow() then SetForegroundWindow().</p>\n\n<pre><code>using System.Diagnostics;\nusing System.Runtime.InteropServices;\n\n// Sets the window to be foreground\n[DllImport("User32")]\nprivate static extern int SetForegroundWindow(IntPtr hwnd);\n\n// Activate or minimize a window\n[DllImportAttribute("User32.DLL")]\nprivate static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);\nprivate const int SW_SHOW = 5;\nprivate const int SW_MINIMIZE = 6;\nprivate const int SW_RESTORE = 9;\n\nprivate void ActivateApplication(string briefAppName)\n{\n    Process[] procList = Process.GetProcessesByName(briefAppName);\n\n    if (procList.Length &gt; 0)\n    {\n        ShowWindow(procList[0].MainWindowHandle, SW_RESTORE);\n        SetForegroundWindow(procList[0].MainWindowHandle);\n    }\n}\n</code></pre>\n'}, {'answer_id': 46187, 'author': 'Joel Coehoorn', 'author_id': 3043, 'author_profile': 'https://Stackoverflow.com/users/3043', 'pm_score': 0, 'selected': False, 'text': "<p>You shouldn't need to import any win32 functions for this.  If .Focus() isn't enough the form should also have a .BringToFront() method you can use.  If that fails, you can set it's .TopMost property to true.  You don't want to <em>leave</em> it true forever, so then call Application.DoEvents so the form can process that message and set it back to false.</p>\n"}, {'answer_id': 46467, 'author': 'sieben', 'author_id': 1147, 'author_profile': 'https://Stackoverflow.com/users/1147', 'pm_score': 2, 'selected': False, 'text': "<p>Doesn't <strong>ShowDialog()</strong> have different window behavior than just <strong>Show()</strong>?</p>\n\n<p>What if you tried:</p>\n\n<pre><code>msgFrm.Show();\nmsgFrm.BringToFront();\nmsgFrm.Focus();\n</code></pre>\n"}, {'answer_id': 46470, 'author': 'Quibblesome', 'author_id': 1143, 'author_profile': 'https://Stackoverflow.com/users/1143', 'pm_score': 2, 'selected': False, 'text': "<p>TopMost = true;\n.Activate() ?</p>\n\n<p>Either of those any good?</p>\n\n<p>Splitting it out into its own thread is a bit evil as it wont work properly if you don't call it with Application.Run and that will swallow up the thread. In the worst case scenario I guess you could separate it out into a different process and communicate via the disk or WCF.</p>\n"}, {'answer_id': 94642, 'author': 'Kevin Gale', 'author_id': 7176, 'author_profile': 'https://Stackoverflow.com/users/7176', 'pm_score': 4, 'selected': False, 'text': '<p>Here is some code that I\'ve used on one form or another for a few years. There are a few gotchas to making a window in another app pop up. Once you have the window handle do this:</p>\n\n<pre><code>      if (IsIconic(hWnd))\n        ShowWindowAsync(hWnd, SW_RESTORE);\n\n      ShowWindowAsync(hWnd, SW_SHOW);\n\n      SetForegroundWindow(hWnd);\n\n      // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm\n      // Converted to Delphi by Ray Lischner\n      // Published in The Delphi Magazine 55, page 16\n      // Converted to C# by Kevin Gale\n      IntPtr foregroundWindow = GetForegroundWindow();\n      IntPtr Dummy = IntPtr.Zero;\n\n      uint foregroundThreadId = GetWindowThreadProcessId(foregroundWindow, Dummy);\n      uint thisThreadId       = GetWindowThreadProcessId(hWnd, Dummy);\n\n      if (AttachThreadInput(thisThreadId, foregroundThreadId, true))\n      {\n        BringWindowToTop(hWnd); // IE 5.5 related hack\n        SetForegroundWindow(hWnd);\n        AttachThreadInput(thisThreadId, foregroundThreadId, false);\n      }\n\n      if (GetForegroundWindow() != hWnd)\n      {\n        // Code by Daniel P. Stasinski\n        // Converted to C# by Kevin Gale\n        IntPtr Timeout = IntPtr.Zero;\n        SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, Timeout, 0);\n        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Dummy, SPIF_SENDCHANGE);\n        BringWindowToTop(hWnd); // IE 5.5 related hack\n        SetForegroundWindow(hWnd);\n        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Timeout, SPIF_SENDCHANGE);\n      }\n</code></pre>\n\n<p>I won\'t post the whole unit since since it does other things that aren\'t relevant\nbut here are the constants and imports for the above code. </p>\n\n<pre><code>//Win32 API calls necesary to raise an unowned processs main window\n\n[DllImport("user32.dll")]\n\nprivate static extern bool SetForegroundWindow(IntPtr hWnd);\n[DllImport("user32.dll")]\nprivate static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);\n[DllImport("user32.dll")]\nprivate static extern bool IsIconic(IntPtr hWnd);\n[DllImport("user32.dll", SetLastError = true)]\nprivate static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);\n[DllImport("user32.dll", SetLastError = true)]\nprivate static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId);\n[DllImport("user32.dll")]\nprivate static extern IntPtr GetForegroundWindow();\n[DllImport("user32.dll")]\nprivate static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);\n[DllImport("user32.dll")]\nstatic extern bool BringWindowToTop(IntPtr hWnd);\n\n[DllImport("user32.dll")] \nprivate static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, Int32 nMaxCount);\n[DllImport("user32.dll")]\nprivate static extern int GetWindowThreadProcessId(IntPtr hWnd, ref Int32 lpdwProcessId);\n[DllImport("User32.dll")]\npublic static extern IntPtr GetParent(IntPtr hWnd); \n\nprivate const int SW_HIDE = 0;\nprivate const int SW_SHOWNORMAL = 1;\nprivate const int SW_NORMAL = 1;\nprivate const int SW_SHOWMINIMIZED = 2;\nprivate const int SW_SHOWMAXIMIZED = 3;\nprivate const int SW_MAXIMIZE = 3;\nprivate const int SW_SHOWNOACTIVATE = 4;\nprivate const int SW_SHOW = 5;\nprivate const int SW_MINIMIZE = 6;\nprivate const int SW_SHOWMINNOACTIVE = 7;\nprivate const int SW_SHOWNA = 8;\nprivate const int SW_RESTORE = 9;\nprivate const int SW_SHOWDEFAULT = 10;\nprivate const int SW_MAX = 10;\n\nprivate const uint SPI_GETFOREGROUNDLOCKTIMEOUT = 0x2000;\nprivate const uint SPI_SETFOREGROUNDLOCKTIMEOUT = 0x2001;\nprivate const int  SPIF_SENDCHANGE = 0x2;\n</code></pre>\n'}, {'answer_id': 155351, 'author': 'jyoung', 'author_id': 14841, 'author_profile': 'https://Stackoverflow.com/users/14841', 'pm_score': 0, 'selected': False, 'text': "<p>Don't you just want the dialog to be a child of the calling form?</p>\n\n<p>To do that you'll need the pass in the calling window and \nuse the ShowDialog( IWin32Window owner ) method.</p>\n"}, {'answer_id': 438971, 'author': 'Milan Gardian', 'author_id': 23843, 'author_profile': 'https://Stackoverflow.com/users/23843', 'pm_score': 2, 'selected': False, 'text': '<p>The following solution should meet your requirements:</p>\n\n<ol>\n<li>Assembly can be loaded into PowerShell and main class instantiated</li>\n<li>When ShowMessage method on this instance is called, a new window is shown and activated</li>\n<li>If you call ShowMessage multiple times, this same window updates its title text and is activated</li>\n<li>To stop using the window, call Dispose method</li>\n</ol>\n\n<p><strong>Step 1</strong>: Let\'s create a temporary working directory (you can naturally use your own dir)</p>\n\n<pre><code>(powershell.exe)\nmkdir C:\\TEMP\\PshWindow\ncd C:\\TEMP\\PshWindow\n</code></pre>\n\n<p><strong>Step 2</strong>: Now let\'s define class that we will be interacting with in PowerShell:</p>\n\n<pre><code>// file \'InfoProvider.cs\' in C:\\TEMP\\PshWindow\nusing System;\nusing System.Threading;\nusing System.Windows.Forms;\n\nnamespace PshWindow\n{\n    public sealed class InfoProvider : IDisposable\n    {\n        public void Dispose()\n        {\n            GC.SuppressFinalize(this);\n            lock (this._sync)\n            {\n                if (!this._disposed)\n                {\n                    this._disposed = true;\n                    if (null != this._worker)\n                    {\n                        if (null != this._form)\n                        {\n                            this._form.Invoke(new Action(() =&gt; this._form.Close()));\n                        }\n                        this._worker.Join();\n                        this._form = null;\n                        this._worker = null;\n                    }\n                }\n            }\n        }\n\n        public void ShowMessage(string msg)\n        {\n            lock (this._sync)\n            {\n                // make sure worker is up and running\n                if (this._disposed) { throw new ObjectDisposedException("InfoProvider"); }\n                if (null == this._worker)\n                {\n                    this._worker = new Thread(() =&gt; (this._form = new MyForm(this._sync)).ShowDialog()) { IsBackground = true };\n                    this._worker.Start();\n                    while (this._form == null || !this._form.Created)\n                    {\n                        Monitor.Wait(this._sync);\n                    }\n                }\n\n                // update the text\n                this._form.Invoke(new Action(delegate\n                {\n                    this._form.Text = msg;\n                    this._form.Activate();\n                }));\n            }\n        }\n\n        private bool _disposed;\n        private Form _form;\n        private Thread _worker;\n        private readonly object _sync = new object();\n    }\n}\n</code></pre>\n\n<p>As well as the Form that will be shown:</p>\n\n<pre><code>// file \'MyForm.cs\' in C:\\TEMP\\PshWindow\nusing System;\nusing System.Drawing;\nusing System.Threading;\nusing System.Windows.Forms;\n\nnamespace PshWindow\n{\n    internal sealed class MyForm : Form\n    {\n        public MyForm(object sync)\n        {\n            this._sync = sync;\n            this.BackColor = Color.LightGreen;\n            this.Width = 200;\n            this.Height = 80;\n            this.FormBorderStyle = FormBorderStyle.SizableToolWindow;\n        }\n\n        protected override void OnShown(EventArgs e)\n        {\n            base.OnShown(e);\n            this.TopMost = true;\n\n            lock (this._sync)\n            {\n                Monitor.PulseAll(this._sync);\n            }\n        }\n\n        private readonly object _sync;\n    }\n}\n</code></pre>\n\n<p><strong>Step 3</strong>: Let\'s compile the assembly...</p>\n\n<pre><code>(powershell.exe)\ncsc /out:PshWindow.dll /target:library InfoProvider.cs MyForm.cs\n</code></pre>\n\n<p><strong>Step 4</strong>: ... and load the assembly in PowerShell to have fun with it:</p>\n\n<pre><code>(powershell.exe)\n[System.Reflection.Assembly]::LoadFile(\'C:\\TEMP\\PshWindow\\PshWindow.dll\')\n$a = New-Object PshWindow.InfoProvider\n$a.ShowMessage(\'Hello, world\')\n</code></pre>\n\n<p>A green-ish window with title \'Hello, world\' should now pop-up and be active. If you reactivate the PowerShell window and enter:</p>\n\n<pre><code>$a.ShowMessage(\'Stack overflow\')\n</code></pre>\n\n<p>The Window\'s title should change to \'Stack overflow\' and the window should be active again.</p>\n\n<p>To stop working with our window, dispose the object:</p>\n\n<pre><code>$a.Dispose()\n</code></pre>\n\n<p>This solution works as expected in both Windows XP SP3, x86 and Windows Vista SP1, x64. If there are question about how this solution works I can update this entry with detailed discussion. For now I\'m hoping the code if self-explanatory.</p>\n'}, {'answer_id': 717431, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 1, 'selected': False, 'text': "<p>Huge thanks people.<br>\nI think I've made it a bit shorter, here's what I put on a seperate thread and seems to be working ok.</p>\n\n<pre><code>private static void StatusChecking()\n{\n    IntPtr iActiveForm = IntPtr.Zero, iCurrentACtiveApp = IntPtr.Zero;\n    Int32 iMyProcID = Process.GetCurrentProcess().Id, iCurrentProcID = 0;\n    IntPtr iTmp = (IntPtr)1;\n\n    while (bIsRunning)\n    {\n        try\n        {\n            Thread.Sleep(45);\n            if (Form.ActiveForm != null)\n            {\n                iActiveForm = Form.ActiveForm.Handle;\n            }\n            iTmp = GetForegroundWindow();\n            if (iTmp == IntPtr.Zero) continue;\n            GetWindowThreadProcessId(iTmp, ref iCurrentProcID);\n            if (iCurrentProcID == 0)\n            {\n                iCurrentProcID = 1;\n                continue;\n            }\n            if (iCurrentProcID != iMyProcID)\n            {\n                SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, IntPtr.Zero, 0);\n                SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, IntPtr.Zero, SPIF_SENDCHANGE);\n                BringWindowToTop(iActiveForm);\n                SetForegroundWindow(iActiveForm);\n            }\n            else iActiveForm = iTmp;\n        }\n        catch (Exception ex)\n        {\n            Definitions.UnhandledExceptionHandler(ex, 103106);\n        }\n    }\n}\n</code></pre>\n\n<p>I don`t bother repasting the definitions...</p>\n"}]
['https://Stackoverflow.com/questions/46030', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1358/']