원문에서는 XP만 다루고 있지만 Windows 7에서도 잘 작동한다.
우선 아래 명령으로 자동으로 청소할 항목을 선택한다.
cleanmgr /SAGESET:1
여기서 1은 원하는 숫자를 사용하면 된다. 청소할 항목을 지정했으면, 아래 명령으로 지정한 항목을 청소시킬 수 있다.
cleanmgr /SAGERUN:1
원문에서는 XP만 다루고 있지만 Windows 7에서도 잘 작동한다.
우선 아래 명령으로 자동으로 청소할 항목을 선택한다.
cleanmgr /SAGESET:1
여기서 1은 원하는 숫자를 사용하면 된다. 청소할 항목을 지정했으면, 아래 명령으로 지정한 항목을 청소시킬 수 있다.
cleanmgr /SAGERUN:1
아래와 같은 csv 파일이 있다고 가정한다.
a,1 b,2 c,3 d,4 e,5
위 파일에서 두 번째 열의 숫자를 모두 합하고 싶다면 아래와 같이 하면 된다.
cat test.csv | awk -F "," '{sum += $2} END {print sum}'
find와 wc를 사용하면 된다.
wc --lines `find ./ -type f \( -name "*.c" -or -name "*.cpp" -or -name "*.asm" -name "*.h" \)`
이미 등록된 제품 번호를 변경하고 다시 인증을 받는 방법을 설명한다.
관리자 권한으로 cmd 창을 열고 아래 명령을 차례대로 입력한다.
cscript %windir%\system32\slmgr.vbs /upk cscript %windir%\system32\slmgr.vbs /ipk 제품번호 cscript %windir%\system32\slmgr.vbs /ato제품 번호는 XXXXX-XXXXX-XXXXX-XXXXX-XXXXX 형식을 사용하면 된다.
ctypes를 이용해 Win32 환경에서 작업하는 예제 기록.
ctypes.wintypes를 참고한다.
WCHAR [1000]의 배열을 선언한다고하면
FileNameType = c_wchar * 1000
a = FileNameType()
SYSTEM_INFO 구조체는 아래와 같이 역명 구조체와 공용체를 가지고 있다.
typedef struct _SYSTEM_INFO {
union {
DWORD dwOemId;
struct {
WORD wProcessorArchitecture;
WORD wReserved;
};
};
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD_PTR dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
} SYSTEM_INFO;
이 구조체를 ctypes로 표시하면 아래와 같다.
class _Noname1(ctypes.Structure):
_fields_ = [("wProcessorArchitecture", ctypes.c_ushort),
("wReserved", ctypes.c_short)]
class _Noname2(ctypes.Union):
_anonymous_ = ("s",)
_fields_ = [('dwOemId', ctypes.c_ulong),
('s', _Noname1)]
class SYSTEM_INFO(ctypes.Structure):
_anonymous_ = ("u",)
_fields_ = [("u", _Noname2),
("dwPageSize", ctypes.c_ulong),
("lpMinimumApplicationAddress", ctypes.c_void_p),
("lpMaximumApplicationAddress", ctypes.c_void_p),
("dwActiveProcessorMask", ctypes.c_ulong), # 64 bit에서는 c_longlong이 되어야 한다.
("dwNumberOfProcessors", ctypes.c_ulong),
("dwProcessorType", ctypes.c_ulong),
("dwAllocationGranularity", ctypes.c_ulong),
("wProcessorLevel", ctypes.c_ushort),
("wProcessorRevision", ctypes.c_ushort)]
위에서 선언한 SYSTEM_INFO에 대한 pointer type으로 LPSYSTEM_INFO을 선언한다고 하면
LPSYSTEM_INFO = ctypes.POINTER(SYSTEM_INFO)
ctypes.LP_c_char를 ctypes.c_char_p로 형변환하면 된다.
ctypes.cast(ctypes.LP_c_char 객체, ctypes.c_char_p).value
ctypes.windll뒤에 원하는 dll 모듈과 함수를 사용하면 된다. 예를 들어 kernel32의 GetsystemInfo함수를 호출한다면 아래와 같이 호출할 수 있다.
ctypes.windll.kernel32.GetsystemInfo( ... )
test1.dll의 void __cdecl testfunction1() 함수를 호출한다고 하면
test1 = ctypes.CDLL('test1.dll')
if test1:
test1.testfunction1()
si = SYSTEM_INFO()
ctypes.windll.kernel32.GetSystemInfo(ctypes.byref(si))
buf = ctypes.create_unicode_buffer(4096)
r = ctypes.windll.kernel32.GetWindowsDirectoryW(buf, 4096)
if r > 0:
print buf.value
함수 객체의 errcheck를 지정하면 함수의 반환값 검사를 모아서 할 수 있다. 예를 들어 test2.dll의 BOOL __cdecl testfunction2() 함수에 대해서 코드를 작성해보면 아래와 같다.
>def checkBOOL(result, function, args):
if result == 0:
raise ctypes.WinError()
return args
test2 = ctypes.CDLL('test2.dll')
test2.testfunction2.errcheck = checkBOOL
test2.testfunction2() # 함수 호출이 끝나면 바로 checkBOOL 함수가 호출되서 반환값 검사를 할 수 있다.
함수 객체의 argtypes를 이용해서 함수의 인자를 명시적으로 지정할 수 있다. 예를 들어 test3.dll의 BOOL __cdecl testfunction3(LPCWSTR, LPBOOL)에 대해서 코드를 작성해보면 아래와 같다.
test3 = ctypes.CDLL('test3.dll')
test3.testfunction3.argtypes = [ctypes.c_wchar_p, ctypes.POINTER(ctypes.c_long)]
b = ctypes.c_long()
r = test3.testfunction3(u"hello, world!", ctype.byref(b))
함수 객체의 restype을 시용해서 함수의 반환형을 명시적으로 지정할 수 있다(함수 반환형이 void라면 None을 사용한다). 예를 들어 test4.dll의 HANDLE __cdecl testfunction4()에 대해서 코드를 작성해보면 아래와 같다.
test4 = ctypes.CDLL('test4.dll')
test4.testfunction4.restype = ctypes.c_void_p
h = test4.testfunction4()
callback 함수 형식에 따라 ctypes.CFUNCTYPE 또는 ctypes.WINFUNCTYPE을 사용해서 callback 함수 형을 만들면 된다.
python 문서에 나온 예제를 Win32에 맞게 변형했다.
CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
def py_cmp_func(a, b):
print 'py_cmp_func', a[0], b[0]
return 0
cmp_func = CMPFUNC(py_cmp_func)
IntArray5 = ctypes.c_int * 5
ia = IntArray5(5, 1, 7, 33, 99)
qsort = ctypes.windll.msvcrt.qsort
qsort.restype = None
qsort(ia, len(ia), ctypes.sizeof(ctypes.c_int), cmp_func)
LF_FACESIZE = 32
LF_FULLFACESIZE = 64
class LOGFONT(ctypes.Structure):
_fields_ = [
('lfHeight', ctypes.c_long),
('lfWidth', ctypes.c_long),
('lfEscapement', ctypes.c_long),
('lfOrientation', ctypes.c_long),
('lfWeight', ctypes.c_long),
('lfItalic', ctypes.c_byte),
('lfUnderline', ctypes.c_byte),
('lfStrikeOut', ctypes.c_byte),
('lfCharSet', ctypes.c_byte),
('lfOutPrecision', ctypes.c_byte),
('lfClipPrecision', ctypes.c_byte),
('lfQuality', ctypes.c_byte),
('lfPitchAndFamily', ctypes.c_byte),
('lfFaceName', ctypes.c_wchar * LF_FACESIZE)]
PLOGFONT = ctypes.POINTER(LOGFONT)
class ENUMLOGFONT(ctypes.Structure):
_fields_ = [
('elfLogFont', LOGFONT),
('elfFullName', ctypes.c_wchar * LF_FULLFACESIZE),
('elfStyle', ctypes.c_wchar * LF_FACESIZE)]
PENUMLOGFONT = ctypes.POINTER(ENUMLOGFONT)
if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p):
LPARAM = ctypes.c_long
elif ctypes.sizeof(ctypes.c_longlong) == ctypes.sizeof(ctypes.c_void_p):
LPARAM = ctypes.c_longlong
#int CALLBACK EnumFontFamProc(ENUMLOGFONT *lpelf,__in NEWTEXTMETRIC *lpntm, DWORD FontType, LPARAM lParam;
EnumFontFamProc = ctypes.WINFUNCTYPE(ctypes.c_int, PENUMLOGFONT, ctypes.c_void_p, ctypes.c_long, LPARAM)
def py_enum_font_fam_proc(lpelf, lpntm, FontType, lparam):
print 'py_enum_font_fam_proc', lpelf.contents.elfFullName
return 1
enum_font_proc = EnumFontFamProc(py_enum_font_fam_proc)
EnumFontFamilies = ctypes.windll.gdi32.EnumFontFamiliesW
hdc = ctypes.windll.user32.GetDC(0)
EnumFontFamilies(hdc, 0, enum_font_proc, 0)
ctypes.windll.user32.ReleaseDC(hdc)
cygwin에서 Windows 프로그램 개발을 위한 Makefile template.
BASECFLAGS = -DUNICODE -D_UNICODE -DWIN32 -D_WIN32 -Wall -Wextra -ffunction-sections -fdata-sections
CXXFLAGS = -fno-rtti -fno-exceptions
ifdef debug
OPTFLAGS = -g -DDEBUG -Wall -Wextra -Wfloat-equal -Wunreachable-code
else
OPTFLAGS = -Os -s -DNDEBUG
endif
ifdef x64
MINGWPREFIX = x86_64-w64-mingw32
CFLAGS = $(BASECFLAGS) $(OPTFLAGS) -DWIN64 -D_WIN64
else
MINGWPREFIX = i686-pc-mingw32
CFLAGS = $(BASECFLAGS) $(OPTFLAGS)
endif
LDFLAGS = -Wl,--gc-sections -mwindows -mno-cygwin
CC = $(MINGWPREFIX)-gcc
CXX = $(MINGWPREFIX)-g++
RES = $(MINGWPREFIX)-windres
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
%.o: %.cpp
$(CXX) $(CFLAGS) $(CXXFLAGS) -c $< -o $@
%.res.o: %.rc
$(RES) -i $< -o $@
위 Makefile은 아래와 같이 사용할 수 있다.
디버그 빌드시
$ make debug=1
x64 빌드시
$ make x64=1