소프트웨어 PureBasic으로 BCD 툴 따라해보는 중
2024.03.24 13:00
시작은 그냥 따라서 만들어보고 싶어서였는데... 생각보다 맨땅에 헤딩이 많네요.
한 일주일 가지고 놀다보니 더이상 동기부여도 안되서 완성도 못하고 그만하고 싶은맘만 가득....
결정적으로 고질병인 뭔가 꾸미기(?) 단계에 오면 모든 게 자동으로 고장나버리는....
PureBasic 해보실분은 왕초보님이 올려주신
https://windowsforum.kr/review/20514407 << 이 글을 참고하시면 됩니다.
그냥 방법을 몰라 찾느라 고생했던 소스들만 몇 개 올려볼게요 (지난 번에 올린 것과 중복이 있을 수도...)
Global Window_0
Global Button_0, Button_1
Procedure OpenWindow_0(x = 0, y = 0, width = 260, height = 80)
Window_0 = OpenWindow(0, 100, 100, 300, 200, "Hello PureBasic", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Button_0 = ButtonGadget(#PB_Any, 20, 20, 100, 40, "Click Me")
Button_1 = ButtonGadget(#PB_Any, 140, 20, 100, 40, "Close Window")
EndProcedure
Procedure Window_0_Events()
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit = #True
Case #PB_Event_Gadget
If EventGadget() = Button_0
MessageRequester("Greetings", "Hello, PureBasic!")
ElseIf EventGadget() = Button_1
MessageRequester("Greetings", "Hello, PureBasic!")
EndIf
EndSelect
Until Event = #PB_Event_CloseWindow
EndProcedure
OpenWindow_0()
Window_0_Events()
이건 기본으로 제공되는 예제 소스입니다.
-------- 아래는 배치파일처럼 콘솔 화면의 출력 결과를 PureBasic에서 추출하는 방법 샘플
guid_run = RunProgram("bcdedit", "/create /d aaa /application osloader", "", #PB_Program_Open | #PB_Program_Read)
Output$ = ""
If guid_run
While ProgramRunning(guid_run)
If AvailableProgramOutput(guid_run)
Output$ + ReadProgramString(guid_run, #PB_Ascii) + Chr(13)
EndIf
Wend
Output$ + "Exitcode: " + Str(ProgramExitCode(guid_run))
CloseProgram(guid_run) ; Close the connection to the program
EndIf
guid_os$ = Mid(Output$, 1, 38)
MessageRequester("Output", guid_os$)
MessageRequester("Output", Output$)
--------- 레지키 생성
result = RegCreateKeyEx_(#HKEY_LOCAL_MACHINE, "SOFTWARE\Classes\Directory\background\shell\One_Boot", 0, 0, #REG_SZ, #KEY_WRITE, 0, @handle, @result)
Debug result
---- 레지키 등록 - 그냥 RunProgram 으로 넣어도 되는데 혹시 대량으로 하거나 나중에 수정할 때 이 방법이 편해서
---- 혹시 PureBasic 하시게 된다면 알아두시는게 좋은, 더 간편하고 좋은 방법을 아직 못찾은
Procedure.l WriteRegKey(OpenKey.l, SubKey.s, KeyName.s, KeyValue.s)
Protected handle.l, result.l, dataSize.l
If RegCreateKeyEx_(OpenKey, @SubKey, 0, 0, #REG_SZ, #KEY_WRITE, 0, @handle, @result) = 0
dataSize = Len(KeyValue) + Len(KeyValue) ; Add 1 for the null terminator
If RegSetValueEx_(handle, @KeyName, 0, #REG_SZ, @KeyValue, dataSize) = 0
Debug "Value set successfully"
EndIf
RegCloseKey_(handle)
EndIf
ProcedureReturn result
EndProcedure
Define Key1.l = #HKEY_LOCAL_MACHINE
Define SubKey.s = "SOFTWARE\Classes\Directory\background\shell\GPolicy"
WriteRegKey(Key1, SubKey, "Position", "Top")
WriteRegKey(Key1, SubKey, "Icon", "C:\\Windows\\system32\\gpedit.dll,0")
WriteRegKey(Key1, SubKey + "\Command", "", "mmc gpedit.msc")
--------- 원래는 아래처럼 닫아주고 해야 되는데 에러처리는 모른척 하고 있는 상태라...
EnableExplicit
Define result, OpenKey, handle, hKey
If RegCreateKeyEx_(#HKEY_LOCAL_MACHINE, "SOFTWARE\Classes\Directory\background\shell", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_WRITE, 0, @OpenKey, @result) = 0
Debug "1 :" + @result + " " + @OpenKey
If RegCreateKeyEx_(OpenKey, "oneBoot", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_WRITE, 0, @handle, @result) = 0
Debug "2 :" + @result + " " + @handle
RegCloseKey_(@handle)
EndIf
RegCloseKey_(OpenKey)
EndIf
If RegCreateKeyEx_(#HKEY_LOCAL_MACHINE, "SOFTWARE\Classes\Directory\background\shell\oneBoot", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_WRITE, 0, @hKey, @result) = 0
If RegSetValueEx_(@hKey, "Version", 0, #REG_SZ, "2.------------0", StringByteLength("2.------------0"))
Debug "Value 'Version' set successfully."
Else
Debug "Error setting value 'Version'."
EndIf
RegCloseKey_(@hKey)
Else
Debug "Error creating or opening registry key."
EndIf
DisableExplicit
----- 문자를 입력받는 방법
Input$ = InputRequester("드라이브 문자", "부팅할 드라이브 문자를 입력하세요 (문자만) : ", "D")
MessageRequester("Information", Input$)
Input1.s = InputRequester("드라이브 문자", "부팅할 드라이브 문자를 입력하세요 (문자만) : ", "D")
MessageRequester("Information", Input1.s)
Input2.s{1} = InputRequester("드라이브 문자", "부팅할 드라이브 문자를 입력하세요 (문자만) : ", "D")
MessageRequester("Information", Input2)
----- 현재의 경로를 가져오는 방법
Result$ = GetCurrentDirectory()
Debug Mid(Result$, 3, StringByteLength(Result$))
----- 경로의 일부 문자만 가져오기
PE_Path$ = Mid( GetCurrentDirectory(), 3, StringByteLength(GetCurrentDirectory()) )
Debug PE_Path$
----- 실행 파일 만든 후에 옵션(파라미터) 입력 받는 방법
result0$ = ProgramParameter(0)
MessageRequester("test", result0$)
result1$ = ProgramParameter(1)
MessageRequester("test", result1$)
result2$ = ProgramParameter(2)
MessageRequester("test", result2$)
result3$ = ProgramParameter(3)
MessageRequester("test", result3$)
result4$ = ProgramParameter(4)
MessageRequester("test", result4$)
result5$ = ProgramParameter(-1)
MessageRequester("test", result5$)
-- 지난 번에 올린 몇가지와 위에 것들을 하나로 합치면 참고로 아래 코드는 분석하시기 전엔 컴파일은 하시지 마세요.
-- 컴퓨터 난장판 될수도... 꼬인 상태를 풀어야 하는데 하다가 동기부여 안되서 잠정중단 상태고... 제가 어디까지 했는지 기억이 안나요;
EnableExplicit
Global Window_0
Global Button_0, Button_1
Global Event
Global Quit
Global BCD_Parameter
Procedure SetBCDValue()
OpenConsole()
Define dvid$
Define guid$
Define PE_Name$
Define drv_l.s{1}
Define result1
Define result2
dvid$="{11111112-1111-1111-1111-111111111111}"
guid$="{11111111-1111-1111-1111-111111111111}"
PE_Name$ = NextSelectedFileName()
MessageRequester("PENAME", PE_Name$)
Define PE_Path$ = Mid(GetCurrentDirectory(), 3, StringByteLength( GetCurrentDirectory() ) )
MessageRequester("PEPATH", PE_Path$)
drv_l.s{1} = GetCurrentDirectory()
MessageRequester("drv_letter", drv_l)
While result1 <> 1
result1 = RunProgram("bcdedit", "/delete " + dvid$ + " /f", "", #PB_Program_Wait)
Wend
While result2 <> 1
result2 = RunProgram("bcdedit", "/delete " + guid$ + " /f", "", #PB_Program_Wait)
Wend
RunProgram("bcdedit", "/create " + dvid$ + " /device /d " + #DQUOTE$+PE_Name$+#DQUOTE$, "", #PB_Program_Wait)
RunProgram("bcdedit", "/set " + dvid$ + " ramdisksdidevice partition="+#DQUOTE$+drv_l+#DQUOTE$+":", "", #PB_Program_Wait)
RunProgram("bcdedit", "/set " + dvid$ + " ramdisksdipath "+ #DQUOTE$+ drv_l + ":\" + PE_Path$ + "\boot.sdi" + #DQUOTE$, "", #PB_Program_Wait)
RunProgram("bcdedit", "/create " + guid$ + " /application osloader /d " + #DQUOTE$+PE_Name$+#DQUOTE$, "", #PB_Program_Wait)
RunProgram("bcdedit", "/set " + guid$ + " device " + #DQUOTE$ + "ramdisk=["+ drv_l +":]\" +PE_Path$+ "\boot.wim," + dvid$ + #DQUOTE$, "", #PB_Program_Wait)
RunProgram("bcdedit"," /set " + guid$ + " OSdevice "+ #DQUOTE$ + "ramdisk=["+ drv_l +":]\" +PE_Path$+ "\boot.wim," + dvid$ + #DQUOTE$, "", #PB_Program_Wait)
RunProgram("bcdedit"," /set " + guid$ + " systemroot \windows", "", #PB_Program_Wait)
RunProgram("bcdedit"," /set " + guid$ + " winpe yes", "", #PB_Program_Wait)
RunProgram("bcdedit"," /set " + guid$ + " detecthal yes", "", #PB_Program_Wait)
RunProgram("bcdedit"," /displayorder " + guid$ + " /addlast", "", #PB_Program_Wait)
RunProgram("bcdedit","/bootsequence " + guid$ + " /addlast", "", #PB_Program_Wait)
RunProgram("bcdedit"," /timeout 5", "", #PB_Program_Wait)
CloseConsole()
EndProcedure
Procedure WriteRegKey(RootKey.l, SubKey.s, KeyName.s, KeyValue.s)
Protected handle.l, result.l
If RegCreateKeyEx_(RootKey, @SubKey, 0, 0, #REG_SZ, #KEY_WRITE, 0, @RootKey, @result) = 0
If RegSetValueEx_(RootKey, KeyName, 0, #REG_SZ, KeyValue, StringByteLength(KeyValue)) = 0
Debug "Value set successfully"
RegCloseKey_(RootKey)
EndIf
EndIf
EndProcedure
Procedure Rclk_Registration()
Protected OpenKey, result, handle
If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, "SystemFileAssociations\.wim\shell", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_WRITE, 0, @OpenKey, @result) = 0
If RegCreateKeyEx_(OpenKey, "OneBoot", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_WRITE, 0, @handle, @result) = 0
RegCloseKey_(handle)
EndIf
RegCloseKey_(OpenKey)
EndIf
Define RootKey.l = #HKEY_CLASSES_ROOT
Define SubKey.s = "SystemFileAssociations\.wim\shell\OneBoot"
WriteRegKey(RootKey, SubKey, "Icon", "C:\\Windows\\system32\\imageres.dll,147")
WriteRegKey(RootKey, SubKey, "Position", "Top")
WriteRegKey(RootKey, SubKey + "\Command", "", GetCurrentDirectory() + "OneBoot.exe /b")
EndProcedure
Procedure OpenWindow_0(x = 0, y = 0, width = 300, height = 300)
Window_0 = OpenWindow(0, 100, 100, 300, 200, "Hello PureBasic", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Button_0 = ButtonGadget(#PB_Any, 20, 20, 100, 40, "우클릭 등록")
Button_1 = ButtonGadget(#PB_Any, 140, 20, 100, 40, "1회부팅 생성")
EndProcedure
Procedure Window_0_Events()
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit = #True
Case #PB_Event_Gadget
If EventGadget() = Button_0
Rclk_Registration() ; Call the procedure to register right-click
ElseIf EventGadget() = Button_1
SetBCDValue()
EndIf
EndSelect
Until Quit = #True
EndProcedure
If ProgramParameter(0) = "/b"
SetBCDValue()
Rclk_Registration()
Else
OpenWindow_0()
Window_0_Events()
EndIf
------------------------------------- 이상입니다.
저는 입니다님 전원단추 프로그램에서 먼저 폼과 버튼을 공부하고 버튼에 기본 명령어 대신에 필요한 기능을 넣은 방식으로 진행을
하였습니다
어렵지만 한번한발 전진을 하고 계신것 같습니다..맨 마지막에 완성이 되시면 그 기쁨은 완성을 하신분만 느낄수 있는 기쁨일것입니다
화이팅입니다..