[C] 반디집 자동설치 프로그램

spring·2020년 11월 9일
0

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;
    }
profile
Researcher & Developer @ NAVER Corp | Designer @ HONGIK Univ.

0개의 댓글