Archive: Shut down computer


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


This is the code I made after looking at MSDN, but it doesn't work.

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

-Stu


there are several win32-api functions to do this, documented on this page:
http://msdn.microsoft.com/library/de..._functions.asp

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

Use ExitWindowsEx. On Windows NT you'll have to adjust the process tokens. EnumUsersReg shows you how to do that.


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.

Comm@nder21, that doesn't seem to work here.

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

-Stu


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 :)


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


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"

That doesn't work either lol
Takes a while to execute it though.

-Stu


this is very annoying ...
msdn sucks.
or system.dll does.
or i do.
dunno ...

:)


NSIS denies exiting Windows while it's working (it returns FALSE to WM_QUERYENDSESSION).


Oh, so that means this isn't possible through NSIS?

-Stu


Not without a plug-in to avoid the denial or a source code change.


there's a force parameter for this one ...


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

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


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.


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


this one ?
http://www.tdnsoftware.com/download.html

http://www.freeware-download.com/dow...tails/964.html

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.

Right here is my first NSIS plugin:
http://nsis.sourceforge.net/mediawik...9/ShutDown.zip

It's only 2.5kB :)
Source and readme included.

-Stu


If you're already using a plug-in, subclass the dialog and return TRUE for WM_QUERYSESSION instead of using EWX_FORCE.


I'll have a go :)

-Stu


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


Ah right, dwwin.exe is Doctor Watson therefore I've got an error here somewhere.

Attached C source code.

-Stu


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.

http://nsis.sourceforge.net/mediawik...utDown-0.2.zip

-Stu


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


http://nsis.sourceforge.net/File:ShutDown.zip

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

-Stu


Thanks :)