Windows에서의 wget
, 다른 프로세스 제어
나는 운영체제를 자주 설치하는 편이다. 뭐 이런저런 이유가 있지만 하드카피기기가 없는것이 가장 큰 이유이다.
Linux야 bash나 perl로 설치 명령어만 써주면 자동으로 인스톨이 슥슥 되지만,
CLI 기반의 설치가 아닌 Windows에서는 그것이 쉽지가 않다….
따라서 먼저 wget과 같은 함수로 installer 파일을 받아야한다.
다행이 이 함수는 존재한다.
#include<urlmon.h> //URLDownloadToFileA
#pragma comment(lib,"urlmon.lib")
static char* url = "http://www.bandisoft.co.kr/bandizip/dl.php?web";
static char* file = "BANDIZIP-SETUP-KR.EXE";
int main(){
...
if (URLDownloadToFileA(NULL, url, file, 0, 0) == S_OK){
InstallBandiZip();
}
...
return 0;
}
사용법은 위의 소스를 보면 쉽게 알 수 있다.
이제 WinExec로 해당 프로그램을 실행 시킨후 spy++로 해당 윈도우의 class나 name을 알아온후
FindWindow함수로 HWND을 얻어온다.
자식 HWND를 알고싶다면 FindWindowEx 함수를 사용한다.
아래는 전체 소스이다.
#include<stdio.h> //puts , printf , remove
#include<stdlib.h> //EXIT_FAILURE
#include<time.h>
#include<stdbool.h>
#include<urlmon.h> //URLDownloadToFileA
#pragma comment(lib,"urlmon.lib")
#include<shellapi.h> //SHELLEXECUTEINFOA
#include<synchapi.h> //WaitForSingleObject Sleep
#include<winnt.h> //SID_IDENTIFIER_AUTHORITY , PSID
#include<securitybaseapi.h> //AllocateAndInitializeSid, CheckTokenMembership, FreeSid
#include<windef.h> //HWND
#include<WinUser.h> //FindWindowA , FindWindowEx , SendMessageA
#define PRINT_HWND(H) printf("%x\n",(H))
void InstallBandiZip() {
char* url = "http://www.bandisoft.co.kr/bandizip/dl.php?web";
char* file = "BANDIZIP-SETUP-KR.EXE";
if (URLDownloadToFileA(NULL, url, file, 0, 0) == S_OK) {
HWND hwnd;
//If the function succeeds, the return value is greater than 31.
if (WinExec(file, SW_SHOW) <= 31) {
puts("[ERROR] 반디집 설치프로그램 실행 실패");
return;
}
puts("반디집 설치 프로그램 실행...");
if ((hwnd = FindWindowA("#32770", "반디집 설치")) == 0) {
puts("[ERROR] 반디집 자동설치 실패. 수동으로 설치하세요");
return;
}
HWND view = 0;
HWND lp = 0;
do { //핸들을 순회하면서 inner form을 찾습니다.
view = lp;
lp = FindWindowExA(hwnd, lp, NULL, NULL);
} while (lp);
char* option[2] = { "프로그램 그룹 생성", "압축 파일 확장자 연결" };
HWND combo1 = FindWindowExA(view, NULL, "Button", option[0]);
HWND combo2 = FindWindowExA(view, NULL, "Button", option[1]);
SendMessageA(combo1, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
SendMessageA(combo2, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
printf("%s 설치옵션 체크\n", option[0]);
printf("%s 설치옵션 체크\n", option[1]);
HWND ok = FindWindowExA(hwnd, NULL, "Button", "설치");
SendMessageA(ok, BM_CLICK, (WPARAM)0, (LPARAM)0);
WaitForSingleObject(hwnd, INFINITE);
//반디집은 설치후에 프로그램이 뜨나 필요없기에 뜰때까지 기다렸다가 닫아준다.
while ((hwnd = FindWindowA("BandiZipClass", NULL)) == 0) {
Sleep(100);
}
SendMessageA(hwnd, WM_CLOSE, (WPARAM)0, (LPARAM)0);
puts("[SUCCESS] 반디집 설치 완료");
remove(file);
}
else {
puts("[ERROR] 반디집 다운로드 실패");
}
}
BOOL IsUserAdmin(void) {
BOOL b;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
if (b) {
if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) {
b = FALSE;
}
FreeSid(AdministratorsGroup);
}
return b;
}
int main(void) {
if (IsUserAdmin() == FALSE) {
puts("[ERROR] : 관리자 권한으로 실행 하세요");
Sleep(1000);
exit(EXIT_FAILURE);
}
InstallBandiZip();
return 0;
}