How to detect whether Windows is shutting down or restarting - c++

I know that when Windows is shutting down, it sends a WM_QUERYENDSESSION message to each application. This makes it easy to detect when Windows is shutting down. However, is it possible to know if the computer going to power-off or is it going to restart after Windows has shutdown.
I am not particularly hopeful, considering the documentation at MSDN has this to say about WM_QUERYENDSESSION: "...it is not possible to determine which event is occurring," but the cumulative cleverness of stackoverflow never ceases to amaze me.

In Windows 7 (and probably also in Vista / 8 / Server) you could use the system events to track whether Windows is shutting down (and powering off the computer) or just restarting. Every time a shutdown/reboot is initiated (by any means - clicking the button in Start menu, or programmatically), Windows 7 writes one or two events in the System log, source USER32, event ID 1074. You can see these events recorded if you open the Event Viewer from Administrative Tools (filter the System log to see only ID 1074). The description (message) of these events contains the shutdown type. So you could parse the description of the most recent event of this type (after the shutdown was initiated), looking for the necessary word (shutdown, reboot/restart).
I didn't try to see the shutdown type written in the event when using the power button to gracefully shutdown Windows (I usually disable this function), but some site suggests that it states a "power off" type instead of "shutdown" - so check it out, if you need to be sure. Or simply look for a "reboot" type - if it's not found, then a "shutdown" type is assumed.
In Windows XP, from my experience, an event 1074 is recorded only if the shutdown/reboot is done programmatically (e.g. during a program install or using the shutdown.exe utility). So it does not register the shutdowns initiated from the shell (Explorer), but perhaps you could combine this method with reading the value from registry as proposed in another answer. Also, keep in mind that in WinXP the message of event 1074 contains the word "restart" no matter what the real type of shutdown is, so you should look at the "Shutdown Type:" field, which will state either "shutdown" or "reboot".
Related to this, an event ID 1073 is recorded whenever Windows fails to shutdown/reboot for some reason (e.g. if an application doesn't allow to shutdown as a response to WM_QUERYENDSESSION). In that case the message will also contain words as "shutdown", "reboot" or "power off" - in WinXP. For Win7 this type of event is less useful in our case, since it won't make any difference between shutdown and reboot. But for WinXP - if you only need to intercept the shutdown/reboot, perform some actions, then continue the corresponding shutdown or reboot process - it should work as expected.

From here:
You can read the DWORD value from
"HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shutdown
Setting" to determine what the user
last selected from the Shut Down
dialog.
A bit of a roundabout solution, but it should do the trick.

A trick that usually works is to trap WM_ENDSESSION and log it. Now keep track of the time. If the system comes back up within a reasonable peroid (say 5 minutes). Then that was a reboot, not a shutdown.
Idea: If the system comes back up within 5 minutes, does it really matter if the user clicked 'shutdown' or 'reboot'?
If you really need to detect a shutdown (and the only reason I think you'd need to do this is if you're depending upon an obscure behavioral software difference between a shutdown vs a reboot) you could investigate API hooking of ExitWindowsEx and related functions but I don't recommend this approach. Rethink if you really need to detect this directly.

Possible experimental solution for Windows7 could be the following. (I'm not sure if this works well with other localizations, therefore I would call it a workaround)
using System.Diagnostics.Eventing.Reader;
namespace MyApp
{
public class RestartDetector : IDisposable
{
public delegate void OnShutdownRequsted(bool restart);
public OnShutdownRequsted onShutdownRequsted;
private EventLogWatcher watcher = null;
public RestartDetector()
{
try
{
EventLogQuery subscriptionQuery = new EventLogQuery(
"System", PathType.LogName, "*[System[Provider[#Name='USER32'] and (EventID=1074)]]");
watcher = new EventLogWatcher(subscriptionQuery);
// Make the watcher listen to the EventRecordWritten
// events. When this event happens, the callback method
// (EventLogEventRead) is called.
watcher.EventRecordWritten +=
new EventHandler<EventRecordWrittenEventArgs>(
EventLogEventRead);
// Activate the subscription
watcher.Enabled = true;
}
catch (EventLogReadingException e)
{
}
}
public void EventLogEventRead(object obj, EventRecordWrittenEventArgs arg)
{
bool restart = false;
try
{
// Make sure there was no error reading the event.
if (arg.EventRecord != null)
{
String[] xPathRefs = new String[1];
xPathRefs[0] = "Event/EventData/Data";
IEnumerable<String> xPathEnum = xPathRefs;
EventLogPropertySelector logPropertyContext = new EventLogPropertySelector(xPathEnum);
IList<object> logEventProps = ((EventLogRecord)arg.EventRecord).GetPropertyValues(logPropertyContext);
string[] eventData = (string[])logEventProps[0];
foreach (string attribute in eventData)
{
if (attribute.Contains("restart")) { restart = true; break; }
}
}
}
catch (Exception e)
{
}
finally
{
if (onShutdownRequsted != null) { onShutdownRequsted(restart); }
}
}
public void Dispose()
{
// Stop listening to events
if (watcher != null)
{
watcher.Enabled = false;
watcher.Dispose();
}
}
}
}
The following is an example of XML which is written to the event log when a PC is restarted:
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="USER32" />
<EventID Qualifiers="32768">1074</EventID>
<Level>4</Level>
<Task>0</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2015-12-15T11:10:43.000000000Z" />
<EventRecordID>90416</EventRecordID>
<Channel>System</Channel>
<Computer>WIN7PC</Computer>
<Security UserID="S-1-5-21-1257383181-1549154685-2724014583-1000" />
</System>
- <EventData>
<Data>C:\Windows\system32\winlogon.exe (WIN7PC)</Data>
<Data>WIN7PC</Data>
<Data>No title for this reason could be found</Data>
<Data>0x500ff</Data>
<Data>restart</Data>
<Data />
<Data>WIN7PC\WIN7PCUser</Data>
<Binary>FF00050000000000000000000000000000000000000000000000000000000000</Binary>
</EventData>
</Event>

Related

In AnyLogic, how do I return a crane to automatic mode (idle state) after executing a CraneProgram?

AnyLogic (version 8.7.5) OverheadCrane is working well in automatic mode.
I use the moveByCrane logic blocks to move other agents from one location to another.
But I'd like to modify the behaviour just a little. After the crane has finished its move, I'd like it to lift the hook up out of the way.
There is a facility for operating cranes manually: the CraneProgram. In the crane's "On bridge state change" action, I use the following code to lift the hook up.
traceln("crane.onStateChange() "+newState);
if (newState == OverheadCraneBridgeState.IDLE) {
traceln(" Raising hook");
CraneProgram cp = new CraneProgram();
cp.moveHook(8, METER);
bridge.moveByProgram(cp);
}
This works nicely, except that the crane proceeds through MOVING_UNLOADED state and ends up in the WAITING state, and in that state it will not automatically work on any agents that are subsequently available to be moved.
The documentation describes WAITING as:
The bridge is seized by the agent, but this agent is currently moving through any blocks that are not SeizeCrane, MoveByCrane, or ReleaseCrane blocks. Also includes cases where the bridge in manual mode remains at target, executes a programmed delay command, or has finished the program and waits for the next command.
Is there a way to tell the crane that there will be no "next command", and it should switch from manual mode back to automatic mode?
Advice from AnyLogic support, received with thanks:
In this case I advise you to use “moveTo(…)” function of a bridge instead of using “CraneProgram” class. This function has “remainsAsTarget” argument, that allows you to use the required behavior when it reaches the destination.
Essence of solution:
if (newState == OverheadCraneBridgeState.IDLE && !movedHookUp) {
Point newPosition = new Point(endNode.getX(),endNode.getY(),endNode.getZ()+toPixels(8, LengthUnits.METER))
bridge.moveTo(newPoint, //destination
8, // safety height
false); // remainsAtTarget - see documentation
movedHookUp = true;
}
See moveTo function in the bridge documentation.

How to make sure last AMQP message is published successfully before closing connection?

I have multiple processes working together as a system. One of the processes acts as main process. When the system is shutting down, every process need to send a notification (via RabbitMQ) to the main process and then exit. The program is written in C++ and I am using AMQPCPP library.
The problem is that sometimes the notification is not published successfully. I suspect exiting too soon is the cause of the problem as AMQPCPP library has no chance to send the message out before closing its connection.
The documentation of AMQPCPP says:
Published messages are normally not confirmed by the server, and the RabbitMQ will not send a report back to inform you whether the message was succesfully published or not. Therefore the publish method does not return a Deferred object.
As long as no error is reported via the Channel::onError() method, you can safely assume that your messages were delivered.
This can of course be a problem when you are publishing many messages. If you get an error halfway through there is no way to know for sure how many messages made it to the broker and how many should be republished. If this is important, you can wrap the publish commands inside a transaction. In this case, if an error occurs, the transaction is automatically rolled back by RabbitMQ and none of the messages are actually published.
Without a confirmation from RabbitMQ server, it's hard to decide when it is safe to exit the process. Furthermore, using transaction sounds like overkill for a notification.
Could anyone suggest a simple solution for a graceful shutting down without losing the last notification?
It turns out that I can setup a callback when closing the channel. So that I can safely close connection when all channels are closed successfully. I am not entirely sure if this process ensures all outgoing messages are really published. However from the test result, it seems that the problem is solved.
class MyClass
{
...
AMQP::TcpConnection m_tcpConnection;
AMQP::TcpChannel m_channelA;
AMQP::TcpChannel m_channelB;
...
};
void MyClass::stop(void)
{
sendTerminateNotification();
int remainChannel = 2;
auto closeConnection = [&]() {
--remainChannel;
if (remainChannel == 0) {
// close connection when all channels are closed.
m_tcpConnection.close();
ev::get_default_loop().break_loop();
}
};
auto closeChannel = [&](AMQP::TcpChannel & channel) {
channel.close()
.onSuccess([&](void) { closeConnection(); })
.onError([&](const char * msg)
{
std::cout << "cannot close channel: "
<< msg << std::endl;
// close the connection anyway
closeConnection();
}
);
closeChannel(m_channelA);
closeChannel(m_channelB);
}

understanding RProperty IPC communication

i'm studying this source base. Basically this is an Anim server client for Symbian 3rd edition for the purpose of grabbing input events without consuming them in a reliable way.
If you spot this line of the server, here it is basically setting the RProperty value (apparently to an increasing counter); it seems no actual processing of the input is done.
inside this client line, the client is supposed to be receiving the notification data, but it only calls Attach.
my understanding is that Attach is only required to be called once, but is not clear in the client what event is triggered every time the server sets the RProperty
How (and where) is the client supposed to access the RProperty value?
After Attaching the client will somewhere Subscribe to the property where it passes a TRequestStatus reference. The server will signal the request status property via the kernel when the asynchronous event has happened (in your case the property was changed). If your example source code is implemented in the right way, you will find an active object (AO; CActive derived class) hanging around and the iStatus of this AO will be passed to the RProperty API. In this case the RunL function of the AO will be called when the property has been changed.
It is essential in Symbian to understand the active object framework and quite few people do it actually. Unfortunately I did not find a really good description online (they are explained quite well in Symbian OS Internals book) but this page at least gives you a quick example.
Example
In the ConstructL of your CMyActive subclass of CActive:
CKeyEventsClient* iClient;
RProperty iProperty;
// ...
void CMyActive::ConstructL()
{
RProcess myProcess;
TSecureId propertyCategory = myProcess.SecureId();
// avoid interference with other properties by defining the category
// as a secure ID of your process (perhaps it's the only allowed value)
TUint propertyKey = 1; // whatever you want
iClient = CKeyEventsClient::NewL(propertyCategory, propertyKey, ...);
iClient->OpenNotificationPropertyL(&iProperty);
// ...
CActiveScheduler::Add(this);
iProperty.Subscribe(iStatus);
SetActive();
}
Your RunL will be called when the property has been changed:
void CMyActive::RunL()
{
if (iStatus.Int() != KErrCancel) User::LeaveIfError(iStatus.Int());
// forward the error to RunError
// "To ensure that the subscriber does not miss updates, it should
// re-issue a subscription request before retrieving the current value
// and acting on it." (from docs)
iProperty.Subscribe(iStatus);
TInt value; // this type is passed to RProperty::Define() in the client
TInt err = iProperty.Get(value);
if (err != KErrNotFound) User::LeaveIfError(err);
SetActive();
}

How to find whether a given application is single instance or not?

I am looking for an efficient way to find whether a given application (say app.exe) is single instance or not? I thought of these following sols:
Do CreateProcess() twice and check whether there are two or more instance running of that application? If no, it is single instance application. But, this is not efficient.
Do CreateProcess() and wait for 1-2 sec. If this instance is killed (because there is already an instance running for it), it will be single instance app.
But I am not convinced with both above sol. Is there any other efficient way of doing that in windows?
Please note that I don't to kill or make any modifications to an already running (if any) instance of that application.
Think about it the other way: When you write a program, how do you specify whether it is single-instance or multiple-instance? Is there a way that some other program can get that information out of your program without running it? (Once you answer this question, then you have the answer to your question.)
This problem is not solvable in general because single-instance/multiple-instance-ness is determined at runtime and can be based on runtime conditions. For example, some applications are "sometimes multiple instance, sometimes single": If you run the application to open document X, and then document Y, you will get two instances. But if you open document X, and then document X again, the two instances will fold into one. Other applications may have a configuration switch that lets you select whether they are single-instance or multiple-instance. Or maybe they decide to flip a coin and decide to be single-instance if tails and multiple-instance if heads.
The best way is via using synchronization object called Mutex (Mutually exclusive). You may google it.
I think the following code may help to.
//---------------------------------------------------------------------------
WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
try
{
HANDLE hMutex=OpenMutex(MUTEX_ALL_ACCESS,0,"SIns");
if (!hMutex) {
//Mutex doesn’t exist. This is the first instance so create the mutex.
//in this case app name is SIns (Single Instance)
hMutex=CreateMutex(0,0,"SIns");
Application->Initialize();
Application->MainFormOnTaskBar = true;
Application->CreateForm(__classid(TfMain), &fMain);
Application->Run();
ReleaseMutex(hMutex);
}
else{
//This is not single. The prev instance is already running
//so informing about it
//remember that if it finds prev instance we're activating it here
//you may do whatsoever here ...... e.g. you may kill process or stuff like this:)
ShowMessage("The program is already running. Switching to ...");
HWND hWnd=FindWindow(0,"SIns");
SetForegroundWindow(hWnd);
}
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
There is no way to do this at all. What happens if the application checks a mutex then makes a messagebox to tell the user an instance is already running and only when the user dismisses it does it kill the application? There are many different ways to ensure mutual exclusion via some shared resource, mutex, shared file, even maybe setting some registry key, the methods are unlimited.
The usual solution is to use some sort of a locking file. Under
traditional Unix, for example, the application will start by creating a
file (which will succeed even if the file exists), then try to create a
link to it (an atomic action); if that fails, the application will
immediately kill itself. Under Windows, the share mode of CreateFile
can be used to the same effect: open a file with share mode 0, and if
that fails, quit. (The Unix solution will leave the lock if the process
crashes, requiring it to be cleaned up manually. The Windows solution
will remove the lock if the system crashes.)
you may use mutexes... I do such check with following code:
bool insureApplicationUniqueness(HANDLE& mutexHandle)
{
mutexHandle=CreateMutexW(NULL,true,UNIQUE_INSTANCE_MUTEX_NAME);
if( mutexHandle&&(ERROR_ALREADY_EXISTS==GetLastError()))
{
CloseHandle(mutexHandle);
return false;
}
return true;
}
but this is for application which source code is yours and which checks is another instance of itself running.
The problem with the notion is that in common environments, there is no explicit static data that determines whether an application is single-instance. You only have behavior to go on, but you cannot fully test behavior.
What if you have an app that is multi-instance, but will fail to open a file that's already open? If you test it twice with the same, valid filename, it would create only a single process, but any other command line argument would cause two processes to exist. Is this a single-instance program?
You could even argue that "single instance" isn't a well-defined catageory of programs for this reason.

Symbian C++ - synchronous Bluetooth discovery with timeout using RHostResolver

I am writing an application in Qt to be deployed on Symbian S60 platform. Unfortunately, it needs to have Bluetooth functionality - nothing really advanced, just simple RFCOMM client socket and device discovery. To be exact, the application is expected to work on two platforms - Windows PC and aforementioned S60.
Of course, since Qt lacks Bluetooth support, it has to be coded in native API - Winsock2 on Windows and Symbian C++ on S60 - I'm coding a simple abstraction layer. And I have some problems with the discovery part on Symbian.
The discovery call in the abstraction layer should work synchronously - it blocks until the end of the discovery and returns all the devices as a QList. I don't have the exact code right now, but I had something like that:
RHostResolver resolver;
TInquirySockAddr addr;
// OMITTED: resolver and addr initialization
TRequestStatus err;
TNameEntry entry;
resolver.GetByAddress(addr, entry, err);
while (true) {
User::WaitForRequest(err);
if (err == KErrHostResNoMoreResults) {
break;
} else if (err != KErrNone) {
// OMITTED: error handling routine, not very important right now
}
// OMITTED: entry processing, adding to result QList
resolver.Next(entry, err);
}
resolver.Close();
Yes, I know that User::WaitForRequest is evil, that coding Symbian-like, I should use active objects, and so on. But it's just not what I need. I need a simple, synchronous way of doing device discovery.
And the code above does work. There's one quirk, however - I'd like to have a timeout during the discovery. That is, I want the discovery to take no more than, say, 15 seconds - parametrized in a function call. I tried to do something like this:
RTimer timer;
TRequestStatus timerStatus;
timer.CreateLocal();
RHostResolver resolver;
TInquirySockAddr addr;
// OMITTED: resolver and addr initialization
TRequestStatus err;
TNameEntry entry;
timer.After(timerStatus, timeout*1000000);
resolver.GetByAddress(addr, entry, err);
while (true) {
User::WaitForRequest(err, timerStatus);
if (timerStatus != KRequestPending) { // timeout
resolver.Cancel();
User::WaitForRequest(err);
break;
}
if (err == KErrHostResNoMoreResults) {
timer.Cancel();
User::WaitForRequest(timerStatus);
break;
} else if (err != KErrNone) {
// OMITTED: error handling routine, not very important right now
}
// OMITTED: entry processing, adding to result QList
resolver.Next(entry, err);
}
timer.Close();
resolver.Close();
And this code kinda works. Even more, the way it works is functionally correct - the timeout works, the devices discovered so far are returned, and if the discovery ends earlier, then it exits without waiting for the timer. The problem is - it leaves a stray thread in the program. That means, when I exit my app, its process is still loaded in background, doing nothing. And I'm not the type of programmer who would be satisfied with a "fix" like making the "exit" button kill the process instead of exiting gracefully. Leaving a stray thread seems a too serious resource leak.
Is there any way to solve this? I don't mind rewriting everything from scratch, even using totally different APIs (as long as we're talking about native Symbian APIs), I just want it to work. I've read a bit about active objects, but it doesn't seem like what I need, since I just need this to work synchronously... In the case of bigger changes, I would appreciate more detailed explanations, since I'm new to Symbian C++, and I don't really need to master it - this little Bluetooth module is probably everything I'll need to write in it in foreseeable future.
Thanks in advance for any help! :)
The code you have looks ok to me. You've missed the usual pitfall of not consuming all the requests that you've issued. Assuming that you also cancel the timer and do a User::WaitForRequest(timerStatus) inside you're error handing condition, it should work.
I'm guessing that what you're worrying about is that there's no way for your main thread to request that this thread exit. You can do this roughly as follows:
Pass a pointer to a TRequestStatus into the thread when it is created by your main thread. Call this exitStatus.
When you do the User::WaitForRequest, also wait on exitStatus.
The main thread will do a bluetoothThread.RequestComplete(exitStatus, KErrCancel) when it wants the subthread to exit, where bluetoothThread is the RThread object that the main thread created.
in the subthread, when exitStatus is signalled, exit the loop to terminate the thread. You need to make sure you cancel and consume the timer and bluetooth requests.
the main thread should do a bluetoothThread.Logon and wait for the signal to wait for the bluetooth thread to exit.
There will likely be some more subtleties to deal correctly with all the error cases and so on.
I hope I'm not barking up the wrong tree altogether here...
The question is already answered, but... If you'd use active objects, I'd propose you to use nested active scheduler (class CActiveSchedulerWait). You could then pass it to your active objects (CPeriodic for timer and some other CActive for Bluetooth), and one of them would stop this nested scheduler in its RunL() method. More than this, with this approach your call becomes synchronous for the caller, and your thread will be gracefully closed after performing the call.
If you're interested in the solution, search for examples of CActiveSchedulerWait, or just ask me and I'll give your some code sample.