[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

.NET Remoting with  Windows Forms

Posted on 2004-10-14
30
Medium Priority
?
570 Views
Last Modified: 2008-03-17
I have looked through various tutorials and figured out how to get one of them working.. made a little sample with the following setup:

1) Server (console app, with console.readline()  to keep the listener open)
2) Client (console app that calls the remote code)
3) Class library which is the remote vb.net  code.  


What I don't understand is how am I going to use Remoting to send a signal from my Windows Service to the system tray icon..(Windows form) ?    When the Service becomes active I want it to send a message to the desktop (System Tray) so that the System Tray can change its icon into an 'active' mode, or I will have alittle msn like window pop up.  

What I know:    put the server code in the system tray project,  client code in the Service.

What I need to know:   When the Client calls the Remote Code, how can I get this code (which is just a class library)  to pop up a window or do something as mentioned above?   I couldn't get the remote code to work any other way than just a class library, is there a way to have my entire form the remote code?  (I tried that but then couldn't reference it in the server because i can only reference .dll , and the .exe wasn't a proper format I guess).

Any help would be appreciated.  Thanks.



This is the code:


Class library ###########################################
Public Class SampleRemoter : Inherits MarshalByRefObject

    Public Function getUser() As String
        Return Environment.MachineName
    End Function

End Class
###################################################

Server###############################################

Class RemotingServer

    Shared Sub Main(ByVal args() As String)

        Console.WriteLine("Registering our remote object...")
        RemotingConfiguration.RegisterWellKnownServiceType(GetType(SampleRemoter), "SampleRemoter", WellKnownObjectMode.SingleCall)
        Console.WriteLine("Create and register a channel...")
        Dim ch As New TcpServerChannel(8080)
        ChannelServices.RegisterChannel(ch)
        Console.Read()

    End Sub

End Class

###################################################

Client ###############################################

    Shared Sub Main(ByVal args() As String)
        Try
            Console.WriteLine("Registering Channel...")
            Dim ch As New TcpClientChannel
            ChannelServices.RegisterChannel(ch)
            Console.WriteLine("Registering remote object in local domain...")
            RemotingConfiguration.RegisterWellKnownClientType(GetType(SampleRemoter), "tcp://localhost:8080/SampleRemoter")
            Console.WriteLine(" Create remote object and execute method")
            Dim sr As New SampleRemoter
            Dim username As String = sr.getUser()
            Console.WriteLine("Machine name of remote machine = " & username)
        Catch ex As Exception
            Console.WriteLine(ex.ToString())
        Finally
            Console.Read()
        End Try


###################################################

0
Comment
Question by:bswiftly
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 15
  • 11
  • 3
  • +1
30 Comments
 
LVL 4

Expert Comment

by:Jigit
ID: 12331485
bswiftly, you can use System.Windows.Forms.Timer object from your System Tray app and perform some checks in your internal file, or registry setting which are set by the Windows Service.

HTH,
Jigit
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12333220
there must be a better way.. I'm looking to be able to send events directly to it without having to poll a local file or registry.  
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12338936
Are these going to be on the same machine or separate machines?

Bob
0
Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

 
LVL 1

Author Comment

by:bswiftly
ID: 12339158
they are both on the same machine.  I have had some help outside this site and what I have been able to do is create a wrapper for my form class.  The wrapper inherits the MarshalByRefObject class and then calls the pop up to display.  The Remoting Server is the forms project with the NotifyIcon object.  

So in other words I have resolved this issue, but will still give points for someone who can give me a way to change the notifyIcon.   Is there a way to return a variable from the remote code to the remoting server and have the remoting server do something accordingly? (i see how this may not be possible due to potential security risks..)

0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12339221
Why are you using Remoting if the 2 applications are on the same machine?  That sounds like a lot of overhead to me.

Bob
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12339242
I have a Windows Service.  It can't have visual elements.  So I created a System tray app.. (NotifyIcon class)  that will be the controller for the Service.  This all works without remoting.

However,  when I want to have the service notify the desktop of its state, there is no way to do this other than remoting, or my own TCP/IP connectivity, or something that would incur more overhead is to have the system tray query a file every 5 seconds, as Jigit suggested.  

Do you have a  more efficient implementation of this that I could use?
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12339285
Does your System Tray application have a form?

Bob
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12339294
http://www.thinktecture.com/Resources/RemotingFAQ/RemotingUseCases.html

this is a good article to read on .NET Remoting.  The author, Ingo Rammer, has a few books published on .NET Remoting, and suggests that this is a good use of Remoting.
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12339306
Yes, my systray app does have a form.  It is currently invisible (I just created a windows forms app, not a console app, because originally to test the pop up window I used the form).   How do you suggest the windows service sends events to the systray app to have the form slide up?

0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12339368
I am thinking of a way to send a message, not through MSMQ, but through the normal Windows message (WndProc), as long as you can get a handle to the Window.

Bob
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12339446
But then how do I ensure where the message is coming from?  

I think that way would have just as much overhead as using Remoting?  After all, all remoting does is TCP commands.  The server just holds a reference to the memory allocation for the remote code..  In my trials the code is very quick and works well.

Ingo Rammer got back to me and said I should be able to use most Windows.Forms classes directly as Remote Hosts because most of them derive from MarshalByRefObject, however I haven't been able to import forms projects into my client, so this is not a possibility yet.

0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12339558
All very good points, so let's get back to the matter at hand.  

Would something like this work:

http://www.dotnet247.com/247reference/msgs/12/60499.aspx

Why would you use the "Invoke" method instead of the Remote
Asynchronous Programming Paradigm? What is the difference between the
two? Does the RemoteAsyncDelegate give you anything?

Their example in the MSDN is something like..

Dim RemoteCallback As New AsyncCallback(AddressOf Me.OurCallBack)
Dim RemoteDel As New RemoteAsyncDelegate(AddressOf obj.RemoteMethod)
Dim RemAr As IAsyncResult = RemoteDel.BeginInvoke(RemoteCallback,
Nothing)
RemAr.AsyncWaitHandle.WaitOne()

Bob
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12339577
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12339755
I'm not really sure.. I'm new to Remoting.. even found out about it while researching what I wanted to do here.

I found this quote at teh botton of the page where you got that code snippet off msdn:
"Note that if the client is a context-bound class that requires a synchronized context, the callback function is dispatched through the .NET remoting context infrastructure. "

So that offers some insight, although I'm not sure how much sense I can make of it... not sure what a context bound class is or if what I have IS one?


I'm not sure how to implement this remotecallback .. how would that interact ?  Have you actually used this before?
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12339809
Do you have Ingo Rammer's .NET Remoting book?

Bob
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12339819
No I don't, there is a new version that we might pick up, but isn't available yet.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12339829
I have it on the shelf, so I thought a good reference in the book might help.  I don't do remoting very much, so the specifics escape me.

Bob
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12339833
Maybe I will email Ingo the link to this article and see if he has time to reply :)
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12339839
Now that would be the best solution.  Get it right from the real Remoting expert :)

Bob
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12339885
If you find some specifics on this, I would be very interested.

Bob
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12339897
I have emailed him and he will either reply here or I will post his email reply for him.   I think its bedtime in Austria so we may have to wait till tomorrow.
0
 
LVL 1

Accepted Solution

by:
rammeri earned 500 total points
ID: 12340061
Bedtime? It's around 7pm here ... we're just starting, right? ;-)

Bob: Thanks! Great to hear that you like the book!

Re your Qs: Remoting of events is always a little bit cumbersome. In this case, however it might make perfect sense as you are running client and server on the same machine. (Just make sure that rejectRemoteRequest is set to "true" in the server side config ... else everybody on your network can connect to your service!) Of course you could also implement your service as a COM+ EnterpriseService with RunAsService=true ... but that's a completely different story ;-). If you are not familiar with E/S or COM+, this will be harder.

You should be able to either use an AsyncCallback (but you'd have to define it as a public Event in the server side class) *or* you can use any other delegate/event.

BUT: There's a drawback. You have to pass the events through a shim layer, as otherwise, the server would need to have the client-side EXE available in its directory. (You can see an example of this at http://www.ingorammer.com/Book/EventsEnhanced.zip). In addition, starting with version 1.1 of the .NET Framework, you will have to specify typeFilterLevel="full" as illustrated at http://www.thinktecture.com/Resources/RemotingFAQ/Changes2003.html.

I hope this is enough to get you started.

BTW: The second edition is not yet available. I've today sent in the drafts of the final chapters. We only have to finish work ont he new "reference" section/appendixes. I guess we'll work on this section for about a week or two. After this, there are several review cycles so that it might still take two or three months before the book hits the stores. (Printing and distribution alone takes about 2-4 weeks ... paper is slow ;-))

-Ingo
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12341798
well i've been hacking away at this all day.. can't seem to get it working.  Ingo, I haven't actually looked at your code above, I'm still trying to just get the popup window working from my windows service.  I had it working from a test application, but when i  put the client in the windows service I can't see the remote code being run.. I have a method that writes to the eventlog and I am using that to place checkpoints as I run it.. (debugging is a pain!)

I'm wondering if there is an easy way of debugging the remote code file?

Or is this realising its being called from a windows service and therefore not allowing a visual element to be displayed?
0
 
LVL 1

Expert Comment

by:rammeri
ID: 12341869
For debugging, you have to first simply start your Windows Service using Service Control Manager. In VS.NET you can then select Debug->Attach and select the EXE of your windows service. This attaches the VS.NET debugger to the running instance of your Windows Service. Afterwards, you can use breakpoints, etc. just as if it were a "regular" application.

(BTW: I'll be travelling for the next few days an won't be able to respond to this thread. If you didn't find a solution by Saturday, just email me your code and I'll have a look at it)

In general: I would design the Windows Service as your Remoting server and the systray app as a client.

Cheers,
-Ingo
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12342204
I know how to debug windows services.. its the remote code library that I am having probs with.

Why would you have the remoting server on the windows service?  That kind of defeats the purpose of what I'm trying to do doesn't it?  The whole issue with this is to create a form pop up when something happens with the windows service.. I can't have visual elements in the windows service so i thought of using remoting to notify the systray application and have it (or now the remote code) display the popup.

0
 
LVL 1

Expert Comment

by:rammeri
ID: 12342279
Sorry - I routinely meet developers who don't know how to debug a Svc ... ;-)

Re client/server: Simply because more than one listener could be active. For example with Windows XP "Fast User Switching" or Terminal Services. In this case, it's better if you allow multiple clients to receive notifications from one server. (i.e. subscribe the client to an event of the Windows Service)

-Ingo
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12463007
Hey, thanks for your help.. haven't tried implementing your "shim layer" to get notifications directly to  the systray Icon, but I do now have a little popup working.  Systray as the remoting host and Win. Service as the client... it works great!  I might be able to find some time to try that shim layer thing soon, so I'll keep this question open for now in case I have other questions.  

ps. If you have an email list for notifications of when your new book is printed and shipped, feel free to put me on it :)
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12463086
Me too :)

Bob
0
 
LVL 1

Author Comment

by:bswiftly
ID: 12486004
Well I have a working sample, converted it to VB (unfortunately we use VB), and implemented it in windows forms.  Didn't use the Client listener app or code to implement that in the server because I will not need this for the systray Icon.

One interesting thing, is that the config file is case sensitive even in VB!  A second is that VB automatically gives you a namespace in the properties window that doesn't appear in the code.. so when you specify Namespace Server.. in your code.. it is redundant..  (dumb VB!)

One problem that I did have however, which will be the last problem hopefully.. in order to get this Systray working with the features I want, is that I want to be able to manipulate the context menu and displayed image of the icon, when specific events are received from the Windows service.  Because I can't inherit more than one interface, my remote code has to be in a separate class from the Form code (Systray icon).  I have tested to see if I could make a shared (static) label, and set that label from the other class but this didn't work.  

How would I do this... anyone?

0
 
LVL 1

Author Comment

by:bswiftly
ID: 12487687
nevermind.. i'm guessing that is what the EventListener part of the code is for..   will have to implement that now to test it!
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IP addresses can be stored in a database in any of several ways.  These ways may vary based on the volume of the data.  I was dealing with quite a large amount of data for user authentication purpose, and needed a way to minimize the storage.   …
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question