Диалог завершения работы
От: Аноним  
Дата: 18.08.04 04:33
Оценка:
Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС.
Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит.
Почему?


Вот код:


typedef void (_stdcall *SHShutDownDialogProc)(HWND);

if(Надо вывести диалог завершения работы)
{
    // получаем версию
    OSVERSIONINFO osvi;
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&osvi);

    // если 9x, то просто запоминаем в глобальной переменной
    if(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
    {
        WinVer = VER_PLATFORM_WIN32_WINDOWS;
    }
    // если NT, то устанавливаем привилегии на завершение работы
    else if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
    {
        WinVer = VER_PLATFORM_WIN32_NT;

        HANDLE hToken; 
        TOKEN_PRIVILEGES tkp; 

        if(!OpenProcessToken(GetCurrentProcess(),
            TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
            PrintError("OpenProcessToken");

        if(!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
            &tkp.Privileges[0].Luid))
            PrintError("LookupPrivilegeValue");

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

        if(!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
            (PTOKEN_PRIVILEGES)NULL, 0))
            PrintError("AdjustTokenPrivileges");
    }
    //иначе ошибка
    else
    {
        MessageBox(0,"Данная версия ОС не поддерживает эту операцию.",
            0,MB_OK|MB_ICONSTOP);
        return 1;
    }


    // ищем в shell32.dll функцию, которая выводит диалог завершения работы
    // и вызываем её
    SHShutDownDialogProc SHShutDownDialog;
    HMODULE hDll;

    hDll = LoadLibrary("shell32.dll");
    if(!hDll)PrintError("LoadLibrary");

    SHShutDownDialog = (SHShutDownDialogProc)GetProcAddress(hDll,(LPCSTR)60);
    if(!SHShutDownDialog)PrintError("GetProcAddress");

    SHShutDownDialog(GetDesktopWindow());
    FreeLibrary(hDll);
}
Re: Диалог завершения работы
От: rockandroll Казахстан  
Дата: 18.08.04 05:10
Оценка: +1 -1
Здравствуйте, <Аноним>, Вы писали:

А>Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС.

А>Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит.
А>Почему?

Наверное потому, что эта функция просто выводит диалог.
... << RSDN@Home 1.1.4 >>
Re: Диалог завершения работы
От: aGrey Литва  
Дата: 18.08.04 05:16
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС.

А>Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит.
А>Почему?
А> ...

А я откуда знаю? Фича недокументированная!
Хотя, rockandroll по-моему правильно сказал...

Используй лучше это (см. Re: свернуь все окна приложений на рабочем столе
Автор: aGrey
Дата: 02.08.04
):

#include <windows.h>
#include <shldisp.h> // ole32.lib uuid.lib

BOOL SHShutdownWindows(BOOL fStandBy) {

LONG lRes = -1, lNCo = CoInitialize(NULL);

if(lNCo == S_OK || lNCo == S_FALSE)
{
    IShellDispatch * pIShDisp = NULL;

    CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER,
        IID_IShellDispatch, (LPVOID*)&pIShDisp);

    if(pIShDisp != NULL)
    {
        if(fStandBy) lRes = pIShDisp->ShutdownWindows();
        else         lRes = pIShDisp->Suspend();        // Срабатывает сразу!

        pIShDisp->Release();
    }

    CoUninitialize();
}

return (lRes == S_OK);    }

Или даже на JavaScript:

new ActiveXObject('Shell.Application').ShutdownWindows()
Re[2]: Диалог завершения работы
От: Аноним  
Дата: 18.08.04 06:05
Оценка:
Здравствуйте, rockandroll, Вы писали:

R>Наверное потому, что эта функция просто выводит диалог.


Но эта функция ничего не возвращает. Как мне узнать, какую кнопку юзер тыкнул? Неужели хуки?
Re: Диалог завершения работы
От: dv2004  
Дата: 18.08.04 06:12
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС.

А>Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит.
А>Почему?

Вообще-то лучше юзать RestartDialogEx — он все возвращает и сам вызывает ExitWindowsEx


А>Вот код:



А>
А>typedef void (_stdcall *SHShutDownDialogProc)(HWND);

А>if(Надо вывести диалог завершения работы)
А>{
А>    // получаем версию
А>    OSVERSIONINFO osvi;
А>    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
А>    GetVersionEx(&osvi);

А>    // если 9x, то просто запоминаем в глобальной переменной
А>    if(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
А>    {
А>        WinVer = VER_PLATFORM_WIN32_WINDOWS;
А>    }
А>    // если NT, то устанавливаем привилегии на завершение работы
А>    else if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
А>    {
А>        WinVer = VER_PLATFORM_WIN32_NT;

А>        HANDLE hToken; 
А>        TOKEN_PRIVILEGES tkp; 

А>        if(!OpenProcessToken(GetCurrentProcess(),
А>            TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
А>            PrintError("OpenProcessToken");

А>        if(!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
А>            &tkp.Privileges[0].Luid))
А>            PrintError("LookupPrivilegeValue");

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

А>        if(!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
А>            (PTOKEN_PRIVILEGES)NULL, 0))
А>            PrintError("AdjustTokenPrivileges");
А>    }
А>    //иначе ошибка
А>    else
А>    {
А>        MessageBox(0,"Данная версия ОС не поддерживает эту операцию.",
А>            0,MB_OK|MB_ICONSTOP);
А>        return 1;
А>    }


А>    // ищем в shell32.dll функцию, которая выводит диалог завершения работы
А>    // и вызываем её
А>    SHShutDownDialogProc SHShutDownDialog;
А>    HMODULE hDll;

А>    hDll = LoadLibrary("shell32.dll");
А>    if(!hDll)PrintError("LoadLibrary");

А>    SHShutDownDialog = (SHShutDownDialogProc)GetProcAddress(hDll,(LPCSTR)60);
А>    if(!SHShutDownDialog)PrintError("GetProcAddress");

А>    SHShutDownDialog(GetDesktopWindow());
А>    FreeLibrary(hDll);
А>}
А>
... << RSDN@Home 1.1.3 stable >>
Re[3]: Диалог завершения работы
От: rockandroll Казахстан  
Дата: 18.08.04 06:48
Оценка:
Здравствуйте, <Аноним>, Вы писали:

R>>Наверное потому, что эта функция просто выводит диалог.


А>Но эта функция ничего не возвращает.

Как ты это узнал?

А>Как мне узнать, какую кнопку юзер тыкнул? Неужели хуки?

Как тебе советовали, не пользуйся недокументированными функциями. Нарисуй свой диалог.
... << RSDN@Home 1.1.4 >>
Re[4]: Диалог завершения работы
От: Аноним  
Дата: 18.08.04 10:34
Оценка:
Здравствуйте, rockandroll, Вы писали:

R>Как ты это узнал?

В нете, умные люди пишут.

R>Как тебе советовали, не пользуйся недокументированными функциями. Нарисуй свой диалог.

Так в разных виндах он разный, а дясять штук делать неохота и ващще...
Re[2]: Диалог завершения работы
От: Аноним  
Дата: 18.08.04 10:36
Оценка:
Здравствуйте, dv2004, Вы писали:

D>Вообще-то лучше юзать RestartDialogEx — он все возвращает и сам вызывает ExitWindowsEx


А подробнее можно, а то я что-то такого не слышал и не видел.
Re[3]: Диалог завершения работы
От: dv2004  
Дата: 18.08.04 11:02
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, dv2004, Вы писали:


D>>Вообще-то лучше юзать RestartDialogEx — он все возвращает и сам вызывает ExitWindowsEx


А>А подробнее можно, а то я что-то такого не слышал и не видел.


Вот кусок из MSDN:
RestartDialogEx Function

Displays a dialog box that asks the user to restart Microsoft® Windows®. When the user clicks the button, the function calls ExitWindowsEx to attempt to restart Windows.
Syntax
int RestartDialogEx(
HWND hParent,
LPCWSTR pszPrompt,
DWORD dwFlags,
HWND dwReasonCode
);
Parameters
hParent
[in] A handle to the parent window.
pszPrompt
[in] A null-terminated string that contains the text that displays in the dialog box to prompt the user.
dwFlags
[in] Flags that specifies the type of shutdown.
This parameter must include one of the following values.
EWX_LOGOFF
Shuts down all processes running in the security context of the process that called this function. Then it logs the user off.
EWX_POWEROFF
Shuts down the system and turns off the power. The system must support the power-off feature. The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see ExitWindowsEx.
EWX_REBOOT
Shuts down the system and then restarts the system. The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see ExitWindowsEx.
EWX_SHUTDOWN
Shuts down the system to a point at which it is safe to turn off the power. At this point, all file buffers have been flushed to disk, and all running processes have stopped. If the system supports the power-off feature, the power is also turned off. The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see ExitWindowsEx.
This parameter can optionally include the following values.
EWX_FORCE
Forces processes to terminate. When this flag is set, the system does not send the WM_QUERYENDSESSION and WM_ENDSESSION messages. This can cause the applications to lose data. Therefore, you should only use this flag in an emergency.
EWX_FORCEIFHUNG
Forces processes to terminate if they do not respond to the WM_QUERYENDSESSION or WM_ENDSESSION message. This flag is ignored if EWX_FORCE is used.
dwReasonCode
[in]
Windows XP:Specifies the reason for initiating the shutdown. For more information, see System Shutdown Reason Codes.
Windows 2000: This parameter is ignored.
Return Value
Returns the identifier of the button that was pressed to close the dialog box.
Function Information
Minimum DLL Version shell32.dll version 5.0 or later
Custom Implementation No
Header shlobj.h
Import library shell32.lib
Minimum operating systems Windows 2000


© 2004 Microsoft Corporation. All rights reserved.
... << RSDN@Home 1.1.3 stable >>
Re: Диалог завершения работы
От: Regular_Man  
Дата: 18.08.04 11:15
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС.

А>Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит.
А>Почему?
А>Вот код:
А>
A> ......
А>


На самом деле функция работает нормально и компутер выключает как надо. Просто по неизвестным причинам вызов FreeLibrary непосредственно после этой волшебной функции прерывает процесс выключения. Если поставить там задержку, то все работает.
Re: Диалог завершения работы
От: aGrey Литва  
Дата: 18.08.04 11:36
Оценка:
Народ — чего вы мучаетесь? Вам же предложили работоспособные варианты: 1
Автор: aGrey
Дата: 18.08.04
; 2
Автор: dv2004
Дата: 18.08.04
...
Re[2]: Диалог завершения работы
От: Regular_Man  
Дата: 18.08.04 11:38
Оценка:
Здравствуйте, aGrey, Вы писали:

G>Народ — чего вы мучаетесь? Вам же предложили работоспособные варианты: 1
Автор: aGrey
Дата: 18.08.04
; 2
Автор: dv2004
Дата: 18.08.04
...

но ведь вариант 0 тоже работоспособен...
Re: Диалог завершения работы
От: dimitry_dimitry  
Дата: 18.08.04 11:46
Оценка:
Здравствуйте, <Аноним>, Вы писали:
скажите кто-нибудь — а какие задачи требуют такого???
... << Rsdn@Home 1.1.4 beta 1 >>
Re: Диалог завершения работы
От: aGrey Литва  
Дата: 18.08.04 12:04
Оценка:
Хм. А фича действительно ничего не возвращает!

STDAPI_(VOID) ExitWindowsDialog(HWND hWndParent); // shell32.dll ordinal 60

Похоже, просто не надо использовать FreeLibrary() для shell32.dll...
Re[2]: Диалог завершения работы
От: Аноним  
Дата: 19.08.04 08:06
Оценка:
Здравствуйте, aGrey, Вы писали:

G>Хм. А фича действительно ничего не возвращает!


G>
G>STDAPI_(VOID) ExitWindowsDialog(HWND hWndParent); // shell32.dll ordinal 60
G>

G>Похоже, просто не надо использовать FreeLibrary() для shell32.dll...

А прога после этого сразу завершается и Виновззз сам Освобождает ресурсы, т.е. билу тоже. Короче, не получается так. А вот если задержку сделать, то, действительно вырубает.
Re: Диалог завершения работы
От: aGrey Литва  
Дата: 19.08.04 13:45
Оценка: 3 (1)
Ловите еще вариант, СОМ-ненавистники

#define IDM_LOGOFF   402
#define IDM_SUSPEND  409 // Вырубает сразу!
#define IDM_EJECTPC  410 // Вырубает сразу!
#define IDM_EXITWIN  506

HWND hTrayWnd = FindWindow(TEXT("Shell_TrayWnd"), NULL);
if(hTrayWnd != NULL) PostMessage(hTrayWnd, WM_COMMAND, IDM_EXITWIN, 0);
Re[2]: Диалог завершения работы
От: Аноним  
Дата: 20.08.04 10:26
Оценка:
Здравствуйте, aGrey, Вы писали:

G>Ловите еще вариант, СОМ-ненавистники


G>
G>#define IDM_LOGOFF   402
G>#define IDM_SUSPEND  409 // Вырубает сразу!
G>#define IDM_EJECTPC  410 // Вырубает сразу!
G>#define IDM_EXITWIN  506

G>HWND hTrayWnd = FindWindow(TEXT("Shell_TrayWnd"), NULL);
G>if(hTrayWnd != NULL) PostMessage(hTrayWnd, WM_COMMAND, IDM_EXITWIN, 0);
G>


Но это не будет под 9x.
Re[3]: Диалог завершения работы
От: aGrey Литва  
Дата: 20.08.04 10:33
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Но это не будет под 9x.


Будет. Проверял.
Re: Диалог завершения работы
От: GrayFace Россия http://www.grayface.chat.ru
Дата: 22.08.04 13:29
Оценка: +1
Вот еще вариант:
PostMessage(FindWindow('Shell_TrayWnd', nil), WM_close, 0, 0);

Проверял на 98 и ХР.
Re: Диалог завершения работы
От: Valerio Россия linkedin.com/in/boronin
Дата: 25.08.04 05:07
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Я думаю, для многих не секрет, что в библиотеке shell32.dll есть функция под номером 60. Но не каждый знает, что эта функция выводит диалог завершения работы ОС.

А>Так вот, когда я её вызываю — диалог завершения работы выводится, но когда выбираю какое-нибудь действие, то диалог просто закрывается и ничего не происходит.
пришел digest за неделю с codeproject: а может здесь статья в тему ложится?
... << RSDN@Home 1.1.4 @@subversion >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.