<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>개발관련 :: 카테고리 :: 모두의프린터</title><link>https://modu-print.com/categories/%EA%B0%9C%EB%B0%9C%EA%B4%80%EB%A0%A8/</link><description/><generator>Hugo</generator><language>ko-KR</language><lastBuildDate>Thu, 22 Oct 2026 13:31:53 +0900</lastBuildDate><atom:link href="https://modu-print.com/categories/%EA%B0%9C%EB%B0%9C%EA%B4%80%EB%A0%A8/index.xml" rel="self" type="application/rss+xml"/><item><title>Google Gemini 4 Argon 짧은 소감.</title><link>https://modu-print.com/posts/18163/</link><pubDate>Fri, 16 Oct 2026 16:42:46 +0900</pubDate><guid>https://modu-print.com/posts/18163/</guid><description>구글은 현재 Ultra 하나 Pro 하나 이렇게 2개 계정을 돌리고 있습니다만 .. 사용량 자체를 Gemini 4 Argon 은 아에 분리를 해 두긴 했습니다만.&#10;진짜 ..&#10;작업물 수준은 Flash 모델들 대비해서 꽤 좋게 올라온건 사실인데. 문제는 ..</description></item><item><title>ds4.c(DwarfStar 4) + Deepseek-v4.1-flash 사용기</title><link>https://modu-print.com/posts/18142/</link><pubDate>Thu, 15 Oct 2026 08:42:33 +0900</pubDate><guid>https://modu-print.com/posts/18142/</guid><description>ds4.c 가 Deepseek 모델 외에도 Glm, Qwen 다양한 모델을 지원하기 시작하면서 부터는 기존에 같이 사용하던 omlx, llama.cpp, mlx-ml등 다른 추론엔진들은 전부 제거하고 ds4.c 하나만 local llm에 사용중입니다.&#10;앞서 다른 글에서도 언급한적 있지만 Deepseek v4 flash 0731와 Dspark가 적용된 뒤로는 ds4.c에 남은 아쉬움 이라고는 모델 자체가 vision을 지원하지 않는다는 것, 별도로 나온 Deepseek v4 vision의 경우 기본적인 지능이 0731과 차이가 나서 코딩 작업에 사용하기 좀 아쉬웠다?</description></item><item><title>DWARFSTAR(ds4.c) 최근 사용기..</title><link>https://modu-print.com/posts/17886/</link><pubDate>Tue, 15 Sep 2026 12:36:08 +0900</pubDate><guid>https://modu-print.com/posts/17886/</guid><description>GitHub - antirez/ds4: DeepSeek 4 Flash and PRO local inference engine for Metal, CUDA and ROCm DeepSeek 4 Flash and PRO local inference engine for Metal, CUDA and ROCm - antirez/ds4 Redis 개발자로 유명한 Antirez의 ds4.c 가 정말 하루가 다르게 엄청나게 발전을 하고 하나둘씩 다양한 모델을 지원하기 시작하면서 ..</description></item><item><title>pmux (Terminal Multiplexer for Windows) - 윈도용 tmux 비슷한거</title><link>https://modu-print.com/posts/17711/</link><pubDate>Fri, 14 Aug 2026 19:20:54 +0900</pubDate><guid>https://modu-print.com/posts/17711/</guid><description>리눅스, MacOS에서는 tmux 를 자주 사용하는 편입니다. 윈도에서는 MS의 윈도 터미널앱을 자주 애용하고 있구요, cmux니 뭐니 이것저것 나왔다는건 알고 있지만 개인적으로는 MS의 윈도 터미널앱도 git bash 나 msys2의 MINGW64, CLANG64 환경등을 바로 사용 가능해서 아주 잘 쓰고 있습니다...만!&#10;다 좋은데 저는 보통 한 프로젝트에 여러 AI Cli를 쓰는 편이고 gitui로 커밋 안된 수정사항등을 띄워놓고 빌드용 콘솔도 몇개 띄워야 하는 경우등을 포함해서 보통 4~5개 정도로 분할된 여러 터미널을 한 화면에 놓고 써버릇 합니다.</description></item><item><title>DWARFSTAR(ds4.c) DSpark 업데이트</title><link>https://modu-print.com/posts/17288/</link><pubDate>Sun, 26 Jul 2026 21:12:20 +0900</pubDate><guid>https://modu-print.com/posts/17288/</guid><description>GitHub - antirez/ds4: DeepSeek 4 Flash and PRO local inference engine for Metal, CUDA and ROCm DeepSeek 4 Flash and PRO local inference engine for Metal, CUDA and ROCm - antirez/ds4 일전에 ds4.c 관련해서 꽤나 긍정적인 방향으로 글을 몇 번 써 왔습니다만. 여전히 ds4.c를 통해 LocalLLM으로 Deepseek-v4-flash를 잘 사용하고 있습니다.</description></item><item><title>Deepseek v4 API 서비스 사용기</title><link>https://modu-print.com/posts/16988/</link><pubDate>Tue, 09 Jun 2026 10:19:37 +0900</pubDate><guid>https://modu-print.com/posts/16988/</guid><description>최근에 DS4.c 를 활용해서 LocalLLM 으로 Deepseek v4 Flash 모델을 정말 잘 활용 해 오고 있었습니다. 그런 와중에 DS4.c 에서 Pro 모델에 대한 지원도 추가를 해줘서 Pro 모델도 살짝 돌려보긴 했습니다만. Flash 모델의 경우도 25tps 정도로 약간 답답한 속도를 보여 줫는데 Pro 모델의 경우 모델을 로딩만 해도 일단 512g 의 통합 메모리인 맥 스튜디오 m3 Ultra 라 해도 1M 컨텍스트는 꿈도 못꿉니다. 컨텍스트 타협을 해야 돌려는 볼 수 있고 속도 자체도 5~7tps 정도로 나와서 .. 사실 실 사용 하기엔 좀 많이 답답합니다.</description></item><item><title>DS4.c(DwarfStar 4) - Deepseek-v4-flash 2주 사용후기</title><link>https://modu-print.com/posts/16948/</link><pubDate>Sun, 24 May 2026 20:15:36 +0900</pubDate><guid>https://modu-print.com/posts/16948/</guid><description>GitHub - antirez/ds4: DeepSeek 4 Flash local inference engine for Metal and CUDA DeepSeek 4 Flash local inference engine for Metal and CUDA - antirez/ds4 DwarfStar4 (ds4.c) DeepSeek v4 Flash만을 위한 추론 엔진 앞서 DS4.c 에 대해 간단히 글을 작성 했는데요, 대략 거의 코딩을 위한 로컬LLM은 Claude Code + DS4.c(Deepseek-v4-flash) 만으로 2주를 보낸 것 같습니다.</description></item><item><title>DwarfStar4 (ds4.c) DeepSeek v4 Flash만을 위한 추론 엔진</title><link>https://modu-print.com/posts/16908/</link><pubDate>Fri, 15 May 2026 15:49:54 +0900</pubDate><guid>https://modu-print.com/posts/16908/</guid><description>앞서 몇몇 글에서도 DeepSeek v4 Flash 에 대해서 좀 기대를 하고 있단 말을 적었습니다만 .. 아직 llama.cpp 쪽에서 deepseek v4 에 대해서 작업이 끝나지 못해서 인지 어떤 이유인지 모르지만 아직 LM Studio 나 Ollama 에 클라우드용 모델외에 직접 다운로드 해서 쓸수 있는 형태로 업데이트가 올라오고 있진 않습니다.&#10;이미 HuggingFace 에 이런저런 양자화 모델로 등장을 하고 있는지도 꽤 지났는데 말이죠 ..&#10;그런 와중에 제 기준으론 꽤 반가운 놈이 출시가 되어서 어제부터 이짓 저짓에 매우 열심히 써보고 있습니다.</description></item><item><title>Qwen 3.6 / 35b a3b / 27b / 4bit, 8bit, mlx / etc</title><link>https://modu-print.com/posts/16787/</link><pubDate>Sun, 03 May 2026 10:07:21 +0900</pubDate><guid>https://modu-print.com/posts/16787/</guid><description>다양한 모델을 테스트하며 2주간 1억 토큰 이상의 개발 작업을 진행해 본 결과, 당분간은 Qwen 3.6 35b a3b 모델을 LM Studio와 Claude Code 환경에서 주력으로 사용할 계획입니다.&#10;Deepseek-V4 Flash가 기대되긴 하지만, 어째서인지 아직 LM Studio에는 관련 업데이트가 진행되지 않고 있습니다. Hugging Face에는 이미 모델들이 올라오고 있음에도 말이죠. 현재 제 활용 범위에서는 LM Studio를 벗어날 이유가 없기에 조금 더 기다려보려 합니다.&#10;DeepSeek-V4 Pro의 경우 양자화를 타협한다면 구동은 가능할 것입니다. 다만 타협을 잘 해도 2-bit 양자화 정도가 한계일 텐데, 아무리 MoE 구조로 1.6T 파라미터 중 49B만 활성화된다고 해도 30B급 Dense 모델들이 보통 10~20 TPS 내외인 점을 고려하면, 49B 활성 파라미터 모델의 속도 또한 충분히 예측 가능합니다. 따라서 실사용하기에는 다소 답답할 것으로 보입니다.</description></item><item><title>Unsloth/Qwen-3.6-27b</title><link>https://modu-print.com/posts/16765/</link><pubDate>Fri, 24 Apr 2026 11:33:53 +0900</pubDate><guid>https://modu-print.com/posts/16765/</guid><description>qwen-3.6-27b 모델을 Unsloth 에서 파인튜닝한 모델을 받아서 돌려 봤습니다. 양자화는 Q8_K_XL 입니다.&#10;앞서 글 올린 Qwen-3.6-36b-a3b 는 MoE 모델이라 대충 70~80Tps 정도의 속도가 나왔는데, 역시나 Dense모델인 27b는 속도가 생각보다 많이 느리네요.&#10;물론 Metal 가속을 사용하는 맥의 특성일수도 있고 Nividia랑 친한 Unsloth 에서 파인튜닝한 UD모델을 사용해서 더 그럴순 있겠습니다만.&#10;앞서 글 올린 Qwen-3.6-35b-a3b 의 경우도 동일하게 Unsloth 에서 파인튜닝한 Q8_K_XL UD 모델이었습니다.</description></item><item><title>LM Studio + Unsloth/Qwen-3.6-35b-a3b</title><link>https://modu-print.com/posts/16738/</link><pubDate>Fri, 24 Apr 2026 06:52:51 +0900</pubDate><guid>https://modu-print.com/posts/16738/</guid><description>최근 오픈소스 AI 모델은 중국쪽이 열일 하는 느낌입니다. 클로드 코드를 학습하고 있다느니 어쩌느니 이러쿵 저러쿵 말도 많긴 합니다만, 현실적으로 개인 사용자들이 사용 가능한 범주 내에서 의미 있는 모델을 주기적으로 계속 배포하고 있는 면에서는 Qwen이 가장 활발한 편이라고 볼 수 있겠네요.&#10;Qwen 3.6 과 관련해서는 클라우드 서비스 쪽에 Qwen 3.6 Plus 연나.. 여튼 클라우드 전용 모델로 먼저 공개된 모델이 평이 워낙 좋았어서 기대는 하고 있었습니다.</description></item><item><title>LM Studio + Claude Code + AdamBench prompt</title><link>https://modu-print.com/posts/16489/</link><pubDate>Sat, 04 Apr 2026 09:47:35 +0900</pubDate><guid>https://modu-print.com/posts/16489/</guid><description>LocalLLM 을 활용하다 보면 가장 많이 하게 되는 짓이 수 많은 모델들 중에 무엇을 사용해야 할지와 다운로드 받은 모델이 쓸만 할지 판단하는게 꽤나 귀찮은 일입니다.&#10;저는 최근에는 Claude Code 의 환경변수와 설정파일을 수정해서 Claude Code 는 Opus, Sonnet, Haiku 인주 알고 돌겠지만 실제로는 제 Mac Studio M3 Ultra(512gb ram)에서 동작중인 LM Studio 의 모델들로 돌아가게 되는 식으로 설정을 변경해서 사용중인데요..&#10;이게 모델 교체를 해서 쓰려면 환경변수든 설정파일이든 수정을 해서 써야하는데 꽤 귀찮기도하고 ..</description></item><item><title>IDE 자동완성용 모델 추천 - Qwen2.5-coder-3b-instruct</title><link>https://modu-print.com/posts/16445/</link><pubDate>Sat, 28 Mar 2026 22:47:16 +0900</pubDate><guid>https://modu-print.com/posts/16445/</guid><description>비개발자들은 Ai를 업무 자동화나 채팅을 통한 정보수집? 문제해결? 그런 용도로 가장 많이 사용하지만 개발자들의 경우 IDE에서 코드작성시 코드 자동완성에 도움을 주는 방식으로도 많이 사용하십니다.&#10;Github의 Copilot이 어찌보면 선두주자였는데 지금은 좀 아쉽죠?&#10;물론 클로드 코드 등장으로 코드작성은 개발자가 더이상 하지 않아도 된다느니 딸깍? 해줘? 하면 그만이고 코드한줄 보지 않고 무언갈 완성 했다느니 하는 시절이긴 합니다만..&#10;그럼에도 불구하고 세상의 모든 개발자들이 더이상 코드작성을 하지 않고 ide를 사용하지 않는건 아니니까요.</description></item><item><title>LM Studio 업데이트 후 TPS 급감현상</title><link>https://modu-print.com/posts/16426/</link><pubDate>Wed, 25 Mar 2026 03:26:02 +0900</pubDate><guid>https://modu-print.com/posts/16426/</guid><description>mlx-ml, vLLM, Ollama 등도 새버전이 나오곤 하면 테스트겸 가끔 사용하긴 합니다만, 주력으로 사용중인건 LM Studio 인데요.&#10;LLM관련은 업데이트가 워낙 잦고 주기도 빠른지라 하루가 멀다하고 새버전이 나옵니다. 앱 자체의 기능 추가나 버그수정일수도 있고 llama.cpp 같은 Ai 관련 런타임의 변경일수도 있습니다만..&#10;LM Studio의 경우에는 실행시 새버전이 존재하면 업데이트 여부를 묻고 자동으로 업데이트를 진행 하도록 만들어진 프로그램인데요, 희한한 현상을 하나 겪어서 공유합니다.</description></item><item><title>TTS/Voice Clone MimikaStudio</title><link>https://modu-print.com/posts/16377/</link><pubDate>Thu, 19 Mar 2026 23:44:09 +0900</pubDate><guid>https://modu-print.com/posts/16377/</guid><description>제가 무슨 유명한 유튜버도 아니고 유튜브 영상은 주로 모두의 프린터 사용법 관련된 영상을 만드는게 전부긴 합니다만, 그래도 최근에는 TTS 를 통한 음성도 영상에 포함해서 만들고 있습니다.&#10;최근에는 Typecast 라는 서비스를 구독해서 음성을 만들곤 햇습니다만, 영상을 자주 만드는 것도 아니고 보통은 기존 영상에 수정이 필요한 몇 분 내외의 음성데이터만 필요한데 계속 구독을 하는 것도 좀 돈이 아깝긴 하더라구요.&#10;보통 TTS 에 필요한 모델들은 코딩 에이전트등에 쓰이는 추론 모델들에 비해서는 매우 크기가 작은 편에 속합니다. 보통 8기가 이상의 VRAM 을 가진 NVIDIA GPU 라면 돌려 볼 수 있는 모델들이 꽤 있으니 512GB의 맥 스튜디오를 사용하는 제 입장으론 TTS 쪽은 직접 설치해서 써도 충분한 영역이긴 합니다.</description></item><item><title>Unsloth Studio 출시..</title><link>https://modu-print.com/posts/16359/</link><pubDate>Wed, 18 Mar 2026 17:24:28 +0900</pubDate><guid>https://modu-print.com/posts/16359/</guid><description>Introducing Unsloth Studio | Unsloth Documentation Run and train AI models locally with Unsloth Studio. 최근에 올린 LLM 관련 글들에서 Unsloth 를 많이 언급해 왔습니다.&#10;아직까지 Unsloth 프로젝트는 어쨌든 Nvidia GPU와 CUDA와 좀더 친한건 사실인데요. 그래서 mlx 모델들 대비 mlx 지원 않는 GGUF 모델이 1~20% 정도 성능이 떨어집니다.&#10;그럼에도 불구하고 맥스튜디오 M3 Ultra, 그러니까 애플 실리콘 기반의 컴퓨터로 LocalLLM을 구동하고 있는 제가 Hugging Face 의 mlx-community에도 꽤 빠릿하게 mlx 모델들이 제공되고 있음에도 Unsloth의 모델들을 주로 사용중인 이유는</description></item><item><title>NVIDIA Nemotron-3-Super</title><link>https://modu-print.com/posts/16296/</link><pubDate>Fri, 13 Mar 2026 23:04:42 +0900</pubDate><guid>https://modu-print.com/posts/16296/</guid><description>DGX-Spark 를 클러스터로 사용중인 지인이 한분 계신데요 몇일 전에 Nemotron 새 모델이 나왔다고 꽤 쓸만 하다는 말씀을 해주셔서.. 간단히 테스트를 하는 중입니다.&#10;사실 llama-nemotron 계열 모델은 잠시 사용을 해봤었는데 일단 llama 자체가 저와는 좀 안맞는 모델이어서 아무리 nvidia 가 파인튜닝을 했다 한들 근본이 어디 가진 않을거라 생각 해서 nemotron 은 그리 관심을 두지 않았습니다.&#10;그래도 llama가 아닌 nvidia 가 처음부터 학습 시켰다는 글들을 보고 몇 달 전에 나온 Nemotron-3-nano 의 경우에는 사용을 잠시 해봤습니다만. 아무래도 제가 사용하는 장치가 NVIDIA 가 아닌 애플 Metal 기반 장치다보니 자잘한 문제가 있었습니다.</description></item><item><title>minimax-m2.5 / mlx vs unsloth</title><link>https://modu-print.com/posts/16236/</link><pubDate>Fri, 06 Mar 2026 10:51:59 +0900</pubDate><guid>https://modu-print.com/posts/16236/</guid><description>최근 주로 사용하는 minimax m2.5 모델의 gguf/mlx 모델과 unsloth 모델의 단순 프롬프트 tps 차이에 대해서 기록을 남깁니다.&#10;Bash minimax-m2.5:Q4_K_S - unsloth Prediction Stats: Stop Reason: eosFound Tokens/Second: 45.72 Time to First Token: 13.356s Prompt Tokens: 6057 Predicted Tokens: 166 Total Tokens: 6223&#10;minimax-m2.5:4Bit - lmstudio-community&#10;Prediction Stats: Stop Reason: eosFound Tokens/Second: 38.61 Time to First Token: 9.598s Prompt Tokens: 6153 Predicted Tokens: 1217 Total Tokens: 7370 minimax-m2.5:Q4_K_S - unsloth Prediction Stats: Stop Reason: eosFound Tokens/Second: 45.72 Time to First Token: 13.356s Prompt Tokens: 6057 Predicted Tokens: 166 Total Tokens: 6223 minimax-m2.5:4Bit - lmstudio-community Prediction Stats: Stop Reason: eosFound Tokens/Second: 38.61 Time to First Token: 9.598s Prompt Tokens: 6153 Predicted Tokens: 1217 Total Tokens: 7370</description></item><item><title>Qwen3-coder-next / mlx vs unsloth</title><link>https://modu-print.com/posts/16223/</link><pubDate>Fri, 06 Mar 2026 10:42:29 +0900</pubDate><guid>https://modu-print.com/posts/16223/</guid><description>앞서 qwen3 계열 모델들이 Tool calling 에 문제가 있다는 글을 여러번 작성 했는데요 .. 현재까지 제가 찾아보고 해본 정보로는 qwen3 모델의 경우 qwen 전용 툴로 학습되었다는 것이고 .. chat template 를 수정해서 극복 가능하지 않을까 라는 생각으로 여러 짓을 해봤으나 .. 그리 결과가 좋지는 못했습니다.&#10;현재까지는 tps의 이점 때문에 gguf/mlx 모델을 선호해 왔습니다만 .. 아무래도 mlx 진영이 Ai 모델 시장에서는 사용자가 소수인 상황이라 상대적으로 발전이 느린 느낌이네요 ..</description></item><item><title>Mac Studio M3 Ultra 512g + LocalLLM + Agents</title><link>https://modu-print.com/posts/16187/</link><pubDate>Tue, 03 Mar 2026 19:21:19 +0900</pubDate><guid>https://modu-print.com/posts/16187/</guid><description>여전히 클로드코드니 코덱스니 이런저런 다양한 놈들을 사용하는 와중에 틈틈히 LocalLLM 만으로 어느정도 수준까지 사용이 가능하지에 대한 많은 연구와 테스트를 해보고 있습니다.&#10;새로운 모델이 등장하는 텀이 좀 길어지는 느낌이긴 합니다만 .. 현재까지 정말 다양한 모델을 LM Studio, Ollama, mlx-ml, llama.cpp, exo 등에서 사용을 해봤습니다만 ..&#10;Openai API 를 통한 채팅 기반의 사용에서는 어떤 모델이든 대체로 큰 문제 없이 사용이 가능합니다만 ..</description></item><item><title>LM Studio + Opencode + OMO + 이런저런 모델들</title><link>https://modu-print.com/posts/16150/</link><pubDate>Sat, 28 Feb 2026 01:58:26 +0900</pubDate><guid>https://modu-print.com/posts/16150/</guid><description>맥 스튜디오 M3 Ultra 512g 모델로 이런짓 저런짓을 좀 해보고 있는 와중에 중간 중간 관련 글을 정리해 올려보고 있습니다. Bash pirogom@pirogom-Mac-Studio ~ % lms ls You have 12 models, taking up 599.66 GB of disk space.&#10;LLM PARAMS ARCH SIZE DEVICE google/gemma-3-27b (1 variant) 27B gemma3 16.87 GB Local llama-3.3-70b-instruct@4bit 70B Llama 39.71 GB Local llama-3.3-70b-instruct@8bit 70B Llama 74.98 GB Local llama-4-scout-17b-16e@4bit 17B llama4 61.14 GB Local llama-4-scout-17b-16e@8bit 17B llama4 115.46 GB Local minimax/minimax-m2.5 (1 variant) 230B minimax_m2 128.68 GB Local qwen2.5-coder-3b-instruct-mlx 3B Qwen2 1.75 GB Local qwen3-coder-next@4bit qwen3_next 44.86 GB Local qwen3-coder-next@8bit qwen3_next 84.67 GB Local zai-org/glm-4.6v-flash (1 variant) 9B glm4v 7.09 GB Local zai-org/glm-4.7-flash (1 variant) 30B glm4_moe_lite 24.36 GB Local&#10;EMBEDDING PARAMS ARCH SIZE DEVICE text-embedding-nomic-embed-text-v1.5 Nomic BERT 84.11 MB Local pirogom@pirogom-Mac-Studio ~ % lms ls You have 12 models, taking up 599.66 GB of disk space. LLM PARAMS ARCH SIZE DEVICE google/gemma-3-27b (1 variant) 27B gemma3 16.87 GB Local llama-3.3-70b-instruct@4bit 70B Llama 39.71 GB Local llama-3.3-70b-instruct@8bit 70B Llama 74.98 GB Local llama-4-scout-17b-16e@4bit 17B llama4 61.14 GB Local llama-4-scout-17b-16e@8bit 17B llama4 115.46 GB Local minimax/minimax-m2.5 (1 variant) 230B minimax_m2 128.68 GB Local qwen2.5-coder-3b-instruct-mlx 3B Qwen2 1.75 GB Local qwen3-coder-next@4bit qwen3_next 44.86 GB Local qwen3-coder-next@8bit qwen3_next 84.67 GB Local zai-org/glm-4.6v-flash (1 variant) 9B glm4v 7.09 GB Local zai-org/glm-4.7-flash (1 variant) 30B glm4_moe_lite 24.36 GB Local EMBEDDING PARAMS ARCH SIZE DEVICE text-embedding-nomic-embed-text-v1.5 Nomic BERT 84.11 MB Local</description></item><item><title>Qwen 계열 모델 + Opencode tool calling 문제</title><link>https://modu-print.com/posts/16110/</link><pubDate>Sat, 21 Feb 2026 22:16:02 +0900</pubDate><guid>https://modu-print.com/posts/16110/</guid><description>이런 저런 ai 서비스 업체들의 모델들도 사용하면서 LocalLLM 을 병행하거나 휴일에는 100% LocalLLM 만 가지고 에이전트를 물리거나 하는 등의 실험? 프로젝트를 돌려보고 있습니다.&#10;클로드 코드가 익숙해서 가능하면 클로드 코드를 사용하고 싶지만 .. 클로드 코드의 경우 LocalLLM 을 사용하기 위한 환경변수 설정을 하더라도 Opus, Sonnet, Haiku 같은 모델 명칭으로 픽스된 내부 기능들의 경우 LocalLLM 커넥션인 상태에선 문제가 발생하기도 해서 Opencode 를 좀 활용해 볼까 하고 .. 이짓 저짓을 해보고 있습니다.</description></item><item><title>LM Studio/Qwen3-Coder-Next/80b/mlx</title><link>https://modu-print.com/posts/16094/</link><pubDate>Sat, 21 Feb 2026 11:38:33 +0900</pubDate><guid>https://modu-print.com/posts/16094/</guid><description>이것저것 해보는김에 .. LM Studio 를 다시 업데이트하고 앞서 Ollama 와 mlx-ml 로 테스트 해본 Qwen3-Coder-Next의 MLX 버전 모델을 LM Studio에 올려 봤습니다.&#10;기왕 하는김에 4Bit, 8Bit 차이도 궁금해서 둘다 받아 봤습니다. 기존에 ollama 의 mlx 가 아닌 gguf 모델의 간단한 숫자야구 게임 코드 작성의 결과는 ..</description></item><item><title>mlx-ml/Qwen3-Coder-Next-4Bit</title><link>https://modu-print.com/posts/16072/</link><pubDate>Sat, 21 Feb 2026 09:53:26 +0900</pubDate><guid>https://modu-print.com/posts/16072/</guid><description>앞서 작성한 글들에서 mlx-ml 은 불안정 해서 사용하지 못하고 있다는 내용을 작성한적 있습니다. 그래도 일단 애플 하드웨어에서 mlx의 성능차이가 궁금하신 분들이 계실겁니다. 몇몇 분은 데이터좀 알려달라고 하시기도 했구요 ..&#10;일단 허깅페이스의 mlx커뮤니티에서 Qwen3-Coder-Next-4bit 라는 모델을 hf download 명령으로 다운로드 받았습니다.&#10;https://huggingface.co/mlx-community/Qwen3-Coder-Next-4bit&#10;Bash hf download mlx-community/Qwen3-Coder-Next-4bit hf download mlx-community/Qwen3-Coder-Next-4bit Qwen/Qwen3-Coder-Next 모델을 mlx 로 변환한 모델입니다. 파일크기는 44.8기가 정도이구요.</description></item><item><title>Ollama/qwen3-coder:480b/GGUF</title><link>https://modu-print.com/posts/16045/</link><pubDate>Fri, 20 Feb 2026 09:45:15 +0900</pubDate><guid>https://modu-print.com/posts/16045/</guid><description>이번에는 많은 곳에서 언급하곤 하는 좀 큰 모델에 대한 기록을 남겨봅니다. qwen3-coder의 480b 모델이구요.. 여러 블로그나 유튭 영상등에서 제 맥스튜디오와 동일사양에서 이 모델을 올려 쓴다느니 하는 글을 봐서 받아본 모델입니다.&#10;일단 모델 파일 용량만 290GB 정도라 다운로드받는데 2시간 가까이 걸리는 관계로 .. ollama pull 걸어두고 자고 일어났네요.&#10;우선 제가 뭘 잘못 한건지 ollama 문제인지 mlx 모델이 아닌 gguf 모델을 써서 그런지는 모르겠습니다만.. 좀 뭔가 이상해요..</description></item><item><title>Goland/Jetbrains IDE에서 클로드 코드(Claude Code) 연동문제</title><link>https://modu-print.com/posts/15925/</link><pubDate>Mon, 09 Feb 2026 08:50:14 +0900</pubDate><guid>https://modu-print.com/posts/15925/</guid><description>워낙 많은 언어와 윈도,맥,리눅스등 여러 플랫폼에 대한 개발을 하다보니.. Ai 관련은 플러그인 연동이나 기타 여러 상황상 Vs code에서 진행을 한 경우가 많았습니다...만;;&#10;아무래도 Jetbrains의 IDE가 Vscode 대비 불필요한 설정에 에너지를 덜 쓰기 때문에 최근에는 Jetbrains 의 Goland를 주력으로 사용하고 있습니다. Jetbrains에선 Java, js, c, c#등 정말 다양한 언어를 위한 ide를 판매중이지만 개인적인 경험으론 뭐라도 하나 유료구독을 하면 나머지 기타 언어들은 플러그인 설치만 하더라도 필요한 대부분의 기능은 사용할 수 있습니다.</description></item><item><title>AWS 강의 추천 - AWS 강의실</title><link>https://modu-print.com/posts/15350/</link><pubDate>Sat, 22 Nov 2025 14:21:17 +0900</pubDate><guid>https://modu-print.com/posts/15350/</guid><description>최근 개발 환경은 클라우드 환경을 피하려야 피할 수 없는…. 그런 세상인데요….&#10;그 가장 큰 축 중 하나인 AWS(Amazon Web Services)에 관심을 가지는 개발자 or 개발자 지망생분들이 많을 거로 생각합니다. 이미 시중에도 많은 책들이 나와 있고 많은 학원이 있으며 AWS 자격증을 취득하기 위해 준비 중인 분들도 워낙 많다 보니….인프런이니 유데미니.. 유튜브 에서만 찾아보더라도 정말 다양한 강의를 찾아볼 수 있습니다…. 만!</description></item><item><title>pdf.js Opacity를 포함한 Stamp Annotation 패치</title><link>https://modu-print.com/posts/12390/</link><pubDate>Fri, 21 Jun 2024 16:59:45 +0900</pubDate><guid>https://modu-print.com/posts/12390/</guid><description>모두의 PDF 에서도 일부 기능을 사용중이긴 합니다만.. 최근에 pdf.js 를 가지고 이런저런 일들을 하는 경우가 많습니다. 모질라의 오픈소스이고 Firefox 에서 기본 PDF Viewer를 담당하는 놈이다보니 이래저래 사용하시는 분들이 꽤 되는 걸로 알고 있습니다.&#10;코드를 수정(이라 쓰고 마개조라 읽는다)해서 쓰고 있는 와중에.. 제가 쓰는 목적에선 문제가 있어서 수정한 부분을 공유합니다.&#10;사실;; pdf.js 사용하는 다른 사용자들에게도 해당하지 않을까 싶어서.. pdf.js 쪽에다가 Full Request를 신나게 때리고보니;; 잠시 잊고 있었어요 ㅎㅎ 공동개발하는 대부분의 프로젝트들은 이런저런 컨벤션이니 Lint 오류가 안나게 잘 맞춰서 ;; 때려야 한다는걸.. ;;; 다 맞춰서 다시 풀리퀘를 때릴까 싶다가도.. 그냥 귀찮아서.. 혹시나 같은 문제를 고민하시는 분들을 위해 블로그에 간단히 글로써 올려봅니다.</description></item><item><title>Windows Shell Extention 개발관련 레지스트리</title><link>https://modu-print.com/posts/11694/</link><pubDate>Fri, 16 Feb 2024 17:46:49 +0900</pubDate><guid>https://modu-print.com/posts/11694/</guid><description>오랜만에 C/C++와 Visual Studio로 탐색기의 우클릭 메뉴에 원하는 기능을 추가할 수 있는 Shell Extention을 ATL/COM으로 만들고 있는 와중에 .. regsvr32 /u 로 DLL의 등록을 해제를 한 뒤에도 탐색기 프로세스가 개발중인 DLL을 물고 있어서 파일을 재빌드 하거나 삭제하거나 하는등의 짓을 못하는 ;; 경우가 생겨서 .. 예전기억을 더듬어 찾아둔 자료를 기록삼아 남겨 둡니다.&#10;BAT (Batchfile) HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AlwaysUnloadDLL 이 레지스트리는 원래 윈도 NT이전의 윈도 95, 98, ME에서 탐색기로 하여금 사용하지 않는 DLL들을 좀 빨리 놔주도록 해주는 역할을 했던 것 같은데 .. 혹시 몰라 남겨둡니다. ( 2024년에 윈도 9x 관련 개발을 할일이야 있겠냐만은.. )</description></item><item><title>Vscode에서 Goland로 전환 후기</title><link>https://modu-print.com/posts/10237/</link><pubDate>Mon, 21 Aug 2023 10:15:54 +0900</pubDate><guid>https://modu-print.com/posts/10237/</guid><description>매우 오랜 시간 MS의 Visual Studio Code를 이용해서 Go언어 개발을 해 왔습니다만.. Vscode 에서 go언어를 지원하기 이전에는 서브라임텍스트 라던가 gVim등 정말 많은 편집기들을 전전 긍긍 했고 한때는 Notepad++ 로 Go언어 개발을 하던 시절도 있었습니다.&#10;Vscode 에서 go언어를 지원하기 시작하고 디버깅도 가능해지고 각종 go 언어 관련 부가적인 기능들을 지원하기 시작하면서 부터는 주로 Vscode 로 개발을 해 왔습니다.</description></item><item><title>[Go언어 윈도 GUI] walkmgr에 WebView2(크로미움) 추가</title><link>https://modu-print.com/posts/9589/</link><pubDate>Mon, 31 Jul 2023 16:25:30 +0900</pubDate><guid>https://modu-print.com/posts/9589/</guid><description>오랜만에 walkmgr 에 새로운 기능을 추가하였습니다. 기존에 WebView 가 walkmgr 에 존재하였습니다. 이건 walk 에서 구성되어 있는 것이고 윈도의 OCX기반 WebView를 사용해 보신 분들은 잘 아시겠지만 .. 레거시 중에 레거시죠 .. 마지막 IE에 비해서도 기능이 허접하며 표준따윈 개나 줘버린 과거의 유산입니다. 최신 HTML, CSS, JS등을 이용 못하는건 둘째 치더라도 오만가지 JS관련 오류들을 비롯해서 많은 불편함을 감수해야지만 사용 가능한 놈이긴 한데요 ..</description></item><item><title>유튜브/인프런 추천 - 토비의 스프링</title><link>https://modu-print.com/posts/4206/</link><pubDate>Tue, 18 Jul 2023 22:50:02 +0900</pubDate><guid>https://modu-print.com/posts/4206/</guid><description>자바 백엔드 개발자들의 경우 스프링 프레임워크를 피해 갈 수 없을 정도로 스프링은 자바 백엔드 시장에서 확고한 자리를 차지하고 있는 프레임 워크입니다.&#10;관련한 책들도 시중에 엄청나게 많이 존재하지만, 개인적인 생각이지만, 가장 오랜 시간 수많은 개발자들에게 읽혀오고 있고 출간한 지 꽤 시간이 지났음에도 여전히 많은 분들이 추천하는 서적이 토비의 스프링이라 생각합니다.&#10;저는 책도 책이지만 토비님의 유튜브 채널과 인프런 강의를 추천드리려 합니다.</description></item><item><title>[Go언어 윈도 GUI] walkmgr에 모달 다이얼로그(Modal Dialog) 추가</title><link>https://modu-print.com/posts/1794/</link><pubDate>Thu, 29 Jun 2023 15:32:00 +0900</pubDate><guid>https://modu-print.com/posts/1794/</guid><description>지금까지 walkmgr 에 추가된 기능들로도 어지간한 윈도 네이티브 GUI 프로그래밍은 가능 했습니다만. 보편적인 GUI 프로그래밍에서 가장 크게 부족한 기능중 하나가 모달 다이얼로그(Modal Dialog) 기능이었습니다.&#10;흔히 다이얼로그(Dialog)라고 하자면 대화창 또는 대화상자라고 칭하곤 하지요..&#10;일반적으로는 사용자의 의사를 묻거나 사용자의 어떤 선택이 필요한 경우 사용자 선택에 따른 로직의 분기가 필요하다던가 하는 경우에 사용됩니다.&#10;가장 쉽게 접하는것은 MessageBox 같은 함수겠지요. 자바스크립트를 기준하자면 alert 이나 confirm 같은 함수로 생성되는 대화창을 들 수 있겠습니다.</description></item><item><title>HTTP GET 헤더추가 + gzip 처리</title><link>https://modu-print.com/posts/3386/</link><pubDate>Wed, 17 May 2023 09:36:00 +0900</pubDate><guid>https://modu-print.com/posts/3386/</guid><description>웹 관련 개발을 하게되면 HTTP GET 방식으로 단순 데이터를 수신해야 하는 경우가 있습니다. 이런 경우 Response 데이터의 크기가 큰 경우에 서버측에서 데이터를 gzip 으로 압축해서 전송하는 경우도 종종 있습니다. 트래픽 비용을 cpu 연산으로 커버 치는 샘이겠지요..&#10;이런식의 처리가 가능하려면 Reqeust Header 상에도 accept-encoding 같은 정보에 gzip 을 지원 한다는 명시를 해주지 않을 경우 서버측에선 에러를 리턴하게 됩니다.&#10;상대가 gzip 압축을 처리하지 못한다는데 굳이 gzip 으로 압축된 응답을 할 이유 자체가 없기 때문이겠지요 ..</description></item><item><title>[Go언어 윈도 GUI] walkmgr에 트리뷰(TreeView) 추가 2편</title><link>https://modu-print.com/posts/2148/</link><pubDate>Fri, 10 Feb 2023 09:20:00 +0900</pubDate><guid>https://modu-print.com/posts/2148/</guid><description>앞서 기본적인 트리뷰 생성법에 대해서는 아래 링크를 참고하시구요.&#10;[Go언어 윈도 GUI] walkmgr에 트리뷰(TreeView) 추가 1편 몇가지 예제를 가지고 추가 사용법을 알려드리도록 하겠습니다.&#10;트리뷰에서 선택된 아이템의 이름을 변경하는 예제입니다. 현재 선택된 아이템의 객체를 얻는 방법과 명칭을 변경하는 방법입니다.</description></item><item><title>[Go언어 윈도 GUI] walkmgr에 트리뷰(TreeView) 추가 1편</title><link>https://modu-print.com/posts/2145/</link><pubDate>Thu, 09 Feb 2023 12:50:00 +0900</pubDate><guid>https://modu-print.com/posts/2145/</guid><description>이번에 모두의 PDF에 책갈피 기능을 추가하면서 PDF의 책갈피 기능이 Parent, Children 을 이용한 무한 계층구조 인지라 이런 형태를 다루는데 가장 적합한 UI요소는 아무래도 트리뷰(TreeView)라서 관련 기능을 walkmgr 에 추가해 봅니다.&#10;MFC나 윈도 API를 다루던 시절에도 사실 트리뷰는 진짜 쓰기 싫어라 하던 놈중 하나인데요 가능하면 리스트컨트롤로 대충 땜빵해서 쓰곤 했는데 .. 계층구조를 리스트 컨트롤로 다루는건 매우 비효율적인지라 미루고 미루다 추가해 봅니다.&#10;이런놈을 보통 트리뷰라고 하지요.. 우리가 가장 흔히 접하는 경우를 보자면</description></item><item><title>[Go언어 윈도 GUI] walkmgr 메뉴(Menu) 예제</title><link>https://modu-print.com/posts/2139/</link><pubDate>Sat, 24 Dec 2022 14:39:00 +0900</pubDate><guid>https://modu-print.com/posts/2139/</guid><description>GitHub - pirogom/walkmgr_example: walkmgr example project walkmgr example project . Contribute to pirogom/walkmgr_example development by creating an account on GitHub. walkmgr 에 메뉴관련 기능과 예제는 한참 전에 추가를 해두긴 했습니다만.. 메뉴와 관련된 글은 작성을 제대로 안한것 같아서 예제도 조금더 보강을 하고 관련 글을 작성해봅니다. 관련 예제는 위의 링크 참고 하시면 됩니다.&#10;윈도 프로그래밍을 하다보면 진짜 유용하고 친숙하게 사용하는게 메뉴입니다. UI나 그런거 귀찮으면 ㅎㅎ 그냥 메뉴에 다 때려넣어도 ;;;</description></item><item><title>[Go언어 윈도 GUI] walkmgr에 툴바(ToolBar) 추가</title><link>https://modu-print.com/posts/2142/</link><pubDate>Mon, 19 Dec 2022 13:08:00 +0900</pubDate><guid>https://modu-print.com/posts/2142/</guid><description>윈도 GUI 프로그래밍시 메뉴와 함께 있으면 유용한 기능중 하나가 툴바(ToolBar)입니다.&#10;흔히 이런 것들로 보통 타이틀바나 메뉴 바로 아래즈음에 아이콘들로 주르륵~ 하니 놓여지는 .. 열기, 자르기, 저장 같은 기능들을 모아두는 것들을 툴바라고들 하지요..&#10;제가 클론해서 수정중인 lxn/walk 에도 기본적으로 제공을 하고 있는 기능입니다만.. walkmgr 구조에 포함시켜 보았습니다. 원래 윈도의 툴바는 수직 방향으로도 구성이 가능하고 lxn/walk 에서도 파라메터 상으로는 수직을 지정가능하게 되어 있긴 한데 제대로 동작하진 못하는것 같아서 우선 전통적인 툴바에 대해서만 다뤄 보도록 하겠습니다.</description></item><item><title>[Go언어 윈도 GUI] walkmgr에 링크 라벨(Link Label) 추가</title><link>https://modu-print.com/posts/2136/</link><pubDate>Sat, 10 Dec 2022 00:08:00 +0900</pubDate><guid>https://modu-print.com/posts/2136/</guid><description>walkmgr 에 Link Label 을 추가 하였습니다. 쉽게 말해서 URL 링크를 포함하는 텍스트 라벨을 사용할 수 있도록 추가 하였습니다.&#10;walkmgr 에 link_label.go 파일이 추가 되었구요.&#10;Go / *&#9;LinkLabel / func (wm WalkUI) LinkLabel(text string, at …AlignType) walk.LinkLabel { ne, _ := walk.NewLinkLabel(wm.Parent()) ne.SetText(text) if len(at) == 0 { ne.SetAlignment(walk.AlignHVDefault) } else { switch at[0] { case ALIGN_LEFT: ne.SetAlignment(walk.AlignHNearVCenter) case ALIGN_CENTER: ne.SetAlignment(walk.AlignHCenterVCenter) case ALIGN_RIGHT: ne.SetAlignment(walk.AlignHFarVCenter) default: ne.SetAlignment(walk.AlignHVDefault) } } wm.Append(ne) ne.LinkActivated().Attach(func(link *walk.LinkLabelLink) { exec.Command("rundll32.exe", "url.dll,FileProtocolHandler", link.URL()).Start() }) return ne }</description></item><item><title>[Go언어 윈도 GUI] walkmgr에 스크롤뷰(ScrollView) 추가</title><link>https://modu-print.com/posts/2133/</link><pubDate>Tue, 06 Dec 2022 09:40:00 +0900</pubDate><guid>https://modu-print.com/posts/2133/</guid><description>업데이트된 패키지는 walkmgr, walkmgr_example 2개 입니다.&#10;GitHub - pirogom/walkmgr: for easy window native gui programming on go. enhanced pirogom/walk. for easy window native gui programming on go. enhanced pirogom/walk. - GitHub - pirogom/walkmgr: for easy window native gui programming on go. enhanced pirogom/walk. GitHub - pirogom/walkmgr_example: walkmgr example project walkmgr example project . Contribute to pirogom/walkmgr_example development by creating an account on GitHub. 네이티브 GUI 프로그래밍을 하다 보면 .. 한 화면에 매우 많은 UI요소를 배치해야 하는 경우가 있습니다. 보통 일반 사용자용 프로그램을 만들때 보다는 내부에서 사용할 각종 툴(Tool)같은 것들을 만들때에는 사용성 보다는 기능에 집중하는 경우 같은..</description></item><item><title>[Go언어 윈도 GUI] walkmgr에 상태바(StatusBar) 추가</title><link>https://modu-print.com/posts/2130/</link><pubDate>Fri, 02 Dec 2022 12:34:00 +0900</pubDate><guid>https://modu-print.com/posts/2130/</guid><description>오랜만에 Go언어 관련된 글을 작성합니다.&#10;모두의 프린터, 모두의 PDF등을 비롯한 대부분의 프로그램을 lxn/win, lxn/walk 를 클론해서 조금씩 손보고 해가면서 쓰고 있는데요, 관련 코드는 제 깃헙에 공개를 하고 있습니다. 1일1고 카테고리의 글들을 참고하시면 Go언어로 윈도 GUI 프로그래밍을 하는 것과 관련된 여러 글들을 보실 수 있을겁니다.&#10;이번에 추가한 기능은 .. 자주 쓰이진 않지만 특정 목적의 툴을 만들거나 할때에는 은근 유용한 상태바(StatusBar)를 만들어 넣는방법입니다.</description></item><item><title>[Go언어 윈도 GUI] walkmgr 에 ListControl 추가</title><link>https://modu-print.com/posts/2127/</link><pubDate>Thu, 11 Aug 2022 10:37:00 +0900</pubDate><guid>https://modu-print.com/posts/2127/</guid><description>GitHub - pirogom/walk: Walk is a “Windows Application Library Kit” for the Go Programming Language. Clone from lxn/walk. Walk is a "Windows Application Library Kit" for the Go Programming Language. Clone from lxn/walk. - GitHub - pirogom/walk: Walk is a "Windows Application Library Kit" for the Go… GitHub - pirogom/walkmgr: for easy window native gui programming on go. enhanced pirogom/walk. for easy window native gui programming on go. enhanced pirogom/walk. - GitHub - pirogom/walkmgr: for easy window native gui programming on go. enhanced pirogom/walk. GitHub - pirogom/walkmgr_example: walkmgr example project walkmgr example project . Contribute to pirogom/walkmgr_example development by creating an account on GitHub. Go언어로 윈도API를 이용한 GUI 프로그래밍과 관련된 글을 최근에 계속 작성하고 있는데요..</description></item><item><title>[Go언어 윈도 GUI] walkmgr 에 Progress Bar 추가</title><link>https://modu-print.com/posts/2124/</link><pubDate>Wed, 10 Aug 2022 10:38:00 +0900</pubDate><guid>https://modu-print.com/posts/2124/</guid><description>walkmgr 에 progress bar 기능 추가했습니다. walkmgr_example 저장소에도 예제 적용 되었습니다.&#10;설치나 다운로드시에 진행률을 표시할때 사용하기 좋은 기능입니다. walk 에 기본 내장되어 있었으나 제가 사용빈도가 거의 없어서 추가하지 않았던 기능인데.. 필요하시다는 분들이 계셔서 추가 했습니다.&#10;Go package main import ( "testing" "time" "github.com/pirogom/walkmgr" ) // 프로그래스바 테스트 func TestProgressBar(t testing.T) { wm := walkmgr.NewWin("Progressbar 테스트", 640, 480) pb := wm.ProgressBar(0, 100, 0) wm.Starting(func() { go func() { for { currVal := pb.Value() wm.Sync(func() { pb.SetValue(currVal + 1) }) time.Sleep(250 time.Millisecond) if currVal == pb.MaxValue() { return } } }() }) wm.Start() }</description></item><item><title>[Go언어 윈도 GUI] walkmgr 에 라디오 버튼 추가</title><link>https://modu-print.com/posts/2121/</link><pubDate>Fri, 05 Aug 2022 08:44:00 +0900</pubDate><guid>https://modu-print.com/posts/2121/</guid><description>최근에는 lxn/walk, lxn/win 등을 클론해서 따로 필요한 부분을 수정해서 깃헙에 올려두고 있습니다. walk 를 통한 윈도 GUI 프로그래밍을 조금 수월하게 하고자 walkmgr 이라는 패키지를 만들어 쓰고 있구요.. 이와 관련된건 이 1일1고 카테고리의 이전 글들에 간단히 강좌 비슷한 글을 작성해 두었으니 참고 하시구요 ..&#10;이 walkmgr 은 제가 만드는 모두의 프린터, 모두의 PDF등을 비롯한 윈도 GUI 프로그래밍에 모두 사용되고 있는 패키지들 입니다.</description></item><item><title>컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커</title><link>https://modu-print.com/posts/1690/</link><pubDate>Tue, 12 Jul 2022 12:40:00 +0900</pubDate><guid>https://modu-print.com/posts/1690/</guid><description>컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커 - 조훈, 심근우, 문성주 저 | 길벗  우연찮게 최근 이런저런 개발 관련 대화를 나누곤 하는 오픈 채팅방에 저자분이 계셔서 구입하고 주변에 쿠버네티스 관련 볼만한 책 없냐는 질문을 받으면 적극 추천 중인 책입니다.&#10;최근 개발 인프라 시장은 컨테이너 천국 입지요.. 한때 가상 서버가 한참 창궐(?) 해오다 MSA세상이 도래하고 데브옵스니 빌드/배포의 자동화라느니 여러 가지 이슈들이 복합적으로 등장하면서 급속도로 시장을 지배하기 시작한 놈이 쿠버네티스라고 할 수 있겠습니다.</description></item><item><title>참고하기 좋은 Go언어 패키지 추천 - Owncast</title><link>https://modu-print.com/posts/2119/</link><pubDate>Wed, 06 Jul 2022 12:15:00 +0900</pubDate><guid>https://modu-print.com/posts/2119/</guid><description>Go언어를 사용하거나 공부하면서 참고하기 좋을 .. 교제(?) 삼기 좋은 패키지 하나 소개해봅니다.&#10;Owncast Owncast is your self-hosted live streaming solution. GitHub - owncast/owncast: Take control over your live stream video by running it yourself. Streaming + chat out of the box. Take control over your live stream video by running it yourself. Streaming + chat out of the box. - GitHub - owncast/owncast: Take control over your live stream video by running it yourself. Stre… 1인용 미디어 스트리밍 서버입니다.. 만.. </description></item><item><title>GO언어 ORM 무엇을 써야하나?</title><link>https://modu-print.com/posts/2117/</link><pubDate>Wed, 06 Jul 2022 09:24:00 +0900</pubDate><guid>https://modu-print.com/posts/2117/</guid><description/></item><item><title>MS윈도 - 알려진 폴더 경로 얻기</title><link>https://modu-print.com/posts/3379/</link><pubDate>Tue, 28 Jun 2022 09:30:00 +0900</pubDate><guid>https://modu-print.com/posts/3379/</guid><description>시스템 프로그래밍을 하다보면 .. 윈도에서 흔히 쓰는 경로들 ..&#10;바탕화면, 다운로드, 폰트 같은 경로들을 얻어 써야 하는 경우가 있습니다.&#10;이중 바탕화면이나 다운로드 같은 경로는.. 보통은 특정 룰을 가지고 생성되지만 &#10;사용자가 경로를 변경해서 쓸수도 있지요 ..&#10;레지스트리를 직접 읽어서 처리하는 방법도 있지만 32비트 64비트 분리해서 처리하고 이래저래 복잡할 수 있습니다.</description></item><item><title>Go 백엔드 프레임워크 - Echo,Gin vs Fiber</title><link>https://modu-print.com/posts/2115/</link><pubDate>Wed, 22 Jun 2022 13:12:00 +0900</pubDate><guid>https://modu-print.com/posts/2115/</guid><description/></item><item><title>[Go언어/윈도GUI] 파일 드래그앤드랍(Drag&amp;amp;Drop) 처리</title><link>https://modu-print.com/posts/2112/</link><pubDate>Wed, 23 Mar 2022 10:39:00 +0900</pubDate><guid>https://modu-print.com/posts/2112/</guid><description>우선 앞서 lxn/walk 와 win 을 제 깃헙으로 클론해서 따로 관리한다고 글 올렸으니 참고하시구요.&#10;Go언어 윈도 GUI 개발관련 win/walk 패키지 분리 창이나 특정 UI 객체에 드래그앤드랍을 통한 파일처리가 필요한 경우가 있습니다. &#10;예를들어 파일리스트에 파일을 드래그앤 드랍으로 던지면 던진 파일들이 추가가 된다던지.. &#10;LineEdit 에 파일을 드래그앤드랍하면 해당 파일의 경로가 채워 진다던지 .. </description></item><item><title>Go언어 윈도 GUI 개발관련 win/walk 패키지 분리</title><link>https://modu-print.com/posts/2109/</link><pubDate>Wed, 23 Mar 2022 09:39:00 +0900</pubDate><guid>https://modu-print.com/posts/2109/</guid><description>기존에 Go언어로 윈도 GUI 개발과 관련하여 lxn/win, lxn/walk 패키지를 이용한 개발 방법을 글로 작성 했었는데요.. 작성한 글중중에도 .. WebView 의 자바스크립트 오류와 관련해서 이 패키지들을 수정해서 쓰는 법등도 다루긴 했습니다. 이래저래 계속 써 가다보니 .. 저 패키지들을 직접 수정을 해야 하거나 윈도 API중 lxn/win 에 포함안된 함수들이 있거나 해서 추가를 해야하는 등의 일이 계속 일어날 것 같아서 ..&#10;귀찮아서 ;; 안만들고 버티던 .. 깃헙계정을 ;; 결국 만들고 쓰게 되네요 ..</description></item><item><title>[GO언어/GOLANG] ed25519 암호화/복호화/서명/검증 알고리즘</title><link>https://modu-print.com/posts/2107/</link><pubDate>Fri, 11 Mar 2022 09:03:00 +0900</pubDate><guid>https://modu-print.com/posts/2107/</guid><description>특정 데이터의 유효성 검증을 위해서 만든 메소드들입니다. 원래 ECDSA 를 사용하는 놈으로 만들었다가 키를 만드는데 사용되는 P256.. 등의 P시리즈 커브들이 이래저래 말들이 많아서 ED25519를 사용하는 방식으로 변경하였습니다.&#10;ED25519 나 ECDSA는 데이터를 암호화하고 복호화하는데 사용되는게 아니라 특정 데이터에 개인키로 서명(Sign)을 하고 공개키로 서명이 유효한지를 검증해주는 방식으로 사용합니다.&#10;예를들어 데이터가 "피로곰"인 경우에 서버에서 "피로곰"에 개인키로 서명을하고 서명되고 암호화된 데이터를 클라이언트에 전송하면 클라이언트에서는 "피로곰"과 서버에서 보내준 서명된 데이터를 가지고 공개키로 검증을 합니다. </description></item><item><title>TightVNC 2.8.59-gpl 한영키 패치된 버전</title><link>https://modu-print.com/posts/1694/</link><pubDate>Tue, 08 Mar 2022 14:28:00 +0900</pubDate><guid>https://modu-print.com/posts/1694/</guid><description>모두의 리모트를 완전히 Go언어로 다시 만들고 기존 구조랑 전혀 다르게 수정을 하면서 기존 모두의 리모트를 1년 넘게 사용해오면서 가장 불편하게 느낀 점이 한영키가 먹지 않는다는 점입니다. 모두의 리모트에서 사용중인 TightVNC뿐 아니라 대부분의 VNC계열의 RDP 프로그램들에서 발생하는 문제이긴 한데요..&#10;TightVNC 2.8.59-gpl 버전 소스코드를 받아서 한영키 관련된 부분을 수정하고 아무래도 멀티플랫폼에 맞춰 개발된 프로그램이라 소스코드들이 UTF-8인코딩으로 되어 있어서 Visual Studio 에서 윈도용으로 컴파일시에 뜨는 이런저런 Warning 과 몇가지 define 관련 충돌나는 부분들과 함께 한영키 처리에 대한 부분을 수정하였습니다.</description></item><item><title>[Go언어/GOLANG] RSA 암호화/복호화</title><link>https://modu-print.com/posts/2104/</link><pubDate>Fri, 04 Mar 2022 14:09:00 +0900</pubDate><guid>https://modu-print.com/posts/2104/</guid><description>암호화 관련된 자료들은 워낙 찾아보면 많이 나오는 편이라서;; 근데 또 막상 찾아서 쓸라 하면 또 GPL이고 그래서 짜려니 귀찮고 그런경우가 많다 말이죠 ..&#10;그런이유로 -_-;; 간단히 막 짜서 쓸려고 만든것좀 공유해 봅니다.&#10;Go // // Author: PIROGOM // https://modu-print.com // mop.pirogom@gmail.com // MIT License // package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/hex" "encoding/pem" "errors" "io/ioutil" ) type RSAHelper struct { PriKey rsa.PrivateKey PubKey rsa.PublicKey } / * RSA Key 생성 / func (r RSAHelper) GenerateKey(bits int) error { privateKey, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { r.PriKey = nil r.PubKey = nil return err } r.PriKey = privateKey r.PubKey = &amp;privateKey.PublicKey return nil } func (r RSAHelper) GetPrivate() rsa.PrivateKey { return r.PriKey } func (r RSAHelper) GetPublic() rsa.PublicKey { return r.PubKey } /** PrivateToBytePEM *&#9;PrivateToStringPEM / func (r RSAHelper) PrivateToBytePEM() ([]byte, error) { if r.PriKey == nil { return nil, errors.New("private rsa key is nil") } privateKeyBytes := x509.MarshalPKCS1PrivateKey(r.PriKey) privateKeyPEM := pem.EncodeToMemory( &amp;pem.Block{ Type: "RSA PRIVATE KEY", Bytes: privateKeyBytes, }, ) return privateKeyPEM, nil } func (r RSAHelper) PrivateToStringPEM() (string, error) { pemBuf, err := r.PrivateToBytePEM() if err != nil { return "", err } return string(pemBuf), nil } / *&#9;PrivateFromBytePEM *&#9;PrivateFromFilePEM / func (r RSAHelper) PrivateFromBytePEM(privateKeyPEM []byte) error { block, _ := pem.Decode(privateKeyPEM) if block == nil { r.PriKey = nil return errors.New("invalid PEM Block(private key)") } privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { r.PriKey = nil return err } r.PriKey = privateKey return nil } func (r RSAHelper) PrivateFromStringPEM(privateKeyPEM string) error { return r.PrivateFromBytePEM([]byte(privateKeyPEM)) } func (r *RSAHelper) PrivateFromFilePEM(filename string) error { fileBuf, err := ioutil.ReadFile(filename) if err != nil { return err } err = r.PrivateFromBytePEM(fileBuf) return err } / *&#9;PublicToBytePEM * PublicToStringPEM / func (r RSAHelper) PublicToBytePEM() ([]byte, error) { if r.PubKey == nil { return nil, errors.New("public rsa key is nil") } publicKeyBytes, err := x509.MarshalPKIXPublicKey(r.PubKey) if err != nil { return nil, err } publicKeyPEM := pem.EncodeToMemory( &amp;pem.Block{ Type: "RSA PUBLIC KEY", Bytes: publicKeyBytes, }, ) return publicKeyPEM, nil } func (r RSAHelper) PublicToStringPEM() (string, error) { buf, err := r.PublicToBytePEM() if err != nil { return "", err } return string(buf), nil } / *&#9;PublicFromBytePEM / func (r RSAHelper) PublicFromBytePEM(publicKeyPEM []byte) error { block, _ := pem.Decode(publicKeyPEM) if block == nil { r.PubKey = nil return errors.New("invalid PEM Block (public key)") } publicKey, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { r.PubKey = nil return err } switch pub := publicKey.(type) { case rsa.PublicKey: r.PubKey = pub return nil default: return errors.New("invalid key type") } } func (r RSAHelper) PublicFromStringPEM(publicKeyPEM []byte) error { return r.PublicFromBytePEM([]byte(publicKeyPEM)) } func (r RSAHelper) PublicFromFilePEM(filename string) error { fileBuf, err := ioutil.ReadFile(filename) if err != nil { return err } err = r.PublicFromBytePEM(fileBuf) return err } / *&#9;EncryptByte / func (r RSAHelper) EncryptByte(src []byte) ([]byte, error) { if r.PubKey == nil { return nil, errors.New("public key is nil") } ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, r.PubKey, src) if err != nil { return nil, err } return ciphertext, nil } func (r RSAHelper) EncryptString(src string) (string, error) { enc, err := r.EncryptByte([]byte(src)) if err != nil { return "", err } return hex.EncodeToString(enc), nil } / * DecryptByte **/ func (r RSAHelper) DecryptByte(src []byte) ([]byte, error) { if r.PriKey == nil { return nil, errors.New("private key is nil") } plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, r.PriKey, src) if err != nil { return nil, err } return plaintext, nil } func (r RSAHelper) DecryptString(src string) (string, error) { bsrc, err := hex.DecodeString(src) if err != nil { return "", err } dec, err := r.DecryptByte(bsrc) if err != nil { return "", err } return string(dec), nil }</description></item><item><title>[Go언어/GUI] WebView이용시 자바스크립트 오류 문제</title><link>https://modu-print.com/posts/2097/</link><pubDate>Mon, 28 Feb 2022 12:10:00 +0900</pubDate><guid>https://modu-print.com/posts/2097/</guid><description>앞서 Go언어의 lxn/win, lxn/walk 그리고 제가 막 만든(강조합니다 막 만든겁니다) walk_wrap.go 를 이용해서 윈도 GUI 프로그래밍을 할때.. 웹뷰를 추가 가능한데요..&#10;이 웹뷰는 ..&#10;IE기반의 OLE 객체를 끌어다 동작을 하는지라 최신 웹 브라우저에 비해선 기능이 조금 ;; 제한적이긴 합니다. 그중 가장큰 문제는 .. 자바스크립트 오류가 발생시에는 .. &#10;이런식으로 스크립트 오류창이 뜬다는 것이지요. 최신 브라우져들의 경우엔 개발자도구를 지원하기 때문에 이런식으로 자바스크립트 오류가 뜬다해서 메시지 창을 띄워가며 실행을 하네마네를 묻지 않습니다. 이게 상당히 거슬리는데 ..</description></item><item><title>1/1000초, 밀리세컨드, Milliseconds 얻기</title><link>https://modu-print.com/posts/3384/</link><pubDate>Sat, 26 Feb 2022 09:34:00 +0900</pubDate><guid>https://modu-print.com/posts/3384/</guid><description>Go언어에서 일반적으로 시간을 다루는 패키지는 time 이라는 기본 패키지를 사용합니다. 이 패키지를 통해서 time.Now().Unix() 로 Timestamp 값도 얻을수 있곤 합니다만.. &#10;흔히 윈도에서 프로그래밍을 많이 한 분들은 1/1000초 단위.. 그러니까 밀리세컨드 단위의 시간을 다루는걸 더 선호하시는 경우가 많습니다. &#10;하지만 Go언어의 time 패키지에는 직접적으로 밀리세컨드를 얻을 수 있는 함수는 존재하지 않습니다.&#10;Go /** *&#9;timeGetTime **/ func timeGetTime() int64 { return time.Now().UnixNano() / 1000000 } 결론은 .. 나노 세컨드를 나눠서 쓰시면 되겠습니다.. 너무 복잡하고 어렵게 생각 마세요 ㅋㅋ 어짜피 컴퓨터라는 놈의 시간 정확도라는 것은 그리 정확하지 않답니다 ㅋㅋ</description></item><item><title>[Go언어/GUI] WebView 로딩 문제 ..</title><link>https://modu-print.com/posts/2100/</link><pubDate>Tue, 22 Feb 2022 09:21:00 +0900</pubDate><guid>https://modu-print.com/posts/2100/</guid><description>앞서 강좌?? 까진 아니어도 여튼간에.. Go언어에서 윈도 Gui를 구성하는 법에 대한 글들 중 웹뷰를 설명한 적 있는데요. 이 웹뷰를 사용함에 있어서 한 가지 눈에 거슬리는 부분이 생기실겁니다.&#10;보시면.. 창이 뜨고 잠시후에 웹뷰가 표시되는 걸 보실 수 있는데요.. 이건 이 IWebBrowser2라는 놈이 OLE/COM 그러니까 흔히 말하는 OCX로 만들어진 놈이라.. &#10;원래 MFC로 다이얼로그 베이스의 프로그램을 만들거나 할 경우에는 프로그램의 생성자 즈음에 이 OCX객체의 초기화 관련 코드도 진행을 하기 때문에 .. 창이 표시되기 전에 웹뷰 관련 초기화가 이미 진행이 된 상태라 창이 표시되는 시점과 웹뷰가 준비된 시점이 거의 비슷하지만..</description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #13</title><link>https://modu-print.com/posts/2092/</link><pubDate>Wed, 16 Feb 2022 10:40:00 +0900</pubDate><guid>https://modu-print.com/posts/2092/</guid><description>앞서 12개의 글을 쓰면서 작성한 예제 코드를 올립니다.&#10;예제코드 다운로드 받기&#10;포함된 파일들에 대해서 설명 드리자면&#10;DEMO.ico, test.ico 아이콘 파일입니다. img0.png, img1.png, img3.png ImageView 예제에서 사용된 이미지 파일입니다. list_model.go, list_sample.go, test_table_cbmodel.go TableView 예제를 포함한 소스파일 main.go main 함수가 존재하고 대부분의 예제에 사용된 함수들이 있습니다. Makefile make 명령을 위한 Makefile walk_wrap.go 피로곰이 막 만든 walk 랩퍼 WALK_WRAP.manifest syso 파일을 만들기 위한 메니페스트 파일 WALK_WARP.syso rsrc 명령으로 만들어진 오브젝트 파일 우선</description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #12</title><link>https://modu-print.com/posts/2090/</link><pubDate>Wed, 16 Feb 2022 10:29:00 +0900</pubDate><guid>https://modu-print.com/posts/2090/</guid><description>아마 walk와 제가 대충 만든 walk_wrap.go 를 이용한 윈도 gui 프로그래밍에 대한 글은 이게 마지막? 이지 않을까 싶은데요 응용법이나 그런걸 좀더 세세하게 글을 더 쓸지는 모르겠지만.&#10;이번에 다룰 내용은 특정 GUI요소에 대한게 아니라 Go와 Walk를 가지고 윈도GUI를 함에 있어서 가장 주의해야할 사항을 말씀드리겠습니다.&#10;Go언어의 가장큰 장점은 동시성 프로그래밍이 매우 단순하다는 것이지요..&#10;흔히 윈도 프로그래밍을 할때 스레드(Thread)를 생성할때는 위의 CreateThread나 _beginthread 같은 함수를 사용하는데 인자도 많고 복잡해 보입니다.. </description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #11</title><link>https://modu-print.com/posts/2087/</link><pubDate>Wed, 16 Feb 2022 09:35:00 +0900</pubDate><guid>https://modu-print.com/posts/2087/</guid><description>이번에는 .. 얼마전에 모두의 프린터 업데이트 하면서 추가시킨 웹뷰(WebView)를 다뤄보도록 하겠습니다.&#10;한가지 주의 하실점은 윈도 API에서 지원하는 WebView는 흔히 IWebBrowser2 라고 불리는 COM+로 오랜세월 윈도에 내장된 레거시 브라우져 컴포넌트를 이용하게 됩니다. 그말은 현재 우리가 많이쓰는 HTML5 기반의 크롬이나 엣지나 파이어폭스 같은 브라우저보다 몇세대 전 기술을 사용하는 .. &#10;그냥 쉽게 IE라고 보시면 됩니다. 그렇다 보니 너무 최신의 CSS나 HTML, Javascript 를 사용한 페이지 에서는 스크립트 오류나 기타 여러 증상이 나타날 순 있습니다.</description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #10</title><link>https://modu-print.com/posts/2084/</link><pubDate>Fri, 04 Feb 2022 10:31:00 +0900</pubDate><guid>https://modu-print.com/posts/2084/</guid><description>오랜만입니다.. 이래저래 벌린일이 많다보니 ..&#10;이번에는 PushButton 과 ImageView 를 다뤄 보겠습니다.. 푸쉬 버튼의 경우에는 워낙 오만 예제에서 이미 다 등장을 햇던 놈이라 굳이 설명을 하지 않더라도 대충;; 뭔지 아실테지만 .. 간단하게나마 설명하고 넘어가겠습니다.&#10;Go / *&#9;PushButton / func (m WinResMgr) PushButton(text string, clickFunc func()) walk.PushButton { btn, _ := walk.NewPushButton(m.GetParent()) btn.SetText(text) btn.Clicked().Attach(clickFunc) m.addObj(btn) return btn }</description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #9</title><link>https://modu-print.com/posts/2081/</link><pubDate>Tue, 11 Jan 2022 22:21:00 +0900</pubDate><guid>https://modu-print.com/posts/2081/</guid><description>이번엔 가장 활용도가 높은 편인 테이블뷰에 대해서 알려드리겠습니다.&#10;우선;; interface{}를 사용해서 조금 고급지게 리스트박스를 위한 모델구조를 잡고 하면 보긴 좋긴 하겠으나 애초에 그냥 막 짜서 적용해서 쓰기 바쁜 와중에 만들어 쓴 코드고.. &#10;lxn/walk 의 샘플 코드에 존재하는 것들을 크게 건드리지 않고 사용하다보니 그닥 맘에 드는 구조는 아니라는 점은 미리 말씀드립니다.&#10;우선 테이블을 구성하기 위해서는 2개의 구조체와 몇가지 메소드를 미리 작성하셔야 합니다.</description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #8</title><link>https://modu-print.com/posts/2079/</link><pubDate>Mon, 10 Jan 2022 12:06:00 +0900</pubDate><guid>https://modu-print.com/posts/2079/</guid><description>이번에는 .. 드롭다운박스를 다뤄보도록 하겠습니다.&#10;Go func comboTest1() { mgr, _ := NewWindowMgrNoResize("콤보박스 테스트", 640, 200, GetIcon()) dd1 := mgr.DropDownBox([]string{"1.하하", "2.호호", "3.ㅋㅋ", "4.ㅎㅎ"}) dd1.CurrentIndexChanged().Attach(func() { fmt.Printf("선택된 인덱스 : %d, 선택된 값 : %s\n", dd1.CurrentIndex(), dd1.Text()) }) mgr.StartForeground() }</description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #7</title><link>https://modu-print.com/posts/2077/</link><pubDate>Mon, 03 Jan 2022 10:10:00 +0900</pubDate><guid>https://modu-print.com/posts/2077/</guid><description>이번엔 각종 설정창 등을 만드는데 어찌보면 가장 유용하게 사용하는 체크박스(Checkbox)에 대해서 다뤄보도록 하겠습니다.&#10;Go func (m *WinResMgr) CheckBox(text string, checked bool, attachFunc func()) *walk.CheckBox CheckBox 메소드를 사용하시면 되구요. </description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #6</title><link>https://modu-print.com/posts/2073/</link><pubDate>Thu, 23 Dec 2021 18:04:00 +0900</pubDate><guid>https://modu-print.com/posts/2073/</guid><description>이번엔 EditText? EditBox? 여튼;; 텍스트고 숫자고 입력을 받는 놈을 다뤄보겠습니다.&#10;Go func (m *WinResMgr) NumberEdit() *walk.NumberEdit func (m *WinResMgr) LineEdit(ro bool) *walk.LineEdit func (m *WinResMgr) TextEdit(ro bool) *walk.TextEdit func (m *WinResMgr) TextArea(ro bool) *walk.TextEdit 이정도 되겠습니다.. </description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #5</title><link>https://modu-print.com/posts/2069/</link><pubDate>Fri, 17 Dec 2021 11:07:00 +0900</pubDate><guid>https://modu-print.com/posts/2069/</guid><description>이번에는 각 UI구성 요소들에 대한 부분을 진행 해보도록 합시다.&#10;대충 일반적으로 말하는 라벨(Label, Static Text), 에디트박스, 체크박스, 리스트박스, 이미지컨트롤, 콤보박스 이딴 것들에 대해 논해보도록 합니다. 이러한 놈들은 얼찌 배치 할지는 이전 시간에 다뤘으니까 이전글들 참고 하시고요, 그런 부분들은 직접 해보시면 충분할 거구요.. 그정도 코드도 직접 안짜보고 이해할꺼면 개발자 때려 쳐야죠.. 어디 ㅋㅋ 그런 정신 머리로 개발자 나부랭이를 해보겠다고 크앙!&#10;우선 가장 많이 쓰이는 놈중 하나인 라벨을 먼저 갑시다.</description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #4</title><link>https://modu-print.com/posts/2065/</link><pubDate>Fri, 10 Dec 2021 11:01:00 +0900</pubDate><guid>https://modu-print.com/posts/2065/</guid><description>Go로 윈도 네이티브 GUI 줘 패기... 4번째 입니다.&#10;이번엔 레이아웃에 대한 부분을 다뤄보도록 합니다.&#10;앞서 C/C++에서 윈도 API를 가지고 GUI 어플리케이션을 만드는게 매우 비효율적인 노가다 개삽질이라는 식의 표현을 한적이 있는데요. 그 이유는 ..&#10;API에서 모든 UI객체는 전부다 윈도입니다. 창도 윈도 버튼도 윈도 에디트 박스도 체크박스도 스크롤바도 스크롤바 안의 상하단 버튼도 죄~~다 윈도입니다. 그 말은 그 하나하나를 다 CreateWindow 를 하고 그 각 객체별로 WndProc 같은 메시지 프로시저를 한땀 한땀 다 등록을 시켜야 한단 소리죠 그래야 키보드 입력이던 마우스 클릭이던 내용을 그리고 지우고 지지고 볶고 .. 가 가능합니다.</description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #3</title><link>https://modu-print.com/posts/2058/</link><pubDate>Thu, 09 Dec 2021 12:27:00 +0900</pubDate><guid>https://modu-print.com/posts/2058/</guid><description>Go언어로 윈도GUI .. 3번째 글입니다.&#10;우선 관련 글들을 작성하면서 계속 사용하게될 소스파일 하나 먼저 던져 놓고 시작하겠습니다.&#10;walk_wrap.go&#10;Go // Copyright 2021 PIROGOM // MIT License // https://modu-print.tistory.com package main import ( "container/list" "io/ioutil" "os" "path/filepath" "sync" "github.com/lxn/walk" "github.com/lxn/win" ) const ( walkWinName = "WALK_WRAP" ) / *&#9;tableViewHeader / type tableViewHeader struct { Title string Width int Align string } / *&#9;WinResMgr / type WinResMgr struct { window walk.MainWindow parentList list.List } var ( gIcon walk.Icon iconMutex sync.Mutex ) /** LoadIcon / func LoadIcon(icoBuf []byte, icoName string) { icoFile := filepath.Join(os.TempDir(), icoName) var err error if , err = os.Stat(icoName); os.IsNotExist(err) { if err = ioutil.WriteFile(icoFile, icoBuf, 0644); err != nil { return } } iconMutex.Lock() gIcon, = walk.NewIconFromFile(icoFile) iconMutex.Unlock() } / *&#9;LoadIconFromFile / func LoadIconFromFile(icoPath string) { iconMutex.Lock() defer iconMutex.Unlock() gIcon, _ = walk.NewIconFromFile(icoPath) } / *&#9;GetIcon / func GetIcon() *walk.Icon { iconMutex.Lock() defer iconMutex.Unlock() return gIcon } / *&#9;MsgBox / func MsgBox(msg string, window …*walk.MainWindow) { if len(window) &gt; 0 { walk.MsgBox(window[0], "알림", msg, walk.MsgBoxOK|walk.MsgBoxSetForeground) } else { walk.MsgBox(nil, "알림", msg, walk.MsgBoxOK|walk.MsgBoxSetForeground) } } / *&#9;Confirm / func Confirm(msg string, window …*walk.MainWindow) bool { if len(window) &gt; 0 { if walk.MsgBox(window[0], "알림", msg, walk.MsgBoxYesNo|walk.MsgBoxSetForeground) == win.IDNO { return false } else { return true } } else { if walk.MsgBox(nil, "알림", msg, walk.MsgBoxYesNo|walk.MsgBoxSetForeground) == win.IDNO { return false } else { return true } } return false } / *&#9;NewWindowMgr / func NewWindowMgr(title string, width int, height int, icon walk.Icon) (WinResMgr, *walk.MainWindow) { rd := WinResMgr{} win, _ := walk.NewMainWindowWithName(walkWinName) rd.window = win rd.parentList = list.New() win.SetTitle(title) win.SetLayout(walk.NewVBoxLayout()) win.SetWidth(width) win.SetHeight(height) if icon != nil { win.SetIcon(icon) } return &amp;rd, win } / *&#9;NewWindowMgrNoResize / func NewWindowMgrNoResize(title string, width int, height int, icon walk.Icon) (WinResMgr, *walk.MainWindow) { rd := WinResMgr{} win, _ := walk.NewMainWindowWithName(walkWinName) rd.window = win rd.parentList = list.New() win.SetTitle(title) win.SetLayout(walk.NewVBoxLayout()) win.SetWidth(width) win.SetHeight(height) if icon != nil { win.SetIcon(icon) } win.SetMinMaxSize(walk.Size{Width: width, Height: height}, walk.Size{Width: width, Height: height}) rd.NoResize() return &amp;rd, win } / *&#9;NewWindowMgrNoResizeNoMinMax / func NewWindowMgrNoResizeNoMinMax(title string, width int, height int, icon walk.Icon) (WinResMgr, *walk.MainWindow) { rd := WinResMgr{} win, _ := walk.NewMainWindowWithName(walkWinName) rd.window = win rd.parentList = list.New() win.SetTitle(title) win.SetLayout(walk.NewVBoxLayout()) win.SetWidth(width) win.SetHeight(height) if icon != nil { win.SetIcon(icon) } win.SetMinMaxSize(walk.Size{Width: width, Height: height}, walk.Size{Width: width, Height: height}) rd.NoResize() rd.DisableMinMaxBox(true, true) return &amp;rd, win } / *&#9;NewWindowMgrAds / func NewWindowMgrAds(title string, width int, height int) (WinResMgr, walk.MainWindow) { rd := WinResMgr{} win, _ := walk.NewMainWindowWithName(walkWinName) rd.window = win rd.parentList = list.New() win.SetTitle(title) layout := walk.NewVBoxLayout() margin := walk.Margins{0, 0, 0, 0} layout.SetMargins(margin) layout.SetSpacing(0) win.SetLayout(layout) win.SetWidth(width) win.SetHeight(height) win.SetMinMaxSize(walk.Size{Width: width, Height: height}, walk.Size{Width: width, Height: height}) rd.NoResize() rd.DisableTitleBar() rd.AdsPosition() return &amp;rd, win } / *&#9;HideAndClose / func (m *WinResMgr) HideAndClose() { m.window.Synchronize(func() { m.window.SetVisible(false) m.window.Close() }) } / *&#9;Center / func (m *WinResMgr) Center() { var x, y, width, height int32 var rtDesk, rtWindow win.RECT win.GetWindowRect(win.GetDesktopWindow(), &amp;rtDesk) win.GetWindowRect(m.window.Handle(), &amp;rtWindow) width = rtWindow.Right - rtWindow.Left height = rtWindow.Bottom - rtWindow.Top x = (rtDesk.Right - width) / 2 y = (rtDesk.Bottom - height) / 2 win.MoveWindow(m.window.Handle(), x, y, width, height, true) } / *&#9;AdsPosition / func (m *WinResMgr) AdsPosition() { var x, y, width, height int32 var rtDesk, rtWindow win.RECT win.GetWindowRect(win.GetDesktopWindow(), &amp;rtDesk) win.GetWindowRect(m.window.Handle(), &amp;rtWindow) width = rtWindow.Right - rtWindow.Left height = rtWindow.Bottom - rtWindow.Top x = rtDesk.Right - width y = rtDesk.Bottom - (height + 40) win.MoveWindow(m.window.Handle(), x, y, width, height, true) } / *&#9;Foreground / func (m *WinResMgr) Foreground() { win.SetForegroundWindow(m.window.Handle()) } / *&#9;NoResize / func (m *WinResMgr) NoResize() { defStyle := win.GetWindowLong(m.window.Handle(), win.GWL_STYLE) newStyle := defStyle &amp;^ win.WS_THICKFRAME win.SetWindowLong(m.window.Handle(), win.GWL_STYLE, newStyle) } / *&#9;DisableMinMaxBox / func (m *WinResMgr) DisableMinMaxBox(minBox bool, maxBox bool) { defStyle := win.GetWindowLong(m.window.Handle(), win.GWL_STYLE) newStyle := defStyle if minBox { newStyle = newStyle &amp;^ win.WS_MINIMIZEBOX } if maxBox { newStyle = newStyle &amp;^ win.WS_MAXIMIZEBOX } win.SetWindowLong(m.window.Handle(), win.GWL_STYLE, newStyle) } / *&#9;DisableCloseBox / func (m *WinResMgr) DisableCloseBox() { defStyle := win.GetWindowLong(m.window.Handle(), win.GWL_STYLE) newStyle := defStyle &amp;^ win.WS_SYSMENU win.SetWindowLong(m.window.Handle(), win.GWL_STYLE, newStyle) } / *&#9;DisableTitleBar / func (m *WinResMgr) DisableTitleBar() { defStyle := win.GetWindowLong(m.window.Handle(), win.GWL_STYLE) newStyle := defStyle &amp;^ win.WS_CAPTION win.SetWindowLong(m.window.Handle(), win.GWL_STYLE, newStyle) } / *&#9;HSplit / func (m WinResMgr) HSplit() walk.Splitter { hs, _ := walk.NewHSplitter(m.GetParent()) m.parentList.PushBack(hs) return hs } / *&#9;VSplit / func (m WinResMgr) VSplit() walk.Splitter { vs, _ := walk.NewVSplitter(m.GetParent()) m.parentList.PushBack(vs) return vs } / *&#9;EndSplit / func (m *WinResMgr) EndSplit() { if m.parentList.Len() &gt; 0 { popData := m.parentList.Remove(m.parentList.Back()) parent := m.GetParent() parent.Children().Add(popData.(walk.Widget)) } } / *&#9;GroupBox / func (m WinResMgr) GroupBox(title string, isVertical bool) walk.GroupBox { gb, _ := walk.NewGroupBox(m.GetParent()) gb.SetTitle(title) if !isVertical { gb.SetLayout(walk.NewHBoxLayout()) } else { gb.SetLayout(walk.NewVBoxLayout()) } m.parentList.PushBack(gb) return gb } / *&#9;EndGroupBox / func (m *WinResMgr) EndGroupBox() { if m.parentList.Len() &gt; 0 { popData := m.parentList.Remove(m.parentList.Back()) parent := m.GetParent() parent.Children().Add(popData.(walk.Widget)) } } / *&#9;DefClosing / func (m *WinResMgr) DefClosing() { m.window.Closing().Attach(func(canceled bool, reason walk.CloseReason) { if m.window.Visible() { canceled = true } }) } / *&#9;StartWindow / func (m *WinResMgr) StartWindow() { m.Center() m.window.Show() m.window.Run() } / *&#9;StartForeground / func (m *WinResMgr) StartForeground() { m.Center() m.Foreground() m.window.Show() m.window.Run() } / *&#9;StartAds / func (m *WinResMgr) StartAds() { //m.AdsPosition() m.Foreground() m.window.Show() m.window.Run() } / *&#9;Hide / func (m *WinResMgr) Hide() { m.window.Hide() } / *&#9;ShowForeground / func (m *WinResMgr) ShowForeground() { m.Center() m.Foreground() m.window.Show() } / *&#9;HideStart / func (m *WinResMgr) HideStart() { m.window.Hide() m.window.Run() } / *&#9;addObj / func (m *WinResMgr) addObj(item walk.Widget) { if m.parentList.Len() == 0 { m.window.Children().Add(item) } else { parent := m.parentList.Back().Value.(walk.Container) parent.Children().Add(item) } } / *&#9;GetParent / func (m *WinResMgr) GetParent() walk.Container { if m.parentList.Len() &gt; 0 { parent := m.parentList.Back().Value.(walk.Container) return parent } else { return m.window } } / *&#9;MultiLineLabel / func (m WinResMgr) MultiLineLabel(text string) walk.Label { ne, _ := walk.NewLabelWithStyle(m.GetParent(), win.SS_EDITCONTROL) //|win.SS_CENTER) ne.SetText(text) ne.SetAlignment(walk.AlignHCenterVCenter) ne.SetTextAlignment(walk.AlignCenter) m.addObj(ne) return ne } / *&#9;Label / func (m WinResMgr) Label(text string) walk.Label { ne, _ := walk.NewLabel(m.GetParent()) ne.SetText(text) ne.SetTextAlignment(walk.AlignDefault) m.addObj(ne) return ne } / * LabelCenter / func (m WinResMgr) LabelCenter(text string) walk.Label { ne, _ := walk.NewLabel(m.GetParent()) ne.SetText(text) ne.SetTextAlignment(walk.AlignCenter) m.addObj(ne) return ne } / * LabelRight / func (m WinResMgr) LabelRight(text string) walk.Label { ne, _ := walk.NewLabel(m.GetParent()) ne.SetText(text) ne.SetTextAlignment(walk.AlignFar) m.addObj(ne) return ne } / * LabelLeft / func (m WinResMgr) LabelLeft(text string) walk.Label { ne, _ := walk.NewLabel(m.GetParent()) ne.SetText(text) ne.SetTextAlignment(walk.AlignNear) m.addObj(ne) return ne } / *&#9;CheckBox / func (m WinResMgr) CheckBox(text string, checked bool, attachFunc func()) walk.CheckBox { cb, _ := walk.NewCheckBox(m.GetParent()) cb.SetText(text) cb.SetChecked(checked) cb.CheckStateChanged().Attach(attachFunc) m.addObj(cb) return cb } / *&#9;DropDownBox / func (m WinResMgr) DropDownBox(data []string) walk.ComboBox { cb, _ := walk.NewDropDownBox(m.GetParent()) cb.SetModel(data) cb.SetCurrentIndex(0) m.addObj(cb) return cb } / *&#9;PushButton / func (m WinResMgr) PushButton(text string, clickFunc func()) walk.PushButton { btn, _ := walk.NewPushButton(m.GetParent()) btn.SetText(text) btn.Clicked().Attach(clickFunc) m.addObj(btn) return btn } / *&#9;NumberEdit / func (m WinResMgr) NumberEdit() walk.NumberEdit { ne, _ := walk.NewNumberEdit(m.GetParent()) m.addObj(ne) return ne } / *&#9;NumberEdit / func (m WinResMgr) NumberEditInt(val int) walk.NumberEdit { ne, _ := walk.NewNumberEdit(m.GetParent()) ne.SetValue(float64(val)) m.addObj(ne) return ne } / *&#9;LineEdit / func (m WinResMgr) LineEdit(ro bool) walk.LineEdit { ne, _ := walk.NewLineEdit(m.GetParent()) ne.SetReadOnly(ro) m.addObj(ne) return ne } / *&#9;TextEdit / func (m WinResMgr) TextEdit(ro bool) walk.TextEdit { ne, _ := walk.NewTextEdit(m.GetParent()) ne.SetReadOnly(ro) m.addObj(ne) return ne } / *&#9;TextEdit / func (m WinResMgr) TextEdit2(msg string, ro bool) walk.TextEdit { ne, _ := walk.NewTextEdit(m.GetParent()) ne.SetText(msg) ne.SetReadOnly(ro) m.addObj(ne) return ne } / *&#9;TextArea / func (m WinResMgr) TextArea(ro bool) walk.TextEdit { ne, _ := walk.NewTextEditWithStyle(m.GetParent(), win.WS_VSCROLL) ne.SetReadOnly(ro) m.addObj(ne) return ne } / *&#9;Slider / func (m WinResMgr) Slider(minVal int, maxVal int, defVal int) walk.Slider { ne, _ := walk.NewSlider(m.GetParent()) ne.SetRange(minVal, maxVal) ne.SetValue(defVal) m.addObj(ne) return ne } / *&#9;TableView / func (m WinResMgr) TableView(model interface{}, header []tableViewHeader, checkBox bool, multiSelect bool) walk.TableView { tv, _ := walk.NewTableView(m.GetParent()) tv.SetCheckBoxes(checkBox) tv.SetMultiSelection(multiSelect) tv.SetModel(model) for i := 0; i &lt; len(header); i++ { col := walk.NewTableViewColumn() col.SetTitle(header[i].Title) col.SetWidth(header[i].Width) switch header[i].Align { case "center": col.SetAlignment(walk.AlignCenter) case "right": col.SetAlignment(walk.AlignFar) case "left": col.SetAlignment(walk.AlignNear) } tv.Columns().Add(col) } m.addObj(tv) return tv } / *&#9;ImageViewFromFile / func (m WinResMgr) ImageViewFromFile(imgFile string) walk.ImageView { iv, _ := walk.NewImageView(m.GetParent()) img, imgErr := walk.NewImageFromFile(imgFile) if imgErr == nil { iv.SetImage(img) } m.addObj(iv) return iv } / *&#9;ImageViewFromFile2 / func (m WinResMgr) ImageViewFromFile2(imgFile string, im walk.ImageViewMode) walk.ImageView { iv, _ := walk.NewImageView(m.GetParent()) img, imgErr := walk.NewImageFromFile(imgFile) if imgErr == nil { iv.SetMode(im) iv.SetImage(img) } m.addObj(iv) return iv } / *&#9;ImageView / func (m WinResMgr) ImageView() walk.ImageView { iv, _ := walk.NewImageView(m.GetParent()) m.addObj(iv) return iv } / *&#9;LoadImage / func LoadImage(fileName string) *walk.Image { retImage, retImageErr := walk.NewImageFromFile(fileName) if retImageErr != nil { return nil } return &amp;retImage } / *&#9;SetMultiLineText **/ func MultiLineText(text string, limit int) string { runeText := []rune(text) var res string for { if len(runeText) &lt;= limit { res += string(runeText) break } res += string(runeText[:limit]) + "\n" runeText = runeText[limit:] } return res }</description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #2</title><link>https://modu-print.com/posts/2055/</link><pubDate>Wed, 08 Dec 2021 11:03:00 +0900</pubDate><guid>https://modu-print.com/posts/2055/</guid><description>Go로 윈도 네이티브 GUI 프로그램만들기 2번째 입니다.&#10;앞서 lxn/win, walk 2개 패키지는 go get 하셨을 테구요.. 보통 윈도 API 프로그래밍은 C/C++ 에서도 노가다의 최 정점에 놓여진 그런 놈입니다 ㅋㅋ 그게 싫어서 쓰는게 go 같은 언어들인거고 .. &#10;그런 이유로 이 lxn/walk 의 경우에도 좀더 편하게 GUI를 만들수 있는 방법을 제공하는데요.&#10;그게 lxn/walk 패키지에 포함된 declarative 라는 패키지 입니다. </description></item><item><title>Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #1</title><link>https://modu-print.com/posts/2047/</link><pubDate>Wed, 08 Dec 2021 10:00:00 +0900</pubDate><guid>https://modu-print.com/posts/2047/</guid><description>앞서 크롤러 관련된 강좌를 하다 만게 있는데요.. 요청이 가장 많았어서 시작을 하긴 했는데 아무래도 크롤러가 개발자 입장으론 윤리문제가 좀 있는 영역이고 법적으로도 문제 소지가 발생할 가능성이 매우 큰 영역이라 그걸 대놓고 강좌랍시고 하는 건 좀 ;; 아닌 것 같다는 피드백도 꽤 됐던 지라.. 크롤러 관련된 강좌는 하지 않겠습니다.&#10;저는 Go개발에 MS의 Visual Studio Code를 사용합니다. 관련 사항은 이전 111GO 글을 참고바랍니다.</description></item><item><title>MS VC++ 재배포가능 패키지 존재여부 체크</title><link>https://modu-print.com/posts/3382/</link><pubDate>Sat, 06 Nov 2021 09:32:00 +0900</pubDate><guid>https://modu-print.com/posts/3382/</guid><description>보통 윈도 API를 쓰는 프로그램을 개발해서 배포를할 경우에 .. 적절한 시스템 DLL 이 존재하지 않으면 .. 프로그램이 그냥 죽어버립니다 ㅎㅎ 그래서 많은 프로그램들이 위와같은 .. 재배포가능 패키지를 같이 설치하곤 합니다만 ..&#10;여튼간에 ;; 개발을 하다보면 시스템에 재배포가능 패키지가 존재하는지 안하는지를 ;; 버전 상관 없이 ..&#10;한놈만 있음 되는 그런 상황이 오게 되지요 ..</description></item><item><title>Go 윈도 프로그래밍시 실행파일에 리소스정보 적용</title><link>https://modu-print.com/posts/3743/</link><pubDate>Mon, 18 Oct 2021 12:05:00 +0900</pubDate><guid>https://modu-print.com/posts/3743/</guid><description>우선 Walk를 쓰던 뭘 하던 윈도용 프로그램을 만드는 경우에는 .. 프로그램의 아이콘을 지정하고 싶기도 하고 .. &#10;프로그램의 기본 아이콘과 보통 윈도 프로그래밍에서 말하는 메니페스트(Manifest)의 적용은 rsrc 라는 패키지를 통해 합니다.&#10;GitHub - akavel/rsrc: Tool for embedding .ico &amp; manifest resources in Go programs for Windows. Tool for embedding .ico &amp; manifest resources in Go programs for Windows. - GitHub - akavel/rsrc: Tool for embedding .ico &amp; manifest resources in Go programs for Windows. 요 패키지를 go get ( 최근 go에서는 go install ) 해서 우선 설치하시면 되구요.</description></item><item><title>윈도 프로그래밍시 파일 Dialog에서 네트워크 드라이브 표시 안될경우</title><link>https://modu-print.com/posts/3861/</link><pubDate>Thu, 07 Oct 2021 13:13:00 +0900</pubDate><guid>https://modu-print.com/posts/3861/</guid><description>개발 언어관련된 부분은 아니지만 .. 이글 하나 때문에 카테고리를 추가하기도 좀 그래서 WinAPI 관련으로 보고 이 카테고리에 적어봅니다.&#10;윈도 비스타 이후에 UAC라는 사용자 계정 컨트롤이라는 개념이 생기고 로그인 권한이나 세션권한이 고도화 되면서 발생하는 부작용? 같은거라고 보면 되겠으나 ...&#10;하여튼간에 ;; &#10;이런식으로 파일 선택 기능에 네트워크 드라이브가 표시가 될것이라 생각하지만 .. 안보이는 경우가 생길겁니다.</description></item><item><title>폴더 복사하기</title><link>https://modu-print.com/posts/3389/</link><pubDate>Tue, 07 Sep 2021 09:45:00 +0900</pubDate><guid>https://modu-print.com/posts/3389/</guid><description>Go에서 파일의 복사도 그렇지만 폴더를 복사하는건 .. 일일이 폴더명 따져서 생성을 시키고 파일도 따로따로 복사해대고 하는걸 반복해야 하는 작업입니다.&#10;특정폴더를 다른 위치로 복사하고 싶을때 사용하시면 됩니다.&#10;Go package main import ( "fmt" "io" "io/ioutil" "os" "path/filepath" ) / *&#9;CopyFile / func CopyFile(src, dst string) (err error) { in, err := os.Open(src) if err != nil { return } defer in.Close() out, err := os.Create(dst) if err != nil { return } defer func() { if e := out.Close(); e != nil { err = e } }() , err = io.Copy(out, in) if err != nil { return } err = out.Sync() if err != nil { return } si, err := os.Stat(src) if err != nil { return } err = os.Chmod(dst, si.Mode()) if err != nil { return } return } / *&#9;CopyDir / func CopyDir(src string, dst string) (err error) { src = filepath.Clean(src) dst = filepath.Clean(dst) si, err := os.Stat(src) if err != nil { return err } if !si.IsDir() { return fmt.Errorf("source is not a directory") } , err = os.Stat(dst) if err != nil &amp;&amp; !os.IsNotExist(err) { return } if err == nil { return fmt.Errorf("destination already exists") } err = os.MkdirAll(dst, si.Mode()) if err != nil { return } entries, err := ioutil.ReadDir(src) if err != nil { return } for _, entry := range entries { srcPath := filepath.Join(src, entry.Name()) dstPath := filepath.Join(dst, entry.Name()) if entry.IsDir() { err = CopyDir(srcPath, dstPath) if err != nil { return } } else { // Skip symlinks. if entry.Mode()&amp;os.ModeSymlink != 0 { continue } err = CopyFile(srcPath, dstPath) if err != nil { return } } } return }</description></item><item><title>Go언어에서 ShellExcute, ShellExcuteEx 함수 사용하기</title><link>https://modu-print.com/posts/3866/</link><pubDate>Mon, 06 Sep 2021 13:19:00 +0900</pubDate><guid>https://modu-print.com/posts/3866/</guid><description>Go언어에 exec 패키지를 통해 exec.Command().Run 이나 Start등으로 외부 명령을 실행할 수 있으나 이 함수들의 단점은 CreateProcess 기반인데다 부가적인 옵션이 거의 존재하지 않습니다. 예를들면 Run 함수의 경우에는 실행시킨 명령이 종료되기 전까진 대기를 해야 하지만 콘솔 어플리케이션이 아닌 윈도 어플리케이션을 호출하는 경우 일반적으로 콘솔기준에선 바로 실행이 끝난것으로 넘어오기 때문에 .. 조금 맞지 않는 부분이 생기구요..&#10;예를들어 윈도 프로그래밍에선 ShellExcuteEx 를 사용한뒤에 WaitForSingleEvent 같은 함수로 해당 프로세스의 종료까지 대기가 가능하고 명령어를 open 이 아닌 runAs 같은걸 지정하면 관리자권한으로 실행등의 부가적인 효과를 얻을 수 있습니다.</description></item><item><title>현재 윈도가 32비트인지 64비트 인지 확인</title><link>https://modu-print.com/posts/3864/</link><pubDate>Mon, 06 Sep 2021 13:17:00 +0900</pubDate><guid>https://modu-print.com/posts/3864/</guid><description>Go언어는 개발하는 컴퓨터의 OS나 아키택처 상관 없이 다양한 플랫폼을 대상으로 실행파일 빌드가 가능합니다만. runtime 패키지의 GOARCH나 GOOS 등은 컴파일시에 해당 바이너리가 타겟으로 잡은 정보가 나올뿐 실제 현 시스템에 대한 정보를 대변하진 않습니다.&#10;예를들어 64비트 윈도에서 32비트 실행파일을 실행이 가능한데 runtime.GOARCH 정보를 보면 386 으로 뜨게 되지요..&#10;이런 경우 실제 OS의 CPU 아키텍처 정보를 얻으려면 시스템 정보를 얻어와야 합니다.</description></item><item><title>특정 경로의 총 파일 사이즈, 폴더 갯수, 파일 갯수 얻기</title><link>https://modu-print.com/posts/3375/</link><pubDate>Sat, 26 Jun 2021 00:01:00 +0900</pubDate><guid>https://modu-print.com/posts/3375/</guid><description>지정한 경로내의 총 파일 크기의 합과 폴더, 파일의 갯수를 리턴해주는 함수입니다.&#10;관리자 대시보드등에서 특정 경로의 사용용량등을 표시하는데 쓰시면 되겠습니다.&#10;Go / *&#9;dirUsage / func dirUsage(currentPath string, info os.FileInfo, fileCnt int64, dirCnt int64) int64 { size := info.Size() if !info.IsDir() { return size } dir, err := os.Open(currentPath) if err != nil { return 0 } defer dir.Close() fis, err := dir.Readdir(-1) if err != nil { return 0 } for _, fi := range fis { if fi.Name() == "." || fi.Name() == ".." { continue } if fi.IsDir() { dirCnt++ } else { fileCnt++ } size += dirUsage(currentPath+"/"+fi.Name(), fi, fileCnt, dirCnt) } return size } / *&#9;getDirectorySize / func getDirectorySize(path string) (int64, int64, int64, error) { info, err := os.Lstat(path) if err != nil { return 0, 0, 0, err } var dirCnt int64 var fileCnt int64 size := dirUsage(path, info, &amp;fileCnt, &amp;dirCnt) return size, fileCnt, dirCnt, nil }</description></item><item><title>JSON 오브젝트 사이즈 얻기</title><link>https://modu-print.com/posts/3893/</link><pubDate>Wed, 23 Jun 2021 15:58:00 +0900</pubDate><guid>https://modu-print.com/posts/3893/</guid><description>일반적으로 자바스크립트에서 배열등의 크기를 얻을떄는 .length 를 통해 얻습니다만 .. 이게 JSON 파싱등을 통해서 얻은 오브젝트에 포함된 경우에는 length 변수의 값으로는 얻어지지 않습니다. 그런경우 참고하세요.&#10;JavaScript function jsonLength(objVal){ if( !objVal ){ return 0; } return Object.keys(objVal).length; }</description></item><item><title>mysql/mariadb DATETIME -&gt; 년/월/일 시:분:초 변환</title><link>https://modu-print.com/posts/3859/</link><pubDate>Wed, 23 Jun 2021 13:12:00 +0900</pubDate><guid>https://modu-print.com/posts/3859/</guid><description>JavaScript function convDateFormat(dbDate){ var date = new Date(dbDate) var year = date.getFullYear(); var month = (1 + date.getMonth()); month = month &gt;= 10 ? month : '0' + month; var day = date.getDate(); day = day &gt;= 10 ? day : '0' + day; var hour = date.getHours() hour = hour &gt;= 10 ? hour : "0" + hour; var minute = date.getMinutes() minute = minute &gt;= 10 ? minute : "0" + minute; var sec = date.getSeconds() sec = sec &gt;= 10 ? sec : "0" + sec; return year + '/' + month + '/' + day + " " + hour + ":" + minute + ":" + sec; }</description></item><item><title>바이트를 KB, MB, GB 등의 Human Readable로 변환</title><link>https://modu-print.com/posts/3855/</link><pubDate>Wed, 23 Jun 2021 13:05:00 +0900</pubDate><guid>https://modu-print.com/posts/3855/</guid><description>JS작업을 하다보면 .. 바이트 단위의 파일 사이즈등을 MB 등의 단위로 표시해야 할 경우가 있습니다.&#10;그런경우에 사용가능한 .. 변환 함수입니다..&#10;JavaScript function bytesToHumanSize(bytes) { var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; if (bytes == 0){ return '0 Byte'; } var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); if (i &gt; 4) { return Math.round(bytes / Math.pow(1024, i), 2); } return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i]; };</description></item><item><title>CreateProcessAsUser - 서비스에서 GUI포함한 프로그램 실행</title><link>https://modu-print.com/posts/3870/</link><pubDate>Mon, 21 Jun 2021 13:22:00 +0900</pubDate><guid>https://modu-print.com/posts/3870/</guid><description>일반적으로 윈서 서비스 프로그램은 일반 어플리케이션과 다른 영역에서 실행되기 때문에.. 서비스가 SheelExecute나 CreateProcess 함수등으로 실행한 프로그램들은 GUI를 포함하고 있다하더라도 화면에 표시되지 않습니다.&#10;이러한 이유로 서비스 프로세스에서 .. GUI를 포함한 프로그램을 실행하려 하는 경우에는 ..&#10;CreateProcessAsUser 함수를 통해서 실행을 해줘야 합니다.&#10;이떄 사용가능한 함수인데요..&#10;이 함수 인자가 2개인데요 szExeName, lpCommandLine 2개인데 ..</description></item><item><title>ShellExcute - 프로세스 종료까지 대기</title><link>https://modu-print.com/posts/3868/</link><pubDate>Mon, 21 Jun 2021 13:20:00 +0900</pubDate><guid>https://modu-print.com/posts/3868/</guid><description>MFC나 API 에서 외부 실행파일을 실행하는데 가장 많이쓰는게 ShellExcute 인데요 .. 간혹 .. 실행시킨 프로세스가 종료될때까지 대기해야 하는경우가 있습니다 그런때 사용하면 됩니다.&#10;C++ ::ZeroMemory(&amp;sei, sizeof(SHELLEXECUTEINFO)); sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.lpFile = ("실행파일"); sei.lpDirectory = ("실행경로"); sei.lpParameters = _T("실행인자"); sei.nShow = SW_HIDE; sei.fMask = SEE_MASK_NOCLOSEPROCESS; sei.lpVerb = _T("open"); DWORD result = ::ShellExecuteEx(&amp;sei); if (sei.hProcess != NULL) { // 프로세스 종료까지 대기 WaitForSingleObject(sei.hProcess, INFINITE); }</description></item><item><title>CreateProcess 예제</title><link>https://modu-print.com/posts/3739/</link><pubDate>Mon, 21 Jun 2021 11:53:00 +0900</pubDate><guid>https://modu-print.com/posts/3739/</guid><description>보통 다른 프로그램을 프로그래밍 적으로 실행을 하려면 ShellExcute 함수를 많이 쓰긴 합니다만.. 다른 이유로 CreateProcess 로 실행을 해야 하는 경우도 있지요 .. PID로 뭔가를 해야 한다거나 .. 등등...&#10;그런때 쓰시면 됩니다.&#10;C++ / * RunProcess / BOOL RunProcess(TCHAR* szExeName) { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&amp;si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&amp;pi, sizeof(pi)); // Start the child process. if (!CreateProcess(NULL, // No module name (use command line) szExeName, // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &amp;si, // Pointer to STARTUPINFO structure &amp;pi) // Pointer to PROCESS_INFORMATION structure ) { return FALSE; } // Wait until child process exits. WaitForSingleObject(pi.hProcess, INFINITE); // Close process and thread handles. CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return TRUE; }</description></item><item><title>TEA Encryption Algorithm, TEA 암호화 알고리즘</title><link>https://modu-print.com/posts/3879/</link><pubDate>Wed, 09 Jun 2021 13:29:00 +0900</pubDate><guid>https://modu-print.com/posts/3879/</guid><description>C++ // Encryption ( 8 Byte ) void encipher( unsigned long const v, unsigned long const w, const unsigned long const k ) { register unsigned long y = v[0], z = v[1], sum = 0, delta = 0x9E3779B9, a = k[0], b = k[1], c = k[2], d = k[3], n = 8; while(n–&gt;0) { sum += delta; y += (z &lt;&lt; 4)+a ^ z+sum ^ (z &gt;&gt; 5)+b; z += (y &lt;&lt; 4)+c ^ y+sum ^ (y &gt;&gt; 5)+d; } w[0] = y; w[1] = z; } // Decryption void decipher( unsigned long const v, unsigned long const w, const unsigned long const k ) { register unsigned long y = v[0], z = v[1], sum = 0, delta = 0x9E3779B9, a = k[0], b = k[1], c = k[2], d = k[3], n = 8; //sum = delta&lt;&lt;5;//, in general sum = delta * n / sum = delta n; while(n–&gt;0) { z -= (y &lt;&lt; 4)+c ^ y+sum ^ (y &gt;&gt; 5)+d; y -= (z &lt;&lt; 4)+a ^ z+sum ^ (z &gt;&gt; 5)+b; sum -= delta; } w[0] = y; w[1] = z; } / *&#9;TEA_EncryptData / unsigned long TEA_EncryptData( char plainData, char encData, unsigned long size , unsigned long key ) { unsigned long dwPos = 0; for( unsigned long i = 0; i &lt; size; i += 8 ) { encipher( (unsigned long)&amp;plainData[i], (unsigned long)&amp;encData[dwPos], key ); dwPos += 8; } return dwPos; } / *&#9;TEA_DecryptData / unsigned long TEA_DecryptData( char encData, char plainData, unsigned long size, unsigned long key ) { unsigned long dwPos = 0; for( unsigned long i = 0; i &lt; size; i += 8 ) { decipher( (unsigned long*)&amp;encData[i], (unsigned long*)&amp;plainData[dwPos], key ); dwPos += 8; } return dwPos; }</description></item><item><title>base64 인코딩 / 디코딩</title><link>https://modu-print.com/posts/3875/</link><pubDate>Wed, 09 Jun 2021 13:26:00 +0900</pubDate><guid>https://modu-print.com/posts/3875/</guid><description>C++ /—— Base64 Encoding Table ——/ static const char MimeBase64[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; /—— Base64 Decoding Table ——/ static int DecodeMimeBase64[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / 00-0F / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / 10-1F / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, / 20-2F / 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, / 30-3F / -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, / 40-4F / 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, / 50-5F / -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, / 60-6F / 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, / 70-7F / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / 80-8F / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / 90-9F / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / A0-AF / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / B0-BF / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / C0-CF / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / D0-DF / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / E0-EF / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 / F0-FF / }; int base64_decode( char text, unsigned char dst, int numBytes ) { const char cp; int space_idx = 0, phase; int d, prev_d = 0; unsigned char c; space_idx = 0; phase = 0; for( cp = text; cp != '\0'; ++cp ) { d = DecodeMimeBase64[(int)cp]; if( d != -1 ) { switch( phase ) { case 0: ++phase; break; case 1: c = ((prev_d &lt;&lt; 2) | ((d &amp; 0x30) &gt;&gt; 4)); if( space_idx &lt; numBytes ) dst[space_idx++] = c; ++phase; break; case 2: c = (((prev_d &amp; 0xf) &lt;&lt; 4) | ((d &amp; 0x3c) &gt;&gt; 2)); if( space_idx &lt; numBytes ) dst[space_idx++] = c; ++phase; break; case 3: c = (((prev_d &amp; 0x03) &lt;&lt; 6) | d); if( space_idx &lt; numBytes ) dst[space_idx++] = c; phase = 0; break; } prev_d = d; } } return space_idx; } int base64_encode( char text, int numBytes, char **encodedText ) { unsigned char input[3] = { 0, 0, 0 }; unsigned char output[4] = { 0, 0, 0, 0 }; int index, i, j, size; char p, plen; plen = text + numBytes - 1; size = (4 (numBytes / 3)) + (numBytes % 3 ? 4 : 0) + 1; (encodedText) = (char)malloc( size ); j = 0; for( i = 0, p = text; p &lt;= plen; i++, p++ ) { index = i % 3; input[index] = p; if( index == 2 || p == plen ) { output[0] = ((input[0] &amp; 0xFC) &gt;&gt; 2); output[1] = ((input[0] &amp; 0x3) &lt;&lt; 4) | ((input[1] &amp; 0xF0) &gt;&gt; 4); output[2] = ((input[1] &amp; 0xF) &lt;&lt; 2) | ((input[2] &amp; 0xC0) &gt;&gt; 6); output[3] = (input[2] &amp; 0x3F); (encodedText)[j++] = MimeBase64[output[0]]; (encodedText)[j++] = MimeBase64[output[1]]; (encodedText)[j++] = index == 0 ? '=' : MimeBase64[output[2]]; (encodedText)[j++] = index &lt; 2 ? '=' : MimeBase64[output[3]]; input[0] = input[1] = input[2] = 0; } } (encodedText)[j] = '\0'; return size; }</description></item><item><title>Tucker Go언어 프로그래밍 - 책리뷰</title><link>https://modu-print.com/posts/2852/</link><pubDate>Sat, 15 May 2021 22:00:00 +0900</pubDate><guid>https://modu-print.com/posts/2852/</guid><description>터커(Tucker)님의 Go언어 프로그래밍 책에 대한 리뷰입니다. 저자이신 터커님에게 허락을 받고 만든 영상입니다.</description></item><item><title>Go언어로 윈도 서비스 어플리케이션 만들기</title><link>https://modu-print.com/posts/3881/</link><pubDate>Fri, 23 Apr 2021 13:32:00 +0900</pubDate><guid>https://modu-print.com/posts/3881/</guid><description>최근에는 MS의 Visual Studio도 기본적으로 무료로 사용가능하지만.. 무료버전으로는 서비스 어플리케이션은 개발할 수가 없습니다. ( 물론 Professional 버전 등에서 관련 리소스들을 복사해와서 꼼수로 개발환경을 구성가능하기도 하지만 ㅎㅎ )&#10;여튼 ..&#10;Go로도 윈도 서비스 어플리케이션 개발이 가능합니다.&#10;example command - golang.org/x/sys/windows/svc/example - Go Packages Example service program that beeps. 참고하시면 되겠습니다 ㅎ</description></item><item><title>[MFC] 문자열 분리 - Split String</title><link>https://modu-print.com/posts/3877/</link><pubDate>Sat, 10 Apr 2021 13:28:00 +0900</pubDate><guid>https://modu-print.com/posts/3877/</guid><description>C++ / * SplitString / void SplitString(TCHAR strData, TCHAR Seperator, CStringArray&amp; arr) { CString data = strData; int Position = 0; CString Token; Token = data.Tokenize(Seperator, Position); if (Token != L"") arr.Add(Token); while (!Token.IsEmpty()) { // Get next token. Token = data.Tokenize(Seperator, Position); if (Token != L"") { arr.Add(Token); } } data.Empty(); Token.Empty(); }</description></item><item><title>ANSI(CP949) 한글 조사 처리</title><link>https://modu-print.com/posts/3872/</link><pubDate>Sat, 10 Apr 2021 13:24:00 +0900</pubDate><guid>https://modu-print.com/posts/3872/</guid><description>C++ // kstbl.h #ifndef KSTBL_H #define KSTBL_H /* KS 완성형 2350자의 조합형 코드 */ unsigned KStbl[2350]={&#9;0x8861,0x8862,0x8865,0x8868,0x8869,0x886a,0x886b,0x8871, 0x8873,0x8874,0x8875,0x8876,0x8877,0x8878,0x8879,0x887b, 0x887c,0x887d,0x8881,0x8882,0x8885,0x8889,0x8891,0x8893, 0x8895,0x8896,0x8897,0x88a1,0x88a2,0x88a5,0x88a9,0x88b5, 0x88b7,0x88c1,0x88c5,0x88c9,0x88e1,0x88e2,0x88e5,0x88e8, 0x88e9,0x88eb,0x88f1,0x88f3,0x88f5,0x88f6,0x88f7,0x88f8, 0x88fb,0x88fc,0x88fd,0x8941,0x8945,0x8949,0x8951,0x8953, 0x8955,0x8956,0x8957,0x8961,0x8962,0x8963,0x8965,0x8968, 0x8969,0x8971,0x8973,0x8975,0x8976,0x8977,0x897b,0x8981, 0x8985,0x8989,0x8993,0x8995,0x89a1,0x89a2,0x89a5,0x89a8, 0x89a9,0x89ab,0x89ad,0x89b0,0x89b1,0x89b3,0x89b5,0x89b7, 0x89b8,0x89c1,0x89c2,0x89c5,0x89c9,0x89cb, 0x89d1,0x89d3,0x89d5,0x89d7,0x89e1,0x89e5,0x89e9,0x89f1, 0x89f6,0x89f7,0x8a41,0x8a42,0x8a45,0x8a49,0x8a51,0x8a53, 0x8a55,0x8a57,0x8a61,0x8a65,0x8a69,0x8a73,0x8a75,0x8a81, 0x8a82,0x8a85,0x8a88,0x8a89,0x8a8a,0x8a8b,0x8a90,0x8a91, 0x8a93,0x8a95,0x8a97,0x8a98,0x8aa1,0x8aa2,0x8aa5,0x8aa9, 0x8ab6,0x8ab7,0x8ac1,0x8ad5,0x8ae1,0x8ae2,0x8ae5,0x8ae9, 0x8af1,0x8af3,0x8af5,0x8b41,0x8b45,0x8b49,0x8b61,0x8b62, 0x8b65,0x8b68,0x8b69,0x8b6a,0x8b71,0x8b73,0x8b75,0x8b77, 0x8b81,0x8ba1,0x8ba2,0x8ba5,0x8ba8,0x8ba9,0x8bab,0x8bb1, 0x8bb3,0x8bb5,0x8bb7,0x8bb8,0x8bbc,0x8c61,0x8c62,0x8c63, 0x8c65,0x8c69,0x8c6b,0x8c71,0x8c73,0x8c75,0x8c76,0x8c77, 0x8c7b,0x8c81,0x8c82,0x8c85,0x8c89,0x8c91, 0x8c93,0x8c95,0x8c96,0x8c97,0x8ca1,0x8ca2,0x8ca9,0x8ce1, 0x8ce2,0x8ce3,0x8ce5,0x8ce9,0x8cf1,0x8cf3,0x8cf5,0x8cf6, 0x8cf7,0x8d41,0x8d42,0x8d45,0x8d51,0x8d55,0x8d57,0x8d61, 0x8d65,0x8d69,0x8d75,0x8d76,0x8d7b,0x8d81,0x8da1,0x8da2, 0x8da5,0x8da7,0x8da9,0x8db1,0x8db3,0x8db5,0x8db7,0x8db8, 0x8db9,0x8dc1,0x8dc2,0x8dc9,0x8dd6,0x8dd7,0x8de1,0x8de2, 0x8df7,0x8e41,0x8e45,0x8e49,0x8e51,0x8e53,0x8e57,0x8e61, 0x8e81,0x8e82,0x8e85,0x8e89,0x8e90,0x8e91,0x8e93,0x8e95, 0x8e97,0x8e98,0x8ea1,0x8ea9,0x8eb6,0x8eb7,0x8ec1,0x8ec2, 0x8ec5,0x8ec9,0x8ed1,0x8ed3,0x8ed6,0x8ee1,0x8ee5,0x8ee9, 0x8ef1,0x8ef3,0x8f41,0x8f61,0x8f62,0x8f65,0x8f67,0x8f69, 0x8f6b,0x8f70,0x8f71,0x8f73,0x8f75,0x8f77, 0x8f7b,0x8fa1,0x8fa2,0x8fa5,0x8fa9,0x8fb1,0x8fb3,0x8fb5, 0x8fb7,0x9061,0x9062,0x9063,0x9065,0x9068,0x9069,0x906a, 0x906b,0x9071,0x9073,0x9075,0x9076,0x9077,0x9078,0x9079, 0x907b,0x907d,0x9081,0x9082,0x9085,0x9089,0x9091,0x9093, 0x9095,0x9096,0x9097,0x90a1,0x90a2,0x90a5,0x90a9,0x90b1, 0x90b7,0x90e1,0x90e2,0x90e4,0x90e5,0x90e9,0x90eb,0x90ec, 0x90f1,0x90f3,0x90f5,0x90f6,0x90f7,0x90fd,0x9141,0x9142, 0x9145,0x9149,0x9151,0x9153,0x9155,0x9156,0x9157,0x9161, 0x9162,0x9165,0x9169,0x9171,0x9173,0x9176,0x9177,0x917a, 0x9181,0x9185,0x91a1,0x91a2,0x91a5,0x91a9,0x91ab,0x91b1, 0x91b3,0x91b5,0x91b7,0x91bc,0x91bd,0x91c1,0x91c5,0x91c9, 0x91d6,0x9241,0x9245,0x9249,0x9251,0x9253, 0x9255,0x9261,0x9262,0x9265,0x9269,0x9273,0x9275,0x9277, 0x9281,0x9282,0x9285,0x9288,0x9289,0x9291,0x9293,0x9295, 0x9297,0x92a1,0x92b6,0x92c1,0x92e1,0x92e5,0x92e9,0x92f1, 0x92f3,0x9341,0x9342,0x9349,0x9351,0x9353,0x9357,0x9361, 0x9362,0x9365,0x9369,0x936a,0x936b,0x9371,0x9373,0x9375, 0x9377,0x9378,0x937c,0x9381,0x9385,0x9389,0x93a1,0x93a2, 0x93a5,0x93a9,0x93af,0x93b1,0x93b3,0x93b5,0x93b7,0x93bc, 0x9461,0x9462,0x9463,0x9465,0x9468,0x9469,0x946a,0x946b, 0x946c,0x9470,0x9471,0x9473,0x9475,0x9476,0x9477,0x9478, 0x9479,0x947d,0x9481,0x9482,0x9485,0x9489,0x9491,0x9493, 0x9495,0x9496,0x9497,0x94a1,0x94e1,0x94e2,0x94e3,0x94e5, 0x94e8,0x94e9,0x94eb,0x94ec,0x94f1,0x94f3, 0x94f5,0x94f7,0x94f9,0x94fc,0x9541,0x9542,0x9545,0x9549, 0x9551,0x9553,0x9555,0x9556,0x9557,0x9561,0x9565,0x9569, 0x9576,0x9577,0x9581,0x9585,0x95a1,0x95a2,0x95a5,0x95a8, 0x95a9,0x95ab,0x95ad,0x95b1,0x95b3,0x95b5,0x95b7,0x95b9, 0x95bb,0x95c1,0x95c5,0x95c9,0x95e1,0x95f6,0x9641,0x9645, 0x9649,0x9651,0x9653,0x9655,0x9661,0x9681,0x9682,0x9685, 0x9689,0x9691,0x9693,0x9695,0x9697,0x96a1,0x96b6,0x96c1, 0x96d7,0x96e1,0x96e5,0x96e9,0x96f3,0x96f5,0x96f7,0x9741, 0x9745,0x9749,0x9751,0x9757,0x9761,0x9762,0x9765,0x9768, 0x9769,0x976b,0x9771,0x9773,0x9775,0x9777,0x9781,0x97a1, 0x97a2,0x97a5,0x97a8,0x97a9,0x97b1,0x97b3,0x97b5,0x97b6, 0x97b7,0x97b8,0x9861,0x9862,0x9865,0x9869, 0x9871,0x9873,0x9875,0x9876,0x9877,0x987d,0x9881,0x9882, 0x9885,0x9889,0x9891,0x9893,0x9895,0x9896,0x9897,0x98e1, 0x98e2,0x98e5,0x98e9,0x98eb,0x98ec,0x98f1,0x98f3,0x98f5, 0x98f6,0x98f7,0x98fd,0x9941,0x9942,0x9945,0x9949,0x9951, 0x9953,0x9955,0x9956,0x9957,0x9961,0x9976,0x99a1,0x99a2, 0x99a5,0x99a9,0x99b7,0x99c1,0x99c9,0x99e1,0x9a41,0x9a45, 0x9a81,0x9a82,0x9a85,0x9a89,0x9a90,0x9a91,0x9a97,0x9ac1, 0x9ae1,0x9ae5,0x9ae9,0x9af1,0x9af3,0x9af7,0x9b61,0x9b62, 0x9b65,0x9b68,0x9b69,0x9b71,0x9b73,0x9b75,0x9b81,0x9b85, 0x9b89,0x9b91,0x9b93,0x9ba1,0x9ba5,0x9ba9,0x9bb1,0x9bb3, 0x9bb5,0x9bb7,0x9c61,0x9c62,0x9c65,0x9c69,0x9c71,0x9c73, 0x9c75,0x9c76,0x9c77,0x9c78,0x9c7c,0x9c7d, 0x9c81,0x9c82,0x9c85,0x9c89,0x9c91,0x9c93,0x9c95,0x9c96, 0x9c97,0x9ca1,0x9ca2,0x9ca5,0x9cb5,0x9cb7,0x9ce1,0x9ce2, 0x9ce5,0x9ce9,0x9cf1,0x9cf3,0x9cf5,0x9cf6,0x9cf7,0x9cfd, 0x9d41,0x9d42,0x9d45,0x9d49,0x9d51,0x9d53,0x9d55,0x9d57, 0x9d61,0x9d62,0x9d65,0x9d69,0x9d71,0x9d73,0x9d75,0x9d76, 0x9d77,0x9d81,0x9d85,0x9d93,0x9d95,0x9da1,0x9da2,0x9da5, 0x9da9,0x9db1,0x9db3,0x9db5,0x9db7,0x9dc1,0x9dc5,0x9dd7, 0x9df6,0x9e41,0x9e45,0x9e49,0x9e51,0x9e53,0x9e55,0x9e57, 0x9e61,0x9e65,0x9e69,0x9e73,0x9e75,0x9e77,0x9e81,0x9e82, 0x9e85,0x9e89,0x9e91,0x9e93,0x9e95,0x9e97,0x9ea1,0x9eb6, 0x9ec1,0x9ee1,0x9ee2,0x9ee5,0x9ee9,0x9ef1,0x9ef5,0x9ef7, 0x9f41,0x9f42,0x9f45,0x9f49,0x9f51,0x9f53, 0x9f55,0x9f57,0x9f61,0x9f62,0x9f65,0x9f69,0x9f71,0x9f73, 0x9f75,0x9f77,0x9f78,0x9f7b,0x9f7c,0x9fa1,0x9fa2,0x9fa5, 0x9fa9,0x9fb1,0x9fb3,0x9fb5,0x9fb7,0xa061,0xa062,0xa065, 0xa067,0xa068,0xa069,0xa06a,0xa06b,0xa071,0xa073,0xa075, 0xa077,0xa078,0xa07b,0xa07d,0xa081,0xa082,0xa085,0xa089, 0xa091,0xa093,0xa095,0xa096,0xa097,0xa098,0xa0a1,0xa0a2, 0xa0a9,0xa0b7,0xa0e1,0xa0e2,0xa0e5,0xa0e9,0xa0eb,0xa0f1, 0xa0f3,0xa0f5,0xa0f7,0xa0f8,0xa0fd,0xa141,0xa142,0xa145, 0xa149,0xa151,0xa153,0xa155,0xa156,0xa157,0xa161,0xa162, 0xa165,0xa169,0xa175,0xa176,0xa177,0xa179,0xa181,0xa1a1, 0xa1a2,0xa1a4,0xa1a5,0xa1a9,0xa1ab,0xa1b1,0xa1b3,0xa1b5, 0xa1b7,0xa1c1,0xa1c5,0xa1d6,0xa1d7,0xa241, 0xa245,0xa249,0xa253,0xa255,0xa257,0xa261,0xa265,0xa269, 0xa273,0xa275,0xa281,0xa282,0xa283,0xa285,0xa288,0xa289, 0xa28a,0xa28b,0xa291,0xa293,0xa295,0xa297,0xa29b,0xa29d, 0xa2a1,0xa2a5,0xa2a9,0xa2b3,0xa2b5,0xa2c1,0xa2e1,0xa2e5, 0xa2e9,0xa341,0xa345,0xa349,0xa351,0xa355,0xa361,0xa365, 0xa369,0xa371,0xa375,0xa3a1,0xa3a2,0xa3a5,0xa3a8,0xa3a9, 0xa3ab,0xa3b1,0xa3b3,0xa3b5,0xa3b6,0xa3b7,0xa3b9,0xa3bb, 0xa461,0xa462,0xa463,0xa464,0xa465,0xa468,0xa469,0xa46a, 0xa46b,0xa46c,0xa471,0xa473,0xa475,0xa477,0xa47b,0xa481, 0xa482,0xa485,0xa489,0xa491,0xa493,0xa495,0xa496,0xa497, 0xa49b,0xa4a1,0xa4a2,0xa4a5,0xa4b3,0xa4e1,0xa4e2,0xa4e5, 0xa4e8,0xa4e9,0xa4eb,0xa4f1,0xa4f3,0xa4f5, 0xa4f7,0xa4f8,0xa541,0xa542,0xa545,0xa548,0xa549,0xa551, 0xa553,0xa555,0xa556,0xa557,0xa561,0xa562,0xa565,0xa569, 0xa573,0xa575,0xa576,0xa577,0xa57b,0xa581,0xa585,0xa5a1, 0xa5a2,0xa5a3,0xa5a5,0xa5a9,0xa5b1,0xa5b3,0xa5b5,0xa5b7, 0xa5c1,0xa5c5,0xa5d6,0xa5e1,0xa5f6,0xa641,0xa642,0xa645, 0xa649,0xa651,0xa653,0xa661,0xa665,0xa681,0xa682,0xa685, 0xa688,0xa689,0xa68a,0xa68b,0xa691,0xa693,0xa695,0xa697, 0xa69b,0xa69c,0xa6a1,0xa6a9,0xa6b6,0xa6c1,0xa6e1,0xa6e2, 0xa6e5,0xa6e9,0xa6f7,0xa741,0xa745,0xa749,0xa751,0xa755, 0xa757,0xa761,0xa762,0xa765,0xa769,0xa771,0xa773,0xa775, 0xa7a1,0xa7a2,0xa7a5,0xa7a9,0xa7ab,0xa7b1,0xa7b3,0xa7b5, 0xa7b7,0xa7b8,0xa7b9,0xa861,0xa862,0xa865, 0xa869,0xa86b,0xa871,0xa873,0xa875,0xa876,0xa877,0xa87d, 0xa881,0xa882,0xa885,0xa889,0xa891,0xa893,0xa895,0xa896, 0xa897,0xa8a1,0xa8a2,0xa8b1,0xa8e1,0xa8e2,0xa8e5,0xa8e8, 0xa8e9,0xa8f1,0xa8f5,0xa8f6,0xa8f7,0xa941,0xa957,0xa961, 0xa962,0xa971,0xa973,0xa975,0xa976,0xa977,0xa9a1,0xa9a2, 0xa9a5,0xa9a9,0xa9b1,0xa9b3,0xa9b7,0xaa41,0xaa61,0xaa77, 0xaa81,0xaa82,0xaa85,0xaa89,0xaa91,0xaa95,0xaa97,0xab41, 0xab57,0xab61,0xab65,0xab69,0xab71,0xab73,0xaba1,0xaba2, 0xaba5,0xaba9,0xabb1,0xabb3,0xabb5,0xabb7,0xac61,0xac62, 0xac64,0xac65,0xac68,0xac69,0xac6a,0xac6b,0xac71,0xac73, 0xac75,0xac76,0xac77,0xac7b,0xac81,0xac82,0xac85,0xac89, 0xac91,0xac93,0xac95,0xac96,0xac97,0xaca1, 0xaca2,0xaca5,0xaca9,0xacb1,0xacb3,0xacb5,0xacb7,0xacc1, 0xacc5,0xacc9,0xacd1,0xacd7,0xace1,0xace2,0xace3,0xace4, 0xace5,0xace8,0xace9,0xaceb,0xacec,0xacf1,0xacf3,0xacf5, 0xacf6,0xacf7,0xacfc,0xad41,0xad42,0xad45,0xad49,0xad51, 0xad53,0xad55,0xad56,0xad57,0xad61,0xad62,0xad65,0xad69, 0xad71,0xad73,0xad75,0xad76,0xad77,0xad81,0xad85,0xad89, 0xad97,0xada1,0xada2,0xada3,0xada5,0xada9,0xadab,0xadb1, 0xadb3,0xadb5,0xadb7,0xadbb,0xadc1,0xadc2,0xadc5,0xadc9, 0xadd7,0xade1,0xade5,0xade9,0xadf1,0xadf5,0xadf6,0xae41, 0xae45,0xae49,0xae51,0xae53,0xae55,0xae61,0xae62,0xae65, 0xae69,0xae71,0xae73,0xae75,0xae77,0xae81,0xae82,0xae85, 0xae88,0xae89,0xae91,0xae93,0xae95,0xae97, 0xae99,0xae9b,0xae9c,0xaea1,0xaeb6,0xaec1,0xaec2,0xaec5, 0xaec9,0xaed1,0xaed7,0xaee1,0xaee2,0xaee5,0xaee9,0xaef1, 0xaef3,0xaef5,0xaef7,0xaf41,0xaf42,0xaf49,0xaf51,0xaf55, 0xaf57,0xaf61,0xaf62,0xaf65,0xaf69,0xaf6a,0xaf71,0xaf73, 0xaf75,0xaf77,0xafa1,0xafa2,0xafa5,0xafa8,0xafa9,0xafb0, 0xafb1,0xafb3,0xafb5,0xafb7,0xafbc,0xb061,0xb062,0xb064, 0xb065,0xb069,0xb071,0xb073,0xb076,0xb077,0xb07d,0xb081, 0xb082,0xb085,0xb089,0xb091,0xb093,0xb096,0xb097,0xb0b7, 0xb0e1,0xb0e2,0xb0e5,0xb0e9,0xb0eb,0xb0f1,0xb0f3,0xb0f6, 0xb0f7,0xb141,0xb145,0xb149,0xb157,0xb1a1,0xb1a2,0xb1a5, 0xb1a8,0xb1a9,0xb1ab,0xb1b1,0xb1b3,0xb1b7,0xb1c1,0xb1c2, 0xb1c5,0xb1d6,0xb1e1,0xb1f6,0xb241,0xb245, 0xb249,0xb251,0xb253,0xb261,0xb281,0xb282,0xb285,0xb289, 0xb291,0xb293,0xb297,0xb2a1,0xb2b6,0xb2c1,0xb2e1,0xb2e5, 0xb357,0xb361,0xb362,0xb365,0xb369,0xb36b,0xb370,0xb371, 0xb373,0xb381,0xb385,0xb389,0xb391,0xb3a1,0xb3a2,0xb3a5, 0xb3a9,0xb3b1,0xb3b3,0xb3b5,0xb3b7,0xb461,0xb462,0xb465, 0xb466,0xb467,0xb469,0xb46a,0xb46b,0xb470,0xb471,0xb473, 0xb475,0xb476,0xb477,0xb47b,0xb47c,0xb481,0xb482,0xb485, 0xb489,0xb491,0xb493,0xb495,0xb496,0xb497,0xb4a1,0xb4a2, 0xb4a5,0xb4a9,0xb4ac,0xb4b1,0xb4b3,0xb4b5,0xb4b7,0xb4bb, 0xb4bd,0xb4c1,0xb4c5,0xb4c9,0xb4d3,0xb4e1,0xb4e2,0xb4e5, 0xb4e6,0xb4e8,0xb4e9,0xb4ea,0xb4eb,0xb4f1,0xb4f3,0xb4f4, 0xb4f5,0xb4f6,0xb4f7,0xb4f8,0xb4fa,0xb4fc, 0xb541,0xb542,0xb545,0xb549,0xb551,0xb553,0xb555,0xb557, 0xb561,0xb562,0xb563,0xb565,0xb569,0xb56b,0xb56c,0xb571, 0xb573,0xb574,0xb575,0xb576,0xb577,0xb57b,0xb57c,0xb57d, 0xb581,0xb585,0xb589,0xb591,0xb593,0xb595,0xb596,0xb5a1, 0xb5a2,0xb5a5,0xb5a9,0xb5aa,0xb5ab,0xb5ad,0xb5b0,0xb5b1, 0xb5b3,0xb5b5,0xb5b7,0xb5b9,0xb5c1,0xb5c2,0xb5c5,0xb5c9, 0xb5d1,0xb5d3,0xb5d5,0xb5d6,0xb5d7,0xb5e1,0xb5e2,0xb5e5, 0xb5f1,0xb5f5,0xb5f7,0xb641,0xb642,0xb645,0xb649,0xb651, 0xb653,0xb655,0xb657,0xb661,0xb662,0xb665,0xb669,0xb671, 0xb673,0xb675,0xb677,0xb681,0xb682,0xb685,0xb689,0xb68a, 0xb68b,0xb691,0xb693,0xb695,0xb697,0xb6a1,0xb6a2,0xb6a5, 0xb6a9,0xb6b1,0xb6b3,0xb6b6,0xb6b7,0xb6c1, 0xb6c2,0xb6c5,0xb6c9,0xb6d1,0xb6d3,0xb6d7,0xb6e1,0xb6e2, 0xb6e5,0xb6e9,0xb6f1,0xb6f3,0xb6f5,0xb6f7,0xb741,0xb742, 0xb745,0xb749,0xb751,0xb753,0xb755,0xb757,0xb759,0xb761, 0xb762,0xb765,0xb769,0xb76f,0xb771,0xb773,0xb775,0xb777, 0xb778,0xb779,0xb77a,0xb77b,0xb77c,0xb77d,0xb781,0xb785, 0xb789,0xb791,0xb795,0xb7a1,0xb7a2,0xb7a5,0xb7a9,0xb7aa, 0xb7ab,0xb7b0,0xb7b1,0xb7b3,0xb7b5,0xb7b6,0xb7b7,0xb7b8, 0xb7bc,0xb861,0xb862,0xb865,0xb867,0xb868,0xb869,0xb86b, 0xb871,0xb873,0xb875,0xb876,0xb877,0xb878,0xb881,0xb882, 0xb885,0xb889,0xb891,0xb893,0xb895,0xb896,0xb897,0xb8a1, 0xb8a2,0xb8a5,0xb8a7,0xb8a9,0xb8b1,0xb8b7,0xb8c1,0xb8c5, 0xb8c9,0xb8e1,0xb8e2,0xb8e5,0xb8e9,0xb8eb, 0xb8f1,0xb8f3,0xb8f5,0xb8f7,0xb8f8,0xb941,0xb942,0xb945, 0xb949,0xb951,0xb953,0xb955,0xb957,0xb961,0xb965,0xb969, 0xb971,0xb973,0xb976,0xb977,0xb981,0xb9a1,0xb9a2,0xb9a5, 0xb9a9,0xb9ab,0xb9b1,0xb9b3,0xb9b5,0xb9b7,0xb9b8,0xb9b9, 0xb9bd,0xb9c1,0xb9c2,0xb9c9,0xb9d3,0xb9d5,0xb9d7,0xb9e1, 0xb9f6,0xb9f7,0xba41,0xba45,0xba49,0xba51,0xba53,0xba55, 0xba57,0xba61,0xba62,0xba65,0xba77,0xba81,0xba82,0xba85, 0xba89,0xba8a,0xba8b,0xba91,0xba93,0xba95,0xba97,0xbaa1, 0xbab6,0xbac1,0xbae1,0xbae2,0xbae5,0xbae9,0xbaf1,0xbaf3, 0xbaf5,0xbb41,0xbb45,0xbb49,0xbb51,0xbb61,0xbb62,0xbb65, 0xbb69,0xbb71,0xbb73,0xbb75,0xbb77,0xbba1,0xbba2,0xbba5, 0xbba8,0xbba9,0xbbab,0xbbb1,0xbbb3,0xbbb5, 0xbbb7,0xbbb8,0xbbbb,0xbbbc,0xbc61,0xbc62,0xbc65,0xbc67, 0xbc69,0xbc6c,0xbc71,0xbc73,0xbc75,0xbc76,0xbc77,0xbc81, 0xbc82,0xbc85,0xbc89,0xbc91,0xbc93,0xbc95,0xbc96,0xbc97, 0xbca1,0xbca5,0xbcb7,0xbce1,0xbce2,0xbce5,0xbce9,0xbcf1, 0xbcf3,0xbcf5,0xbcf6,0xbcf7,0xbd41,0xbd57,0xbd61,0xbd76, 0xbda1,0xbda2,0xbda5,0xbda9,0xbdb1,0xbdb3,0xbdb5,0xbdb7, 0xbdb9,0xbdc1,0xbdc2,0xbdc9,0xbdd6,0xbde1,0xbdf6,0xbe41, 0xbe45,0xbe49,0xbe51,0xbe53,0xbe77,0xbe81,0xbe82,0xbe85, 0xbe89,0xbe91,0xbe93,0xbe97,0xbea1,0xbeb6,0xbeb7,0xbee1, 0xbf41,0xbf61,0xbf71,0xbf75,0xbf77,0xbfa1,0xbfa2,0xbfa5, 0xbfa9,0xbfb1,0xbfb3,0xbfb7,0xbfb8,0xbfbd,0xc061,0xc062, 0xc065,0xc067,0xc069,0xc071,0xc073,0xc075, 0xc076,0xc077,0xc078,0xc081,0xc082,0xc085,0xc089,0xc091, 0xc093,0xc095,0xc096,0xc097,0xc0a1,0xc0a5,0xc0a7,0xc0a9, 0xc0b1,0xc0b7,0xc0e1,0xc0e2,0xc0e5,0xc0e9,0xc0f1,0xc0f3, 0xc0f5,0xc0f6,0xc0f7,0xc141,0xc142,0xc145,0xc149,0xc151, 0xc153,0xc155,0xc157,0xc161,0xc165,0xc176,0xc181,0xc185, 0xc197,0xc1a1,0xc1a2,0xc1a5,0xc1a9,0xc1b1,0xc1b3,0xc1b5, 0xc1b7,0xc1c1,0xc1c5,0xc1c9,0xc1d7,0xc241,0xc245,0xc249, 0xc251,0xc253,0xc255,0xc257,0xc261,0xc271,0xc281,0xc282, 0xc285,0xc289,0xc291,0xc293,0xc295,0xc297,0xc2a1,0xc2b6, 0xc2c1,0xc2c5,0xc2e1,0xc2e5,0xc2e9,0xc2f1,0xc2f3,0xc2f5, 0xc2f7,0xc341,0xc345,0xc349,0xc351,0xc357,0xc361,0xc362, 0xc365,0xc369,0xc371,0xc373,0xc375,0xc377, 0xc3a1,0xc3a2,0xc3a5,0xc3a8,0xc3a9,0xc3aa,0xc3b1,0xc3b3, 0xc3b5,0xc3b7,0xc461,0xc462,0xc465,0xc469,0xc471,0xc473, 0xc475,0xc477,0xc481,0xc482,0xc485,0xc489,0xc491,0xc493, 0xc495,0xc496,0xc497,0xc4a1,0xc4a2,0xc4b7,0xc4e1,0xc4e2, 0xc4e5,0xc4e8,0xc4e9,0xc4f1,0xc4f3,0xc4f5,0xc4f6,0xc4f7, 0xc541,0xc542,0xc545,0xc549,0xc551,0xc553,0xc555,0xc557, 0xc561,0xc565,0xc569,0xc571,0xc573,0xc575,0xc576,0xc577, 0xc581,0xc5a1,0xc5a2,0xc5a5,0xc5a9,0xc5b1,0xc5b3,0xc5b5, 0xc5b7,0xc5c1,0xc5c2,0xc5c5,0xc5c9,0xc5d1,0xc5d7,0xc5e1, 0xc5f7,0xc641,0xc649,0xc661,0xc681,0xc682,0xc685,0xc689, 0xc691,0xc693,0xc695,0xc697,0xc6a1,0xc6a5,0xc6a9,0xc6b7, 0xc6c1,0xc6d7,0xc6e1,0xc6e2,0xc6e5,0xc6e9, 0xc6f1,0xc6f3,0xc6f5,0xc6f7,0xc741,0xc745,0xc749,0xc751, 0xc761,0xc762,0xc765,0xc769,0xc771,0xc773,0xc777,0xc7a1, 0xc7a2,0xc7a5,0xc7a9,0xc7b1,0xc7b3,0xc7b5,0xc7b7,0xc861, 0xc862,0xc865,0xc869,0xc86a,0xc871,0xc873,0xc875,0xc876, 0xc877,0xc881,0xc882,0xc885,0xc889,0xc891,0xc893,0xc895, 0xc896,0xc897,0xc8a1,0xc8b7,0xc8e1,0xc8e2,0xc8e5,0xc8e9, 0xc8eb,0xc8f1,0xc8f3,0xc8f5,0xc8f6,0xc8f7,0xc941,0xc942, 0xc945,0xc949,0xc951,0xc953,0xc955,0xc957,0xc961,0xc965, 0xc976,0xc981,0xc985,0xc9a1,0xc9a2,0xc9a5,0xc9a9,0xc9b1, 0xc9b3,0xc9b5,0xc9b7,0xc9bc,0xc9c1,0xc9c5,0xc9e1,0xca41, 0xca45,0xca55,0xca57,0xca61,0xca81,0xca82,0xca85,0xca89, 0xca91,0xca93,0xca95,0xca97,0xcaa1,0xcab6, 0xcac1,0xcae1,0xcae2,0xcae5,0xcae9,0xcaf1,0xcaf3,0xcaf7, 0xcb41,0xcb45,0xcb49,0xcb51,0xcb57,0xcb61,0xcb62,0xcb65, 0xcb68,0xcb69,0xcb6b,0xcb71,0xcb73,0xcb75,0xcb81,0xcb85, 0xcb89,0xcb91,0xcb93,0xcba1,0xcba2,0xcba5,0xcba9,0xcbb1, 0xcbb3,0xcbb5,0xcbb7,0xcc61,0xcc62,0xcc63,0xcc65,0xcc69, 0xcc6b,0xcc71,0xcc73,0xcc75,0xcc76,0xcc77,0xcc7b,0xcc81, 0xcc82,0xcc85,0xcc89,0xcc91,0xcc93,0xcc95,0xcc96,0xcc97, 0xcca1,0xcca2,0xcce1,0xcce2,0xcce5,0xcce9,0xccf1,0xccf3, 0xccf5,0xccf6,0xccf7,0xcd41,0xcd42,0xcd45,0xcd49,0xcd51, 0xcd53,0xcd55,0xcd57,0xcd61,0xcd65,0xcd69,0xcd71,0xcd73, 0xcd76,0xcd77,0xcd81,0xcd89,0xcd93,0xcd95,0xcda1,0xcda2, 0xcda5,0xcda9,0xcdb1,0xcdb3,0xcdb5,0xcdb7, 0xcdc1,0xcdd7,0xce41,0xce45,0xce61,0xce65,0xce69,0xce73, 0xce75,0xce81,0xce82,0xce85,0xce88,0xce89,0xce8b,0xce91, 0xce93,0xce95,0xce97,0xcea1,0xceb7,0xcee1,0xcee5,0xcee9, 0xcef1,0xcef5,0xcf41,0xcf45,0xcf49,0xcf51,0xcf55,0xcf57, 0xcf61,0xcf65,0xcf69,0xcf71,0xcf73,0xcf75,0xcfa1,0xcfa2, 0xcfa5,0xcfa9,0xcfb1,0xcfb3,0xcfb5,0xcfb7,0xd061,0xd062, 0xd065,0xd069,0xd06e,0xd071,0xd073,0xd075,0xd077,0xd081, 0xd082,0xd085,0xd089,0xd091,0xd093,0xd095,0xd096,0xd097, 0xd0a1,0xd0b7,0xd0e1,0xd0e2,0xd0e5,0xd0e9,0xd0eb,0xd0f1, 0xd0f3,0xd0f5,0xd0f7,0xd141,0xd142,0xd145,0xd149,0xd151, 0xd153,0xd155,0xd157,0xd161,0xd162,0xd165,0xd169,0xd171, 0xd173,0xd175,0xd176,0xd177,0xd181,0xd185, 0xd189,0xd193,0xd1a1,0xd1a2,0xd1a5,0xd1a9,0xd1ae,0xd1b1, 0xd1b3,0xd1b5,0xd1b7,0xd1bb,0xd1c1,0xd1c2,0xd1c5,0xd1c9, 0xd1d5,0xd1d7,0xd1e1,0xd1e2,0xd1e5,0xd1f5,0xd1f7,0xd241, 0xd242,0xd245,0xd249,0xd253,0xd255,0xd257,0xd261,0xd265, 0xd269,0xd273,0xd275,0xd281,0xd282,0xd285,0xd289,0xd28e, 0xd291,0xd295,0xd297,0xd2a1,0xd2a5,0xd2a9,0xd2b1,0xd2b7, 0xd2c1,0xd2c2,0xd2c5,0xd2c9,0xd2d7,0xd2e1,0xd2e2,0xd2e5, 0xd2e9,0xd2f1,0xd2f3,0xd2f5,0xd2f7,0xd341,0xd342,0xd345, 0xd349,0xd351,0xd355,0xd357,0xd361,0xd362,0xd365,0xd367, 0xd368,0xd369,0xd36a,0xd371,0xd373,0xd375,0xd377,0xd37b, 0xd381,0xd385,0xd389,0xd391,0xd393,0xd397,0xd3a1,0xd3a2, 0xd3a5,0xd3a9,0xd3b1,0xd3b3,0xd3b5,0xd3b7 }; #endif</description></item><item><title>파일복사 함수</title><link>https://modu-print.com/posts/3935/</link><pubDate>Fri, 09 Apr 2021 16:25:00 +0900</pubDate><guid>https://modu-print.com/posts/3935/</guid><description>기본적으로 파일을 이동시키거나 삭제하는 함수는 제공되고 있지만 복사의 경우 따로 구현을 해야 합니다. Go / * 파일 복사 함수 / func copyFile(srcFile string, destFile string) error { // 기존 파일이 있으면 삭제 if , err := os.Stat(destFile); os.IsNotExist(err) == false { os.Remove(destFile) } // from, err := os.Open(srcFile) if err != nil { return err } defer from.Close() to, err := os.OpenFile(destFile, os.O_RDWR|os.O_CREATE, 0666) if err != nil { return err } defer to.Close() , err = io.Copy(to, from) if err != nil { return err } return nil }</description></item><item><title>프로그램 실행경로를 실행파일 위치로 고정</title><link>https://modu-print.com/posts/3932/</link><pubDate>Fri, 09 Apr 2021 16:22:00 +0900</pubDate><guid>https://modu-print.com/posts/3932/</guid><description>간혹 프로그램을 어디서 실행했느냐 따라서 .. 상대경로로 지정된 코드들이 파일을 못찾는 경우가 생깁니다. 이럴경우 실행파일의 위치로 실행경로를 조정해주면 됩니다.&#10;Go&#9;if err != nil { return } exPath := filepath.Dir(ex) currDir, cdErr := os.Getwd() if cdErr != nil { return } if currDir != exPath { os.Chdir(exPath) }</description></item><item><title>올바른 이메일 주소, 알파벳, 숫자 체크(Regexp)</title><link>https://modu-print.com/posts/3930/</link><pubDate>Fri, 09 Apr 2021 16:21:00 +0900</pubDate><guid>https://modu-print.com/posts/3930/</guid><description>Goa-zA-Z0-9?(?:\.a-zA-Z0-9?)$") return er.MatchString(email) }&#10;/**&#10;알파뱃 , 숫자 체크 / func isAlphaNumString(str string) bool { match, _ := regexp.MatchString("^[a-zA-Z0-9$]+$", str) return match }" style=“color:#d8dee9ff;display:none” aria-label=“Copy” class=“code-block-pro-copy-button”&gt; package main import ( "fmt" "regexp" ) func main() { testMail := "example@example.com" if isValidEmail(testMail) { fmt.Println("올바른 이메일 주소") } else { fmt.Println("잘못된 이메일 주소") } } // 이메일 검사 func isValidEmail(email string) bool { er := regexp.MustCompile("^[a-zA-Z0-9.!#$%&amp;'+\/=?^_`{|}~-]+@a-zA-Z0-9?(?:\.a-zA-Z0-9?)$") return er.MatchString(email) } / * 알파뱃 , 숫자 체크 **/ func isAlphaNumString(str string) bool { match, _ := regexp.MatchString("^[a-zA-Z0-9$]+$", str) return match }</description></item><item><title>간단한 파일 다운로드(HTTP GET)</title><link>https://modu-print.com/posts/3927/</link><pubDate>Fri, 09 Apr 2021 16:20:00 +0900</pubDate><guid>https://modu-print.com/posts/3927/</guid><description>프로그래밍을 하다보면 HTTP GET방식으로 파일을 다운받아 저장해야할 일이 종종 있습니다. 그런떄 사용가능한 GET 방식의 간단한 파일 다운로드 예제입니다.&#10;Go func downloadFile(filepath string, url string) error { // Create the file out, err := os.Create(filepath) if err != nil { return err } defer out.Close() // Request 객체 생성 req, err := http.NewRequest("GET", url, nil) if err != nil { return err } //필요시 헤더 추가 가능 req.Header.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36") // Client객체에서 Request 실행 client := &amp;http.Client{} rep, err := client.Do(req) if err != nil { return err } defer func() { rep.Body.Close() }() // Write the body to file _, err = io.Copy(out, rep.Body) if err != nil { return err } return nil }</description></item><item><title>윈도 API를 이용한 wav 사운드 파일 재생</title><link>https://modu-print.com/posts/3911/</link><pubDate>Fri, 09 Apr 2021 16:11:00 +0900</pubDate><guid>https://modu-print.com/posts/3911/</guid><description>간단히 소리로 무언가를 알려야 할경우에 유용한 코드입니다. 구글링 중에 얻은 코드인지 깃헙 돌아다니다 발췌한 코드인지 기억이 가물가물해서 출처가 애매하네요 ;; &#10;Go package main import ( "syscall" "unsafe" ) const ( SND_SYNC uint = 0x0000 /* play synchronously (default) / SND_ASYNC uint = 0x0001 / play asynchronously / SND_NODEFAULT uint = 0x0002 / silence (!default) if sound not found / SND_MEMORY uint = 0x0004 / pszSound points to a memory file / SND_LOOP uint = 0x0008 / loop the sound until next sndPlaySound / SND_NOSTOP uint = 0x0010 / don't stop any currently playing sound / SND_NOWAIT uint = 0x00002000 / don't wait if the driver is busy / SND_ALIAS uint = 0x00010000 / name is a registry alias / SND_ALIAS_ID uint = 0x00110000 / alias is a predefined ID / SND_FILENAME uint = 0x00020000 / name is file name / SND_RESOURCE uint = 0x00040004 / name is resource name or atom / SND_PURGE uint = 0x0040 / purge non-static events for task / SND_APPLICATION uint = 0x0080 / look for application specific association / SND_SENTRY uint = 0x00080000 / Generate a SoundSentry event with this sound / SND_RING uint = 0x00100000 / Treat this as a "ring" from a communications app - don't duck me / SND_SYSTEM uint = 0x00200000 / Treat this as a system sound / SND_ALIAS_START uint = 0 / alias base */ ) var ( mmsystem = syscall.MustLoadDLL("winmm.dll") playSound = mmsystem.MustFindProc("PlaySound") sndPlaySoundA = mmsystem.MustFindProc("sndPlaySoundA") sndPlaySoundW = mmsystem.MustFindProc("sndPlaySoundW") ) // PlaySound play sound in Windows func PlaySound(sound string, hmod int, flags uint) { if playSound == nil { return } s16, := syscall.UTF16PtrFromString(sound) playSound.Call(uintptr(unsafe.Pointer(s16)), uintptr(hmod), uintptr(flags)) } // SndPlaySoundA play sound file in Windows func SndPlaySoundA(sound string, flags uint) { if sndPlaySoundA == nil { return } b := append([]byte(sound), 0) sndPlaySoundA.Call(uintptr(unsafe.Pointer(&amp;b[0])), uintptr(flags)) } // SndPlaySoundW play sound file in Windows func SndPlaySoundW(sound string, flags uint) { if SndPlaySoundW == nil { return } s16, := syscall.UTF16PtrFromString(sound) sndPlaySoundW.Call(uintptr(unsafe.Pointer(s16)), uintptr(flags)) }</description></item><item><title>현재 날짜, 시간 구하기</title><link>https://modu-print.com/posts/3909/</link><pubDate>Fri, 09 Apr 2021 16:10:00 +0900</pubDate><guid>https://modu-print.com/posts/3909/</guid><description>Go / * 현재 날짜 및 시간 문자열로 얻기 / func currDateTimeStr() string { t := time.Now() return fmt.Sprintf("%04d%02d%02d_%02d%02d%02d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second()) } / *&#9;currDateTimeSplit / func currDateTimeSplit() (year string, month string, day string, hour string, min string, second string) { t := time.Now() sy := fmt.Sprintf("%04d", t.Year()) smon := fmt.Sprintf("%02d", t.Month()) sd := fmt.Sprintf("%02d", t.Day()) sh := fmt.Sprintf("%02d", t.Hour()) sm := fmt.Sprintf("%02d", t.Minute()) ss := fmt.Sprintf("%02d", t.Second()) return sy, smon, sd, sh, sm, ss }</description></item><item><title>CP949 &lt;-&gt; UTF-8 변환</title><link>https://modu-print.com/posts/3905/</link><pubDate>Fri, 09 Apr 2021 16:07:00 +0900</pubDate><guid>https://modu-print.com/posts/3905/</guid><description>Go언어는 기본적으로 UTF-8을 인코딩으로 사용합니다만. 윈도의 경우 기본적으로 CP949 또는 UTF-16입니다. 한글 윈도를 설치한 경우에는 많은 경우에 CP949가 기본 인코딩인 경우가 대부분이라 exec 패키지 등으로 콘솔 명령어를 실행하고 결과를 받아서 사용하는 등의 경우에 한글문자가 깨지는 문제를 겪을 수 있습니다.&#10;이때 사용할수 있는 인코딩 변환 코드입니다.&#10;Go import ( "golang.org/x/text/encoding/korean" "golang.org/x/text/transform" ) / * ansi string을 utf8로 변환 / func ansiToUni(src []byte) []byte { got, , := transform.String(korean.EUCKR.NewDecoder(), string(src)) return []byte(got) } func ansiToUniString(src string) string { got, , := transform.String(korean.EUCKR.NewDecoder(), src) return got } / *&#9;uniToAnsi / func uniToAnsi(src []byte) []byte { got, , := transform.String(korean.EUCKR.NewEncoder(), string(src)) return []byte(got) }</description></item><item><title>파일, 폴더 존재여부 체크</title><link>https://modu-print.com/posts/3902/</link><pubDate>Fri, 09 Apr 2021 16:05:00 +0900</pubDate><guid>https://modu-print.com/posts/3902/</guid><description>Go / *&#9;isExistFile / func isExistFile(fname string) bool { if _, err := os.Stat(fname); os.IsNotExist(err) { return false } return true } / *&#9;isExistFileWithSize / func isExistFileWithSize(fname string) bool { fi, err := os.Stat(fname) if os.IsNotExist(err) { return false } if fi.Size() &gt; 0 { return true } return false }</description></item><item><title>MS윈도 파일또는 폴더를 휴지통으로 버리기</title><link>https://modu-print.com/posts/3898/</link><pubDate>Fri, 09 Apr 2021 16:01:00 +0900</pubDate><guid>https://modu-print.com/posts/3898/</guid><description>윈도에서 프로그래밍을 하다보면 파일을 바로 삭제하는게 아닌 휴지통으로 이동시켜야 하는 경우가 생깁니다. os.Remove 같은 메소드를 이용하여 파일자체를 영구 삭제하는거야 매우 편하지만 ..&#10;사용자를 대상으로 배포할 프로그램을 만드는 경우에는 가능하면 사용자의 실수도 감안하여 바로 삭제하는게 아닌 휴지통으로 이동을 시켜야 할 경우가 생깁니다.&#10;이는 Go언어가 아닌 MFC나 Win32 API를 가지고 개발을 하더라도 결국 MS에서 제공하는 시스템 함수를 가지고서 다뤄야 하는 문제라 ..</description></item><item><title>TCP/IP 안쓰는 포트 얻기 - freeport</title><link>https://modu-print.com/posts/3895/</link><pubDate>Fri, 09 Apr 2021 16:00:00 +0900</pubDate><guid>https://modu-print.com/posts/3895/</guid><description>서버 프로그램을 만들다 보면 가변포트를 사용해야 할 경우가 있습니다. 이런경우 시스템에 사용하고 있지 않은 포트를 얻어야 할때가 있는데요, 그런경우 사용가능한 패키지 입니다.&#10;GitHub - phayes/freeport: Get a free and open tcp port that is ready to use Get a free and open tcp port that is ready to use. Contribute to phayes/freeport development by creating an account on GitHub. Bash go get github.com/phayes/freeport Go package main import "github.com/phayes/freeport" func main() { port, err := freeport.GetFreePort() if err != nil { log.Fatal(err) } // port is ready to listen on }</description></item><item><title>JSON to GO</title><link>https://modu-print.com/posts/3889/</link><pubDate>Fri, 09 Apr 2021 13:38:00 +0900</pubDate><guid>https://modu-print.com/posts/3889/</guid><description>Go로 JSON 데이터를 다루다 보면 .. map 을 이용해 Unmarshal 등을 해도 상관은 없지만. 이래저래 불편합니다. 그래서 보통은 구조체를 생성해서 처리를 합니다. 이때 JSON 구조가 단순하다면야 직접 struct 를 잡아서 작성하면 되지만 복잡한 구조의 JSON 데이터의 경우 구조체 만드는것도 여간 귀찮은 일이 아니지요..&#10;그럴때 사용하기 좋은 사이트가 있습니다.&#10;JSON-to-Go: Convert JSON to Go instantly This tool instantly converts JSON into a Go type definition. Paste a JSON structure on the left and the equivalent Go type will be generated to the right, which you can paste into your program. The script has to make some assumptions, so double-check the output! JSON { "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } } 위 JSON 데이터는 json.org 의 JSON Example 중 하나입니다. 이런 JSON 데이터를 입력하면.</description></item><item><title>XML to GO</title><link>https://modu-print.com/posts/3886/</link><pubDate>Fri, 09 Apr 2021 13:36:00 +0900</pubDate><guid>https://modu-print.com/posts/3886/</guid><description>JSON에 비해 XML의 경우 좀더 파싱이 복잡한 편이긴 합니다만. Go에서는 XML의 Marshal, Unmarshal도 지원을 하고 있습니다. 앞서 작성한 JSON to GO와 마찬가지로 XML의 경우도 구조체를 통해 처리하는 것이 여러모로 관리가 편합니다.&#10;xmltogo 이 사이트를 이용하시면 매우 편리하구요 ㅎㅎ&#10;XML &lt;breakfast_menu&gt; &lt;food&gt; &lt;name&gt;Belgian Waffles&lt;/name&gt; &lt;price&gt;$5.95&lt;/price&gt; &lt;description&gt;Two of our famous Belgian Waffles with plenty of real maple syrup&lt;/description&gt; &lt;calories&gt;650&lt;/calories&gt; &lt;/food&gt; &lt;food&gt; &lt;name&gt;Strawberry Belgian Waffles&lt;/name&gt; &lt;price&gt;$7.95&lt;/price&gt; &lt;description&gt;Light Belgian waffles covered with strawberries and whipped cream&lt;/description&gt; &lt;calories&gt;900&lt;/calories&gt; &lt;/food&gt; &lt;food&gt; &lt;name&gt;Berry-Berry Belgian Waffles&lt;/name&gt; &lt;price&gt;$8.95&lt;/price&gt; &lt;description&gt;Light Belgian waffles covered with an assortment of fresh berries and whipped cream&lt;/description&gt; &lt;calories&gt;900&lt;/calories&gt; &lt;/food&gt; &lt;food&gt; &lt;name&gt;French Toast&lt;/name&gt; &lt;price&gt;$4.50&lt;/price&gt; &lt;description&gt;Thick slices made from our homemade sourdough bread&lt;/description&gt; &lt;calories&gt;600&lt;/calories&gt; &lt;/food&gt; &lt;food&gt; &lt;name&gt;Homestyle Breakfast&lt;/name&gt; &lt;price&gt;$6.95&lt;/price&gt; &lt;description&gt;Two eggs, bacon or sausage, toast, and our ever-popular hash browns&lt;/description&gt; &lt;calories&gt;950&lt;/calories&gt; &lt;/food&gt; &lt;/breakfast_menu&gt; 이런 XML 을 입력하면. ( 출처 : www.w3schools.com/xml/simple.xml ) </description></item><item><title>파일 읽기, 파일을 한줄씩 읽기</title><link>https://modu-print.com/posts/3883/</link><pubDate>Fri, 09 Apr 2021 13:33:00 +0900</pubDate><guid>https://modu-print.com/posts/3883/</guid><description>Go if err != nil { log.Fatal(err) } fmt.Println( string(rbuf) )</description></item><item><title>윈도 API를 이용한 중복실행방지 ( feat. mutex )</title><link>https://modu-print.com/posts/3924/</link><pubDate>Thu, 08 Apr 2021 16:19:00 +0900</pubDate><guid>https://modu-print.com/posts/3924/</guid><description>윈도용 프로그램을 Go로 개발하다보면 중복실행을 원치 않을 경우가 있습니다. 이런때 윈도 API 의 뮤텍스 관련 함수를 이용하면 같은 프로그램의 중복실행을 방지할 수 있습니다.&#10;Bash go get github.com/rodolfoag/gow32 위 패키지 설치가 필요합니다.</description></item><item><title>외부 명령 실행하기( feat exec.Command )</title><link>https://modu-print.com/posts/3921/</link><pubDate>Thu, 08 Apr 2021 16:17:00 +0900</pubDate><guid>https://modu-print.com/posts/3921/</guid><description>프로그래밍 하다보면 .. command line 명령으로 외부 파일을 실행해야할때가 있습니다. 그런때 exe.Command 를 사용하는데요 약간의 추가적인 부분 몇가지를 적어봅니다.&#10;Go / *&#9;execCommandStart / func execCommandStart(name string, arg …string) error { cmd := exec.Command(name, arg…) err := cmd.Start() return err } / *&#9;execCommandRun / func execCommandRun(name string, arg …string) error { cmd := exec.Command(name, arg…) err := cmd.Run() return err } / *&#9;execCommandOutput **/ func execCommandOutput(name string, arg …string) (string, error) { cmd := exec.Command(name, arg…) output, err := cmd.CombinedOutput() return string(output), err }</description></item><item><title>주사위 함수 (Dice, Random)</title><link>https://modu-print.com/posts/3918/</link><pubDate>Thu, 08 Apr 2021 16:15:00 +0900</pubDate><guid>https://modu-print.com/posts/3918/</guid><description>구 CircleMud 현 tbaMud의 C로 작성된 dice 함수를 Go언어 코드로 작성한 함수입니다. tbaMud 라이선스는 아래 링크를 참고 바랍니다.&#10;LICENSE.md 과거에는 GPL 비슷한 라이선스로 봤었는데.. 일부 소스를 타 언어로 포팅한다던지 하는 경우에 오픈소스여야 한다던가 하는 조항이 어디갔는지를 모르겠네요 ;; &#10;여튼 참고만 하시고 상용 프로젝트나 라이선스에 민감한 케이스에는 사용을 자제하시기 바랍니다.</description></item><item><title>윈도 서비스 컨트롤</title><link>https://modu-print.com/posts/3914/</link><pubDate>Thu, 08 Apr 2021 16:13:00 +0900</pubDate><guid>https://modu-print.com/posts/3914/</guid><description>윈도의 실행중인 여러 서비스를 중지시키거나 실행시키거나 하는 .. 서비스를 컨트롤 하는 함수입니다.&#10;모두의 프린터를 만들면서 사용한 코드입니다.&#10;Bash go get golang.org/x/sys/windows/svc go get golang.org/x/sys/windows/svc/mgr 이 두놈이 필요하구요 go get .. 고고</description></item><item><title>실행파일명으로 윈도 프로세스 찾기</title><link>https://modu-print.com/posts/3372/</link><pubDate>Thu, 08 Apr 2021 00:00:00 +0900</pubDate><guid>https://modu-print.com/posts/3372/</guid><description>구글링중 찾은 코드를 조금 손봤습니다. 프로세스명(실행파일명)으로 프로세스가 있는지를 체크하는 함수와 프로세스를 죽이는 함수인데.. os.FindProcess 로 Kill 하는게 윈도서도 제대로 될진 모르겠네요 ㅎㅎ&#10;findProcessByName 까진 정상동작 확인했습니다.&#10;Go package main import ( "os" "strings" "syscall" "unsafe" "golang.org/x/sys/windows" ) const TH32CS_SNAPPROCESS = 0x00000002 type WindowsProcess struct { ProcessID int ParentProcessID int Exe string } / *&#9;processes / func processes() ([]WindowsProcess, error) { handle, err := windows.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) if err != nil { return nil, err } defer windows.CloseHandle(handle) var entry windows.ProcessEntry32 entry.Size = uint32(unsafe.Sizeof(entry)) &lt;em&gt;// get the first process&lt;/em&gt; err = windows.Process32First(handle, &amp;entry) if err != nil { return nil, err } results := make([]WindowsProcess, 0, 50) for { results = append(results, newWindowsProcess(&amp;entry)) err = windows.Process32Next(handle, &amp;entry) if err != nil { &lt;em&gt;// windows sends ERROR_NO_MORE_FILES on last process&lt;/em&gt; if err == syscall.ERROR_NO_MORE_FILES { return results, nil } return nil, err } } } / *&#9;findProcessByName / func findProcessByName(name string) WindowsProcess { processes, perr := processes() if perr != nil { return nil } for _, p := range processes { if strings.ToLower(p.Exe) == strings.ToLower(name) { return &amp;p } } return nil } /** newWindowsProcess / func newWindowsProcess(e *windows.ProcessEntry32) WindowsProcess { &lt;em&gt;// Find when the string ends for decoding&lt;/em&gt; end := 0 for { if e.ExeFile[end] == 0 { break } end++ } return WindowsProcess{ ProcessID: int(e.ProcessID), ParentProcessID: int(e.ParentProcessID), Exe: syscall.UTF16ToString(e.ExeFile[:end]), } } / *&#9;killProcess **/ func killProcess(name string) { pn := findProcessByName(name) if pn != nil { p, perr := os.FindProcess(pn.ProcessID) if perr == nil { p.Kill() } } }</description></item><item><title>MS 인증서 생성 프로그램들</title><link>https://modu-print.com/posts/1699/</link><pubDate>Mon, 29 Mar 2021 09:50:00 +0900</pubDate><guid>https://modu-print.com/posts/1699/</guid><description>데이터 백업 차원에서 글 하나 올려둡니다. 프로그램 개발을 하다보면 사설인증서를 만들어야 하는 경우가 있는데요 그에 사용되는 몇가지 프로그램들이 있는데 .. OpenSSL 을 사용하는 방법도 있고 MS에서 제공하는 관련 툴들을 사용하는 방법도 있습니다만. MS의 프로그램들을 이용하는 방법을 설명하는 사이트들도 많이 있습니다만..&#10;관련 프로그램들을 다 제공을 하는게 아닌데다 .. 필요 프로그램들이 MS에서도 하나의 패키지로 제공하는게 아닌 어떤놈은 VS 설치 폴더에서 찾고 어떤놈은 DDK 를 깔아야 하거나 윈도SDK에 포함되어 있거나 하는 등의 일들이 많아서..</description></item><item><title>윈도API, ShellExcute를 이용한 관리자권한으로 명령어 실행</title><link>https://modu-print.com/posts/3391/</link><pubDate>Sun, 14 Mar 2021 09:47:00 +0900</pubDate><guid>https://modu-print.com/posts/3391/</guid><description>Go import ( "golang.org/x/sys/windows" "path/filepath" ) / *&#9;runAsCommand / func runAsCommand(exe string, runArg string, showCmd int32) error { verb := "runas" cwd := filepath.Dir(exe) verbPtr, := syscall.UTF16PtrFromString(verb) exePtr, := syscall.UTF16PtrFromString(exe) cwdPtr, := syscall.UTF16PtrFromString(cwd) argPtr, := syscall.UTF16PtrFromString(runArg) err := windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, showCmd) if err != nil { return err } return nil }</description></item><item><title>Go로 웹크롤러 만들기 #2</title><link>https://modu-print.com/posts/2041/</link><pubDate>Tue, 24 Nov 2020 16:13:00 +0900</pubDate><guid>https://modu-print.com/posts/2041/</guid><description>1편에 이어서 진행해 보겠습니다. 우선 적당한 위치에 폴더하나를 만드시구요.  저는 GOWEB이라고 만들었습니다.&#10;생성한 폴더를 선택후 우클릭 -&gt; Code(으)로 열기하여 VSCode로 프로젝트를 엽니다.&#10;main.go 파일을 하나 생성 하십시요.&#10;package main func main(){ }</description></item><item><title>Go로 웹크롤러 만들기 #1</title><link>https://modu-print.com/posts/2036/</link><pubDate>Tue, 17 Nov 2020 13:20:00 +0900</pubDate><guid>https://modu-print.com/posts/2036/</guid><description>원래 유튭 영상으로만 어떻게 해보려고 몇 번 녹화도 해보고 라이브도 진행해보고 했으나.. 영상보단 글로써 전달하는 게 효율적이란 생각이 들어서 .. 영상 대본 등을 이용해서 먼저 글을 올립니다. 영상은 포스트 작성후 이 글의 내용에 대해 간단히 설명하는 정도로 넘어가도록 하겠습니다.&#10;유튜브 피로곰TV채널의 구독자와 시청시간이 충족돼서 광고도 달수 있게 되고 커뮤니티 기능도 사용 가능해지면서 전부터 생각하던 대리코딩과 관련한 글을 작성했고 한분께서 크롤링과 관련된 문의를 하셨습니다. 솔직히 별로 하고 싶지 않은 류의 프로그램이라 대리코딩 콘텐츠를 할까 말까 고민한 가장 큰 이유 중 하나가 이놈 때문인데 그래도 요청이 왔으니 진행을 해보겠습니다.</description></item><item><title>프로그램 아이콘을 변경하자GO!</title><link>https://modu-print.com/posts/2032/</link><pubDate>Sat, 30 May 2020 23:09:00 +0900</pubDate><guid>https://modu-print.com/posts/2032/</guid><description>사용된 예제 코드는 아래 링크에서 받으십시요.&#10;예제코드 다운로드&#10;1일1GO 10번째 시간에서 작업한 프로젝트 파일은&#10;위 압축파일을 다운로드 받으시면 됩니다.&#10;추가된 파일은 &#10;baseapp.png&#10;baseapp_icon.ico</description></item><item><title>윈도 트레이 메뉴 추가</title><link>https://modu-print.com/posts/1874/</link><pubDate>Sun, 17 May 2020 01:24:00 +0900</pubDate><guid>https://modu-print.com/posts/1874/</guid><description>9번째 시간 윈도 트레이 메뉴(아이콘)을 추가하는&#10;방법에 대한 영상입니다.&#10;사용된 패키지의 github 주소 입니다&#10;GitHub - tadvi/systray: Go package for Windows Systray icon, menu and notifications Go package for Windows Systray icon, menu and notifications - GitHub - tadvi/systray: Go package for Windows Systray icon, menu and notifications go get github.com/tadvi/systray 콘솔에서 위 명령으로 시스템에 추가 가능합니다.</description></item><item><title>웹페이지 생성,호출</title><link>https://modu-print.com/posts/1870/</link><pubDate>Sat, 09 May 2020 04:47:00 +0900</pubDate><guid>https://modu-print.com/posts/1870/</guid><description>아래는 예제로 사용된 코드들 입니다. 같은 파일명으로 파일들 생성 하셔서 복붙 하시면 되겠습니다.&#10;main.go package main import ( "fmt" "github.com/phayes/freeport" ) var ( gWebServerPort int ) func main() { port, portErr := freeport.GetFreePort() if portErr != nil { fmt.Println(portErr.Error()) return } gWebServerPort = port webServ("127.0.0.1", gWebServerPort) }</description></item><item><title>윈도용 실행파일을 관리자 권한으로 실행하도록 만드는법</title><link>https://modu-print.com/posts/1865/</link><pubDate>Mon, 04 May 2020 16:11:00 +0900</pubDate><guid>https://modu-print.com/posts/1865/</guid><description>영상중 설치한 rsrc 패키지의 깃헙 링크는 다음과 같습니다&#10;GitHub - akavel/rsrc: Tool for embedding .ico &amp; manifest resources in Go programs for Windows. Tool for embedding .ico &amp; manifest resources in Go programs for Windows. - GitHub - akavel/rsrc: Tool for embedding .ico &amp; manifest resources in Go programs for Windows. 콘솔에서</description></item><item><title>더 편리한 환경을 위한 추가 구성 MSYS2!</title><link>https://modu-print.com/posts/1862/</link><pubDate>Mon, 27 Apr 2020 00:26:00 +0900</pubDate><guid>https://modu-print.com/posts/1862/</guid><description>Go는 CGO라는 형식으로 C언어 코드를 직접적으로 Go코드와 함께 사용도 가능하고 C/C++를 비롯한 다른 언어로 개발된 라이브러리나 DLL등을 끌어다 쓰는 짓 등도 가능한 언어입니다. 근본적으로 윈도, 리눅스, MacOS 등을 비롯 다양한 OS에서 실행 가능한 프로그램을 개발 가능하고 더군다나!!&#10;윈도에서도 리눅스, MacOS 등 다른 OS용의 프로그램을 명령어 몇 줄만으로 같은 코드로 만들어 낼 수 있는 놈입니다! (캬~) 하지만 기본적으로 통합개발환경(IDE)을 공식적으로 제공하는 것이 아니기 때문에 윈도 프로그램에 사용되는</description></item><item><title>Go 프로그래밍 환경구성</title><link>https://modu-print.com/posts/1807/</link><pubDate>Fri, 24 Apr 2020 23:36:00 +0900</pubDate><guid>https://modu-print.com/posts/1807/</guid><description>오래전부터 프로그래밍에 관심을 가지는 분들에게 강좌 같은 걸 해볼까 하고 고민을 하긴 했습니다만. 유튜브나 블로그등에 좋은 강좌들은 꽤 많은지라 원론적인 부분 빼고 2~3년 전부터 매우 애정하고 모두의 프린터, 모두의 자막, 모두의 플러그 등을 비롯 최근에 만든 많은 프로그램들의 개발 언어인 Go라는 언어를 가지고 특정 프로그램을 만들기 위한것 보다는 함수 하나, 기능 하나들 위주로 "이러이러한 기능을 만들고 싶으면 요래 하면 됩니다!" 그냥 따라 하거나 복붙 하거나 하면 되는 그 과정에서 필요한 지식을 전달하고 가능하면 C/C++, 자바 등의 다른 언어에 대한 이야기도 풀어 갈 수 있는 영상을 작업해보려 합니다.</description></item><item><title>Json , Xml 구조체 만들기</title><link>https://modu-print.com/posts/1702/</link><pubDate>Mon, 16 Mar 2020 03:18:00 +0900</pubDate><guid>https://modu-print.com/posts/1702/</guid><description>Go언어는 기본적으로 다른 Managed 언어들과 유사하게&#10;Json 이나 Xml 같이 포멀한 데이터 포맷에 대한 Parser를&#10;제공하고 있습니다...만!!!&#10;이런 비정형화 된 텍스트 베이스의 데이터를 구조체 없이&#10;interface를 통해 map 데이터 등으로 Unmarshal해서 사용하는건&#10;엄청난 노가다 및 예외처리의 지옥을 경험하게 되겠지요.</description></item><item><title>윈도API OLE/COM 사용시 메모리릭(Memory Leak)</title><link>https://modu-print.com/posts/1705/</link><pubDate>Thu, 13 Feb 2020 14:58:00 +0900</pubDate><guid>https://modu-print.com/posts/1705/</guid><description>윈도 관련 많은 API들이 COM 방식으로 지원을 하는데요..&#10;MS의 관련 문서에 예제 코드부터 다양하게 제공을 하고 있습니다만.&#10;간혹 이유를 알 수 없는 메모리 누수가 발생하여&#10;곤란해하시는 분들이 계십니다.&#10;우선 기본적으로 &#10;IUnknown 개체들은 전부 사용 후</description></item><item><title>Go 개발 환경 설정</title><link>https://modu-print.com/posts/1685/</link><pubDate>Fri, 06 Sep 2019 09:20:00 +0900</pubDate><guid>https://modu-print.com/posts/1685/</guid><description>이런저런 강좌 시작하기 합서 제가 애정해 마지 않는 Go 라는 언어의 개발환경 설정에 대한 글을 작성해 봅니다.&#10;우선 Go 를 설치 하셔야 겠지요 일단 윈도 사용자를 기준으로 설명합니다. The Go Programming Language Go is an open source programming language that makes it simple to build secure, scalable systems. 저 페이지 가시면 첫 화면에 큼지막 하게 Download Go 라고 있습니다. 클릭!! 고고고!</description></item><item><title>모두의 프린터 코드사이닝 이슈</title><link>https://modu-print.com/posts/1600/</link><pubDate>Sat, 20 Oct 2018 08:34:00 +0900</pubDate><guid>https://modu-print.com/posts/1600/</guid><description>모두의 프린터는 개인이 개발하여 배포하고 있고 특별히 인스톨러형태로 배포되고 있진 않는데요. 일반적으로 불특정 다수에게 배포되는 프로그램의 경우 코드사이닝을 통해 프로그램의 배포자를 알리고 이를 신뢰 할 수 있는지를 따질 수 있는 방법을 사용하게 됩니다. 인증 되지 않은 프로그램의 경우 바이러스 백신이나 각종 사이트의 보안프로그램에서 출처를 알수 없다는 등의 이유로 바이러스로 취급하거나 위험성을 경고하는 등의 일이 일어나곤 하는데요, 그나마 친절하게 안대라도 해주면서 사용을 할지 실행을 할지, 허용을 할지를 물어보기라도 해주면 좋은데 최근의 몇몇 보안프로그램들은 일언만구 어떤 안내도 없이 막 삭제하고 막아버리고 죽여버립(ㅠㅠ)니다. 그리하여 모두의 프린터도 코드사이닝을 통한 프로그램의 출처를 포함하여 배포해야할 때가 되지 않았는가 하여 이 글을 작성합니다.</description></item></channel></rss>