비주얼베이직을 이용한 컴퓨터종료, 시스템관리자 켜는것좀 도와주세요

Posted by 겨울에
2011. 2. 4. 01:55 scrap/ Visual Basic
질문: 비주얼베이직을 이용한 컴퓨터종료, 시스템관리자 켜는것좀 도와주세요
2009-01-09 10:52

이 그림처럼 해서 시스템종료를 선택하고 command2 를 누르면 시스템 종료가 되고,
작업관리자를 선택하고 command2 를 누르면 작업관리자가 열리는 것 어떻게 하는지좀 알려주세요 !!




답변: re: 비주얼베이직을 이용한 컴퓨터종료, 시스템관리자 켜는것좀 도와주세요
2009-01-09 11:27

시스템을 종료하기 위해서는 Api를 사용해야 할듯 합니다.
그리고 작업관리자를 실행하시는 것은 생각보다 간단합니다.
 
작업관리자의 실행 파일은 c:\windows\system32\taskmgr.exe 입니다.
 
따라서 command2의 소스에
 
Shell "c:\windows\system32\taskmgr.exe", vbnormalFocus
 
이렇게 추가해 주시면 됩니다.
 
시스템 종료 api는 내용이 좀 복잡한듯 보이지만 아래 내용을 참조하시기 바랍니다.
 
ExitWindowsEx
InitiateSystemShutdown
NtShutdownSystem
 
먼저, ExitWindowsEx() 에 관하여 알아봅시다.
이 함수는 성공시 TRUE, 실패시 FALSE를 반환합니다.
WINUSERAPI
BOOL
WINAPI
ExitWindowsEx(
    DWORD dwFlags,
    DWORD dwReserved);
 
dwFlags에는 일반적으로 다음과 같은 상수들이 들어갑니다.
EWX_LOGOFF : 시스템을 로그오프시킨다.
EWX_SHUTDOWN : 시스템을 종료시킨다. (전원이 꺼지지 않는경우도 있다)
EWX_REBOOT : 시스템을 재시작시킨다.
EWX_FORCE : 이 옵션이 들어가면 실행중인 프로그램을 강제종료한다
EWX_POWEROFF : 이 옵션이 들어가면 전원을 완전히 끈다.
그리고, 이 상수들은 조합해서 쓸 수도 있습니다.
예를 들면, "실행중 프로그램을 강제종료시키고 시스템을 종료하고 싶다" 면,
dwFlags에는 EWX_SHUTDOWN | EWX_FORCE가 들어가면 되는 것입니다.
 
dwReserved에는 0xFFFFFFFF가 들어가는 것 같습니다.
헤더 파일에도 정의된 것이 있긴 있는것 같습니다.
#define ExitWindows(dwReserved, Code) ExitWindowsEx(EWX_LOGOFF, 0xFFFFFFFF)
자 이번에는 InitiateSystemShutdown()에 대해 알아보겠습니다.
이 함수는 호출시 프로세스 winlogon.exe에 시스템 종료 Message가 담긴 창을 띄워서
시스템 종료까지의 남은 시간을 표시해 줍니다. 남은 시간이 0:00:00이 되면, 시스템은 종료됩니다.
성공시 TRUE, 실패시 FALSE를 반환합니다.
여기서부터 나오는 함수는, Windows 9x는 지원하지 않습니다!!!!
WINADVAPI
BOOL
WINAPI
InitiateSystemShutdownA(
    IN LPSTR lpMachineName,
    IN LPSTR lpMessage,
    IN DWORD dwTimeout,
    IN BOOL bForceAppsClosed,
    IN BOOL bRebootAfterShutdown);
lpMachineName : 종료할 컴퓨터의 이름으로 보여집니다. 일반적으로 NULL
lpMessage : 시스템 종료시 띄울 Message
dwTimeout : 시스템 종료까지의 시간(초)
bForceAppsClosed : 시스템 종료시 프로그램을 강제종료할 것인가의 여부.
bRebootAfterShutdown : 시스템 종료 후에 재부팅 할것인지의 여부
또한, 이 함수로 시작된 시스템 종료는, 시스템 종료까지의 시간이 만기되기 전에 취소할 수 있는데,
이 역할을 하는 함수가 AbortSystemShutdown()입니다.
WINADVAPI
BOOL
WINAPI
AbortSystemShutdownA(
    IN LPSTR lpMachineName);
lpMachineName : 위의 설명과 같다.
 
이제는 좀 특별한 API인 NtShutdownSystem() 에 대해 알아보겠습니다.
이 함수는 다른 함수와는 좀 달리, 설정 저장 없이, 바로 시스템을 종료시킵니다.
성공시 STATUS_SUCCESS를 반환합니다.
STATUS_SUCCESS는 다음으로 정의됩니다:
#define STATUS_SUCCESS            (NTSTATUS)0
NTSYSAPI
NTSTATUS
NTAPI
NtShutdownSystem(
    IN SHUTDOWN_ACTION ShutdownAction);
ShutdownAction : 종료방법(말하자면 옵션).
SHUTDOWN_ACTION은 enum으로 되어있습니다.
typedef enum _SHUTDOWN_ACTION {
    ShutdownNoReboot,
    ShutdownReboot,
    ShutdownPowerOff
} SHUTDOWN_ACTION, *PSHUTDOWN_ACTION;
ShutdownNoReboot : 시스템을 종료하나, 재시작하지 않는다. (전원은 꺼지지 않는 것 같다.)
ShutdownReboot : 시스템을 재시작한다.
ShutdownPowerOff : 시스템 종료 후 전원을 끈다. 만일 하드웨어가 이 기능을 지원하지 않으면,  ShutdownReboot를 수행한다.
 
하지만, Windows NT/2K/XP/... 등에서 이를 사용하기 위해서는 Shutdown 권한이 있어야 합니다.
따라서, 권한을 얻어야 하는데, 그 일을 하는 함수가 바로, NTDLL.DLL의 RtlAdjustPrivilege()입니다.
OpenProcessToken()->LookupPrivilegeValue()->AdjustTokenPrivileges() 를 하는 방법도 있지만,
여기에서는 글이 약간 길어지므로 이 글에서는 다루지 않도록 하겠습니다.
NTSYSAPI
NTSTATUS
NTAPI
RtlAdjustPrivilege(
    ULONG Privilege,
    BOOL bEnable,
    BOOL bIsCurrentThread,
    PULONG PreviousPrivilege);
Privilege : LookupPrivilegeValue()로 얻어온 권한의 값(좀 설명이 애매하군요). Index.
bEnable : 권한을 설정할것인지의 여부. 일반적으로 TRUE.
bIsCurrentThread : 현재 쓰레드에 대하여인지의 여부. (테스트 결과, FALSE를 선택하면 프로세스 전체에 대해서인것 같다.)
일반적으로 FALSE.
PreviousPrivilege : 이전의 권한이 이 인자로 넘어온다.
예를 들어서, Debug 권한을 얻고 싶으면
ULONG PreviousPrivilege;
RtlAdjustPrivilege(20, TRUE, FALSE, &PreviousPrivilege)
를 해주면 될겁니다.