I think the NativeWindow class may be able to help you run a simple message
loop without any UI. Here's some quick code I threw together in LINQPad as a
proof of concept.
void Main()
{
var w = new MyWin();
w.CreateHandle(new CreateParams());
Thread.Sleep(5000);
w.DestroyHandle();
}
// Define other methods and classes here
class MyWin : NativeWindow
{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand,
Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
// Listen for operating system messages
m.Dump();
base.WndProc(ref m);
}
}
ciao, Richard
On Fri, Oct 15, 2010 at 12:34 PM, Matt Siebert <[email protected]> wrote:
> Bugger. As I suspected the original call from the client is blocked so
> re-entrant callbacks from the service can't run on that thread.
>
> Form.ShowDialog() seems to be the simplest option, but I'd really like it
> to be hidden from the user. I understand that this means I'll have to take
> care to ensure it doesn't block the native app indefinitely if something
> goes wrong, and I'm confident I can handle this reliably.
>
> Has anyone got any tips for hiding such a form? So far I've just got
> this...
>
> form.ShowInTaskbar = false;
>
>
> form.StartPosition = FormStartPosition.Manual;
> form.Left = -form.Width;
> form.Top = -form.Height;
>
> Seems to work quite well, but if the user is smart enough they can move it
> onto the screen. Handling the Form.Move event and resetting the form's
> position there seems to work but you get an annoying flickering ghost form
> if you try to move it around.
>
> Another idea is to show a little form (locked?) in front of the native
> app's main window with some kind of animation or something...
>
>
> On Fri, Oct 15, 2010 at 10:15 AM, Matt Siebert <[email protected]>wrote:
>
>> Yes, I need to block the thread. Once control has returned to the native
>> app my add-in can no longer talk to its API, until the native app calls it
>> again.
>>
>> The WCF service would actually be started when the native app starts up.
>> The native app gives add-ins a chance to startup and shutdown, and calls
>> commands exposed by an add-in when the user initiates it. The service and
>> client need to interact within the scope of a command being executed.
>>
>> I'm thinking I might be better off making the add-in the client and host
>> the service in the other process. The client will need to implement a
>> callback contract and support re-entrant calls, and these would need to be
>> handled on the originating thread (not sure if that is possible). I'm about
>> to give this a go...
>>
>>
>> On Fri, Oct 15, 2010 at 9:41 AM, Bill McCarthy <[email protected]>wrote:
>>
>>> Hi Matt,
>>>
>>> Are you sure you need to block the thread ? As in what happens if in the
>>> managed add-in you store the context when the method is first called then
>>> spin off a new thread, and finally invoke back on the original context ?
>>> If
>>> you can't do that, then a modal form sounds like a good idea to me
>>> because
>>> if you are blocking the native app, then you should provide a cancel
>>> button
>>> etc.
>>>
>>>
>>> |-----Original Message-----
>>> |From: [email protected] [mailto:ozdotnet-
>>> |[email protected]] On Behalf Of Matt Siebert
>>> |Sent: Friday, 15 October 2010 1:44 AM
>>> |To: ozDotNet
>>> |Subject: Message Loops
>>> |
>>> |G'day folks,
>>> |
>>> |Aside from Application.Run() and Form.ShowDialog(), are there any other
>>> ways
>>> |to run a message loop in a .NET app? I'm not keen on rolling my own
>>> message
>>> |loop, I'm just wondering if there are other options already available.
>>> |
>>> |Why do I want to do this? Well I'm developing an add-in for a native
>>> app
>>> that
>>> |hosts .NET (3.5). The native app calls a method exposed by the add-in
>>> which is
>>> |then free to do whatever it needs to do before returning control to the
>>> native
>>> |app. One caveat is that the add-in can only talk to the native app's
>>> API
>>> on the
>>> |thread that invoked it, attempting to do so on another thread is
>>> unstable
>>> at
>>> |best.
>>> |
>>> |In my add-in I want to host a WCF service for a client running in
>>> another
>>> |process. The service needs to be able to talk to the API so I'd rather
>>> not
>>> host it
>>> |on another thread. The problem is that I need to prevent my add-in from
>>> |returning control to the native app before the client has finished with
>>> the
>>> |service. I've looked at Application.Run(Form) and
>>> |Application.Run(ApplicationContext) but the native app immediately
>>> resumes
>>> |when these are called, then when the add-in eventually returns the
>>> native
>>> app
>>> |blows up.
>>> |
>>> |Form.ShowDialog() seems to be the only option that works, but I'm not
>>> keen
>>> on
>>> |showing a form whose sole purpose is to block execution until the client
>>> is
>>> |finished with the service.
>>> |
>>> |Thanks,
>>> |Matt.
>>>
>>>
>>
>