|
Yes, I have admin rights to my local computer and to my domain.
That should not matter, or using NotifyIcon would be useless, since not everyone has admin access when they are in a comapny.
My .NET security settings are at what ever the default is when you install, and what ever SP2 may have updated them to.
|
|
|
|
|
Joel, are you using the latest .NET Framework with SP2? Is your VS.NET the latest version? or are you still working with the beta VS?
Did you upgrade from Beta to Release? Or did you completely remove the beta, before install the release?
Everything I have is latest versions, and patches, on XP Pro. This error seems more like the java Serurity where you have a sercurity properties file that can loosen or tighten the internal security. .NET has a similar thing, and this seems to be related. Your code is trying to do something in violation of the .NET security policy which are currently set to default settings. I have never had the Beta software for .NET Framework or VS.NET on this computer. I wonder if MS made security changes when they released, and if you upgrade they do not implement them, because they just move your exisiting security settings.
This is all I can think of. I tried your previous simpler Balloon code from your other article and it gives the same problem.
I do not know enough C# or .NET yet to help more than this.
Aalst
|
|
|
|
|
I am running RTM .NET, with SP2, XP Pro with all critical updates. It was a clean install (not an upgrade from beta).
I would assume that the problem is pretty isolated as this page has had 18000 hits and only one report of problems such as yours. Don't you just love computers?
Try to step through the code (using step into) and find out which line of source code it gets to before it throws an exception.
Joel
|
|
|
|
|
Well I set a break point at line 217 of Form1.cs, just before the line it breaks at with the exception. I stepped-into and it still gives an exception at line 219. It doesn't even step into the constructor of NotifyIconEx(). I thought that was strange but maybe its normal.
The exact error message in the box is:
=======================================
An unhandled exception of type 'System.Security.SecurityException' occurred in NotifyIconTest.exe
Additional information: Request for the permission of type System.Security.Permissions.SecurityPermission, mscorlib, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 failed.
=======================================
I can not even catch this exception, if I try to it just seems to ignore my try catch block.
I am going to keep looking into this, if you have any other sugestions let me know, I want to help any way I can.
Aalst
|
|
|
|
|
Joel,
I asked for help in the main C# forum here, and I got a response for Leppie. Leppie's message pointed me in the right direction. The sercurity violation is that the program is running from a network share.
I it to my local drive and it works fine. Now I am concerned what is a security violation in the application that it can't be runned from a network share. I run other C# apps from there all the time never a problem until now.
Then I wonder once the problem is know, if it can be fixed.
Well there we have it, at the present time your project has to be run from a local physical drive.
Aalst
|
|
|
|
|
Yeah I checked, and there are no compiler options to fix this. I only have 3 choices.
1 - Don't run code from network shares.
2 - Increase the trust level on a assembly by assembly bases.
3 - Adjust the Intranet Zone security to Full Trust.
I did 3 and it works fine. In my mind, Intranet and Local machine security are the same since I am the Admin. So I do not usually consider this. So I should not have this problem again.
Thanks for your help...
Aalst
|
|
|
|
|
Now you mention it I have heard of this issue before but have not researched it. You will find that it seems to be the creation of the hidden NotifyWindow class that is the problem. But I have no idea what is so special about this class!
You will find that security is one of the most little understood aspects of programming (due to the 'yawn factor' I would guess).
Sorry I can't be more insightful.
Joel
|
|
|
|
|
Just wanted to say that this control works on VB.NET very easily. Thank you for creating it.
kl
|
|
|
|
|
I was looking thru your code, and in the CreateOrUpdate procedure, something has me worried:
Create(m_nextId++);
since m_nextId is static... wouldn't it be possible for this to cause threading issues?
maybe it should be something like:
lock( typeof( NotifyIconEx ) ) {
Create( m_nextId );
m_nextId++;
}
and while we're on the subject... what is the point of having the hidden window and the nextId be static?
I don't profess to know a whole lot about threading in general, so just slap me down as needed
|
|
|
|
|
First off you are correct about the potential threading issue. However it would only be a problem if you were creating more than one icon using multiple threads which is not going to be something most people need to do. So I probably should have mentioned that this class is not thread safe as is. It would probably be trivial to fix thise using something like you have suggested (I have not played with lock() yet so I can't comment on it).
The reason that these members are static is that for each instance of the application I wanted one hidden window to handle all icons associated with that app. Also for every instance of notify icon created you need to make sure that you don't try to add an icon to the notify area with the same id, i.e. the id for each icon must be unique. The easiest way to do this is to make the next id static.
Hope this makes sense - Joel
|
|
|
|
|
How to send message to notification icon from other program such as Windows Service?
|
|
|
|
|
You really need a seperate service GUI app to do this. The biggest hurdle is deciding how to communicate with the service. You can use a variety of methods depending on how complex and numerous the communication needs to be. Methods include:
1. Shared memory. (Service and GUI must run on same machine).
2. Windows messages (data is limited unless you use 1.)
3. Socket communication (requires some work, but GUI and service need not be on the same machine).
4. .NET remoting may be a good choice for complex data passing. Learning curve but GUI and service may be on different machines.
5. Registry in tandem with window messages (yuck)
5. Window messages and shared data files.
Hope this gives you some ideas.
Joel
|
|
|
|
|
Joel,
A seventh option that would work with "legacy" applications and ".NET" applications alike, is to use DCOM. From the ".NET" perspective, this is virtually identical to use remoting.
--
Paul
"I drank... WHAT?"
|
|
|
|
|
1) the uint( UInt32 ) data type is not CLS compliant. I suggest you use Int64 or Int32 instead in the public ShowBallon method, and then convert it to an uint internally.
2) I believe the Dispose override should call base.Dispose() after Remove()
3) Make more virtual methods, so we can subclass this effectively.
4) I suggest you take a look at the standard pattern for event raising across the BCL. things you should consider doing along this line:
4a) make the NotifyIconHandler delegate a void NotifyIconTargetEventHandler( Object sender, NotifyIconTargetEventArgs e )
4b) subclass EventArgs to make NotifyIconTargetEventArgs with the Id as a get-only property.
4c) make the OnEVENT methods protected, virtual, and only receive the NotifyIconTargetEventArgs
4d) use the onEVENT methods to determine wether the event is null, and raise it with "this"
4e) use EventArgs.Empty instead of new EventArgs()
5) maybe change ClickBalloon event to BalloonClick, the former sounds more like a method that _does_ the clicking.
overall, very usefull code. good job.
|
|
|
|
|
In answer to your points:
1) the uint( UInt32 ) data type is not CLS compliant. I suggest you use Int64 or Int32 instead in the public ShowBallon method, and then convert it to an uint internally.
- Picky but point taken.
2) I believe the Dispose override should call base.Dispose() after Remove()
- I will fix this.
3) Make more virtual methods, so we can subclass this effectively.
- I am married with 4 kids so you do it
4) I suggest you take a look at the standard pattern for event raising across the BCL. things you should consider doing along this line:
4a) make the NotifyIconHandler delegate a void NotifyIconTargetEventHandler( Object sender, NotifyIconTargetEventArgs e )
4b) subclass EventArgs to make NotifyIconTargetEventArgs with the Id as a get-only property.
- Somebody needs to explain why I should do this since it is just more work than passing the id. Maybe I am missing something. Why bother creating a new class just to pass an id. Just because that's what the .NET library does?
4c) make the OnEVENT methods protected, virtual, and only receive the NotifyIconTargetEventArgs
4d) use the onEVENT methods to determine wether the event is null, and raise it with "this"
- That would be just the way you would do it maybe. You need to give good reasons if you are going to make this kind of suggestion.
4e) use EventArgs.Empty instead of new EventArgs()
- Why? To save memory on the heap? The docs don't say this but I assume it does otherwise what's the point?
Wow, you are pretty picky dude
|
|
|
|
|
Joel Matthias wrote:
4a) make the NotifyIconHandler delegate a void NotifyIconTargetEventHandler( Object sender, NotifyIconTargetEventArgs e )
4b) subclass EventArgs to make NotifyIconTargetEventArgs with the Id as a get-only property.
- Somebody needs to explain why I should do this since it is just more work than passing the id. Maybe I am missing something. Why bother creating a new class just to pass an id. Just because that's what the .NET library does?
Well, it's more than just what the library does.
A) It's promotes consistency. which helps people reading your code
B) Following this allows any method to handle any event with the base "void ( object, eventargs )" signature.
Joel Matthias wrote:
4c) make the OnEVENT methods protected, virtual, and only receive the NotifyIconTargetEventArgs
4d) use the onEVENT methods to determine wether the event is null, and raise it with "this"
- That would be just the way you would do it maybe. You need to give good reasons if you are going to make this kind of suggestion.
The reason for the method attribute changes is so that subclassers of this class can use the standard and good practice of overriding the OnEVENT method to extend behavior. The purpose for the changes in parameters, is, yes, to be consistent with the all the other hundreds of event raising methods.
If you are a coder of this level that doesn't believe in the virtues of having a consistent interface... then I doubt some comment in the forums is going to change that. take what you will from this.
Joel Matthias wrote:
4e) use EventArgs.Empty instead of new EventArgs()
- Why? To save memory on the heap? The docs don't say this but I assume it does otherwise what's the point?
EventArgs.Empty is a static instance of the EventArgs class. basically, every EventHandler in the BCL uses this same instance of EventArgs for an empty args. Using EventArgs.Empty not only stops the creation of a new instance needlessly, it also is one less object that needs to be GC'd.
yes, I know I'm picky... but I don't mean to say your code is bad. I just think that the more programmers using Best Practices, the better
|
|
|
|
|
Andy Smith wrote:
Joel Matthias wrote:
4a) make the NotifyIconHandler delegate a void NotifyIconTargetEventHandler( Object sender, NotifyIconTargetEventArgs e )
4b) subclass EventArgs to make NotifyIconTargetEventArgs with the Id as a get-only property.
- Somebody needs to explain why I should do this since it is just more work than passing the id. Maybe I am missing something. Why bother creating a new class just to pass an id. Just because that's what the .NET library does?
Well, it's more than just what the library does.
A) It's promotes consistency. which helps people reading your code
B) Following this allows any method to handle any event with the base "void ( object, eventargs )" signature.
I have to question the usefulness of B) being able to handle an event with a generic method that does not need know what the actual event argument is. I just don't see that as being useful and have not seen an example of this type of code. I think the trade off of making the code simpler is worth it. I think there is a school of thought that says don't make things complicated just because someone someday may want to use your class in a certain way.
Andy Smith wrote:
Joel Matthias wrote:
4c) make the OnEVENT methods protected, virtual, and only receive the NotifyIconTargetEventArgs
4d) use the onEVENT methods to determine wether the event is null, and raise it with "this"
- That would be just the way you would do it maybe. You need to give good reasons if you are going to make this kind of suggestion.
The reason for the method attribute changes is so that subclassers of this class can use the standard and good practice of overriding the OnEVENT method to extend behavior. The purpose for the changes in parameters, is, yes, to be consistent with the all the other hundreds of event raising methods.
If you are a coder of this level that doesn't believe in the virtues of having a consistent interface... then I doubt some comment in the forums is going to change that. take what you will from this.
I'm not sure I am familiar with the practice of overriding 'OnEvent'. Is this a .NET practice because I couldn't find OnEvent in the .NET help files? Again I think you are just trying to make the class as flexable as possible which is fine but you are going to sacrifice simplicity with this approach.
Don't get me wrong you made some valid points which I have noted and I will update my code. I really did not intend to make this class generic and extendable. For one I wanted to keep is simple and my free time is somewhat limited.
Cheers - Joel
|
|
|
|
|
Joel Matthias wrote:
I think the trade off of making the code simpler is worth it. I think there is a school of thought that says don't make things complicated just because someone someday may want to use your class in a certain way.
yes, that school of thought is the classic Worse it better approach. .Net is is designed to be The Right Thing© instead.
Joel Matthias wrote:
I'm not sure I am familiar with the practice of overriding 'OnEvent'.
I mean "Event" in the generic sense. Look thru the BCL. For every single ( I believe ) public event Foo, you will see a protected virtual OnEvent method. The function of this method is to check the event for null, and raise it if so. the reason for the accessability is for subclassers.
|
|
|
|
|
Andy Smith wrote:
I mean "Event" in the generic sense. Look thru the BCL. For every single ( I believe ) public event Foo, you will see a protected virtual OnEvent method. The function of this method is to check the event for null, and raise it if so. the reason for the accessability is for subclassers.
I looked at the original .NET NotifyIcon and none of the events have a virtual OnEVENT finction associated with them.
And one more thing (in my defense). The hidden window class is a completely private internal class that is not designed to be derived from so I don't feel too bad about not making it easy to do so.
Anyway I have updated the code with some of your suggestions.
Regards - Joel
|
|
|
|
|
Joel Matthias wrote:
I looked at the original .NET NotifyIcon and none of the events have a virtual OnEVENT finction associated with them.
You're right, the NotifyIcon class doesn't have the protected virtual OnEVENT methods because it is sealed, thus a protected method isn't going to do anything for it :-P
For non-sealed classes though, that is the standard and like it or not; if you deviate from the standard you increase the chance people are going to have a problem working with your code then they'll blame your code for not working.
James
Simplicity Rules!
|
|
|
|
|
So I'll just make the class sealed, ha! But seriously how DO you decide whether to seal a class or not.
Joel
|
|
|
|
|
From My Experience©
You seal a class when:
It doesn't make any sense to derive from it ( like most subclasses of EventArgs )
When you've made the class part of a pattern where subclassing it has a high likelyhood of breaking the pattern in subtle ways.
You've made assumptions about the internal layout of the resulting IL, and subclassing it would break those assumptions.
When you feel like being a jerk.
|
|
|
|
|
Andy Smith wrote:
When you feel like being a jerk.
Ouch! Ohhhh, you meant the guy at Microsoft who made their NotifyIcon class sealed is a jerk. For a minute.....
Joel
|
|
|
|
|
Joel Matthias wrote:
1) the uint( UInt32 ) data type is not CLS compliant. I suggest you use Int64 or Int32 instead in the public ShowBallon method, and then convert it to an uint internally.
- Picky but point taken.
IIRC VB.NET doesn't support unsigned types.
James
Simplicity Rules!
|
|
|
|
|
what happens with the balloon when people don't have the newer version of windows/ie/whatever that enables the balloon?
if you haven't addressed that, maybe you should just make it a dialogbox with only an OK button.
|
|
|
|