service unable to reject suspend query on XP

G

Guest

I created a basic service using VS2005. Add OnPowerEvent method as detailed
on MSDN and return false to a PowerBroadcastStatus.QuerySuspend notification.
The service also has set CanHandlePowerEvent = true. But the service still
fails to reject standby. If I do the same in VS2003, it does reject standby,
anyone else done or seen this with VS2005? Even if I set the code to return
false to all PowerBroadcastStatus events, it still doesn't reject standby.
 
J

JMS

dr said:
I created a basic service using VS2005. Add OnPowerEvent method as detailed
on MSDN and return false to a PowerBroadcastStatus.QuerySuspend notification.
The service also has set CanHandlePowerEvent = true. But the service still
fails to reject standby. If I do the same in VS2003, it does reject standby,
anyone else done or seen this with VS2005? Even if I set the code to return
false to all PowerBroadcastStatus events, it still doesn't reject standby.

Actually in .NET 2.0 the OnPowerEvent is broken (in my opinion)!
Microsoft decided to a) let it run asynchronously and b) ignore the
return code. You already have seen b) and what a) means is that the
order of events can be changed (e.g. I got Suspend just before a
QuerySuspend). In MSDN groups this topic is discussed and the Microsoft
team states that in Vista/Longhorn the power event mechanismn is no
longer reliable (can't believe that) and that therefore the behaviour
in .NET has changed.

If you really need it: there is a work-around which reactivates the
..NET 1.1 behaviour.

Jochen
 
G

Guest

thanks for the info. Is this work-around documented anywhere - can you send
me a link or post the info?

thanks again!

DR
 
D

Dr. Jochen Manns

No, the Work-Around is not documented - at least as far as I know. And
actually it shouldn't work (although Keith Brown explained how evil
FullTrust code can be
http://msdn.microsoft.com/msdnmag/issues/04/04/SecurityBriefs/default.aspx
which is exactly what I use here) but it does! Before I show the code some
comments. First I hope that some Microsoft guy reads this and comments how
we should write future services which are aware of power broadcast events.
And second to explain what happens:

1. The Service classes constructor (!) finds the CommandCallbackEx
registered by the base class and replaces it by its own stub.
2. The stub forwards all requests other than the power state information
(13) to the base classes method (actually the OnShutdown no longer works
with .NET 2.0, too but I didn't need it)
3. The stub handles OnPowerEvent the way .NET 1.1 does it.

I use this code on different systems for around four months and it seems to
work fine.

Regards

Jochen

PS: The work-around is used in here (german web site only):
http://www.psimarron.net/vcrnet - the installer includes full sources but I
think the extract shown below will fit your needs.

---------------------
Work-Around Code:
---------------------
public class Service : System.ServiceProcess.ServiceBase

{

public Service()

{

// Find the initialisation routine - may break in later versions

MethodInfo init = typeof(ServiceBase).GetMethod("Initialize",
BindingFlags.NonPublic | BindingFlags.Instance);

// Call it to set up all members

init.Invoke(this, new object[] { false });

// Find the service callback handler

FieldInfo handlerEx = typeof(ServiceBase).GetField("commandCallbackEx",
BindingFlags.NonPublic | BindingFlags.Instance);

// Read the base class provided handler

m_Forward = (Delegate)handlerEx.GetValue(this);

// Create a new delegate to our handler

Delegate test = Delegate.CreateDelegate(m_Forward.GetType(), this,
"ServiceCallbackEx");

// Install our handler

handlerEx.SetValue(this, test);

// This call is required by the Windows.Forms Component Designer.

InitializeComponent();

}

private int ServiceCallbackEx(int command, int eventType, IntPtr eventData,
IntPtr eventContext)

{

// Call the base class implementation which is fine for all but power and
session management

if (13 != command) return (int)m_Forward.DynamicInvoke(command, eventType,
eventData, eventContext);

// Process and forward success code

if (OnPowerEvent((PowerBroadcastStatus)eventType)) return 0;

// Abort power operation

return 0x424d5144;

}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top