Skip to content
⌘ NSIS Forum Archive

Shut down computer

29 posts

Afrow UK#

Shut down computer

I'd like to add functionality to an updater thingy written in NSIS to shut down the computer when updates have been downloaded and installed. Can someone write me System plugin code to do this (I'd attempt it but I have no experience in that area)?

-Stu
Afrow UK#
This is the code I made after looking at MSDN, but it doesn't work.

System::Call "cimwin32::Win32Shutdown(i 5,) i.r0"

-Stu
Comm@nder21#
there are several win32-api functions to do this, documented on this page:


the code you need looks like this:
System::Call "user32::ExitWindowsEx(i 0x00000002, i 0x00030003) i .r0"
this will reboot windows immediatly (first parameter) with reason "software - upgrade" (second parameter).
you also may use 0x00000008 (power off), 0x00000001 (shutdown) or 0 (logoff) instead of 0x00000002.
exitwindowsex function reference, with even more codes 🙂
all system shutdown reason codes


this functions have some more parameters:
InitiateSystemShutdown
InitiateSystemShutdownEx
kichik#
Use ExitWindowsEx. On Windows NT you'll have to adjust the process tokens. EnumUsersReg shows you how to do that.
Comm@nder21#
maybe you better use the InitiateSystemShutdown function.

MSDN:
The ExitWindowsEx function returns as soon as it has initiated the shutdown process. The shutdown or logoff then proceeds asynchronously. The function is designed to stop all processes in the caller's logon session. Therefore, if you are not the interactive user, the function can succeed without actually shutting down the computer. If you are not the interactive user, use the InitiateSystemShutdown or InitiateSystemShutdownEx function.
Afrow UK#
Comm@nder21, that doesn't seem to work here.

System::Call "user32::ExitWindowsEx(i 0x00000001, i 0x00030003) i .r0"

-Stu
Comm@nder21#
hmm, maybe the values are wrong.
i took them 1:1 from the msdn ...

you may try a zero for both values.
the system should initiate a logoff. then at least the function itself works the right way 🙂
Afrow UK#
lol tried 0 and 0 for both but instead of logging me off it just closed a few programs and then stopped. Atleast we know something works (sort of!)

-Stu
Comm@nder21#
you may also try this one (win nt/xp/2k/2k3 only):
System::Call "Advapi32::InitiateSystemShutdown(t 0, t 0, i 0, i 0, i 1) i .r0"
Afrow UK#
I ended up writing a small C++ app to do it. Shuts down computer after X seconds.

// ShutDown.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <mmsystem.h>
#include <string>
#include <stdio.h>

// Tell user usage format (if incorrect)
void printUsageError() {
printf("Usage: shutdown <seconds_untill_shutdown>");
}

int _tmain(int argc, _TCHAR* argv[])
{
if (argc > 1)
{

// Get paramater (time in seconds)
long timer = atol(argv[1]);

if (timer <= 0)
{
// Tell user usage format (if incorrect)
printUsageError();
}
else
{
// Calculate # of seconds
timer *= 1000;

// Confirm?
char szConfirm[2];
printf("This computer will shutdown in %s second(s).\r\nDo you want to continue (y|n)? ", argv[1]);
gets(szConfirm);

if (strcmp(szConfirm, "y") == 0)
{

// Perform sleep for [timer] seconds
Sleep(timer);

HANDLE hToken;
TOKEN_PRIVILEGES tkp;

// Get a token for this process.
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

// Get the LUID for the shutdown privilege.
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);

tkp.PrivilegeCount = 1; // one privilege to set
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

// Get the shutdown privilege for this process.
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);

// Perform the shutdown!
ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0);

}
}
}
else
{
// Tell user usage format (if incorrect)
printUsageError();
}
return 0;
}
-Stu
Afrow UK#
Actually, now I've learnt a lot of C++ in about 2 hours I'll turn this into a plugin with the option of chosing which shutdown type to do (ie log off, shutdown etc)

Not now though - at the weekend.

-Stu
Brummelchen#
try shutdown.exe from winxp (works also on 2k)

%windir%\system32\shutdown.exe -s -t 90 -c "Shutdown in 90secs"

so nsis is closed but shutdown is initiated.
Afrow UK#
Yeh thanks I was already aware of that but it doesn't seem to be on my Windows 98 machine so it's no use to me really. I also found this tool: http://www.budja.com/shutdown/
but again he designed it only for Windows XP.
Windows 98 and 95 has REBOOT95.EXE too, but that's got a GUI which I don't want.

-Stu
Brummelchen#
this one ?



Slawdog Smart Shutdown is a free commercial power shutdown utility. The program, based on a 1-2-3 interface and has huge number of shutdown options. It allows you to shut down, log off, reboot, lock, turn off, hibernate, disconnect from the Internet or network, enter standby mode in Windows, shut down and reboot computers in your network, both manually and automatically. Its built-in Smart Shutdown technology can shut down your computer if you are inactive for the specified period of time. Plus, with Easy Shutdown technology, you can shut down your computer with just a single click. The program shows options available in your OS only, supports command line and eats little resources. In addition, our exclusive Dependable Timer System technology, ErrorGuard and other similar features gives you 99.999% guaranty that your system will be shut down in any occasion, according to our tests.
Afrow UK#
Right here is my first NSIS plugin:


It's only 2.5kB 🙂
Source and readme included.

-Stu
kichik#
If you're already using a plug-in, subclass the dialog and return TRUE for WM_QUERYSESSION instead of using EWX_FORCE.
Afrow UK#
Ok now I'm getting an error message with the heading:
dwwin.exe - DLL Initialisation Failed

The message is something along the lines of "DLL failed to initialise because Windows is being shut down".

Not the exact message because I can only see it for a split second. Any ideas?

Should I attach the new source code?

-Stu
Afrow UK#
Ah right, dwwin.exe is Doctor Watson therefore I've got an error here somewhere.

Attached C source code.

-Stu
Afrow UK#
I was unable to get it to work, so I decided to go about it a different way.

The plugin now calls DestroyWindow to close NSIS safely.
If this fails, the ExitWindowsEx is not called.

I've added optional switches to enable EWX_FORCE and one to turn this safety feature off (user can then call Quit to close NSIS instead - e.g. in Section).

Am I right in using DestroyWindow, or should I be sending WM_CLOSE instead.



-Stu
Guest#
Is ShutDown-0.2.zip available for download anywhere?
The link in the post above doesn't work
Afrow UK#


Edit: The file appears to have been deleted! I shall re-upload.
Edit #2: Done.

-Stu