Dislocker/dislocker_client.py

657 lines
31 KiB
Python

import os
import json
import tkinter.messagebox
import customtkinter
from winotify import Notification, audio
import keyboard
import subprocess
import requests
import hashlib
import string
import random
import tkinter
import threading
import sys
import shutil
import uuid
import time
import win32com.client
import pythoncom
from PIL import Image
app_name = "Dislocker"
dislocker_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
os.chdir(dislocker_dir)
sp_startupinfo = subprocess.STARTUPINFO()
sp_startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW
sp_startupinfo.wShowWindow = subprocess.SW_HIDE
resource_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "resource")
config_dir_path = "./config/"
client_config_path = config_dir_path + "client.json"
if not os.path.isfile(client_config_path):
if not os.path.isdir(config_dir_path):
os.mkdir(config_dir_path)
client_config = {
"initial": True,
"auth_host_url": "http://localhost",
"pc_number": 1,
"master_password_hash": "",
"testing": False,
"eraser": True,
"pc_uuid": "",
"pc_token": "",
"hard_lock": False
}
elif os.path.isfile(client_config_path):
with open(client_config_path, "r") as r:
client_config = json.load(r)
def get_input_devices():
str_computer = "."
obj_wmi_service = win32com.client.Dispatch("WbemScripting.SWbemLocator")
obj_swem_services = obj_wmi_service.ConnectServer(str_computer, "root\\cimv2")
col_items = obj_swem_services.ExecQuery("Select * from Win32_PnPEntity where PNPDeviceID like 'HID%'")
input_devices = []
for obj_item in col_items:
input_devices.append({
"device_id": obj_item.DeviceID,
"PNPDeviceID": obj_item.PNPDeviceID,
"Description": obj_item.Description,
"device_name": obj_item.Name,
"Manufacturer": obj_item.Manufacturer,
"Service": obj_item.Service,
"FriendlyName": obj_item.Name, # デバイスとプリンターで表示される名前
"device_instance_path": obj_item.DeviceID # デバイスインスタンスパス
})
return input_devices
def device_register(**kwargs):
onetime = str(kwargs["onetime"])
mode = str(kwargs["mode"])
number = int(kwargs["number"])
device_instance_path = str(kwargs["device_instance_path"])
device_name = str(kwargs["device_name"])
device_register_json = {
"number": number,
"device_instance_path": device_instance_path,
"device_name": device_name,
"mode": mode,
"onetime": onetime
}
register_url = client_config["auth_host_url"] + "/device_register"
responce = requests.post(register_url, json=device_register_json)
if responce.status_code == 200:
print("デバイスの登録に成功しました。")
return {"result": 0, "about": "ok"}
elif responce.status_code == 401:
print("認証に失敗しました。")
return {"result": 1, "about": "auth_failed"}
else:
print("内部エラーによりデバイスの登録に失敗しました。")
return {"result": 1, "about": "error"}
def master_password_gen():
numbers = string.digits # (1)
password = ''.join(random.choice(numbers) for _ in range(10)) # (2)
password_hash = hashlib.sha256(password.encode()).hexdigest()
result = {"password": password, "password_hash": password_hash}
return result
def init(**kwargs):
task_exist = subprocess.run('tasklist /fi "IMAGENAME eq dislocker_client.exe"', startupinfo=sp_startupinfo, stdout=subprocess.PIPE, text=True)
if 'dislocker_client.exe' in task_exist.stdout:
task_count = task_exist.stdout.count("dislocker_client.exe")
if task_count == 1:
pass
else:
return 1
if client_config["initial"] == True:
pc_uuid = uuid.uuid4()
client_config["pc_uuid"] = str(pc_uuid)
if "pc_number" in kwargs:
client_config["pc_number"] = int(kwargs["pc_number"])
else:
tkinter.messagebox.showerror(title=f"{app_name} | 登録時にエラー", message=f"登録時にエラーが発生しました。\nPC番号が指定されていません。1個目の引数にPC番号、2個目の引数にワンタイムパスワードを指定して、もう一度お試しください。")
return 2
if "onetime" in kwargs:
onetime = str(kwargs["onetime"])
else:
tkinter.messagebox.showerror(title=f"{app_name} | 登録時にエラー", message=f"登録時にエラーが発生しました。\nワンタイムパスワードが指定されていません。1個目の引数にPC番号、2個目の引数にワンタイムパスワードを指定して、もう一度お試しください。")
return 2
if "host_url" in kwargs:
client_config["auth_host_url"] = str(kwargs["host_url"])
else:
pass
register_url = client_config["auth_host_url"] + "/register"
register_json = {
"pc_number": int(client_config["pc_number"]),
"pc_uuid": str(pc_uuid),
"onetime": onetime
}
responce = requests.post(register_url, json=register_json)
if responce.status_code == 200:
print("PCの情報が登録されました。")
responce_json = responce.json()
pc_token = str(responce_json["pc_token"])
master_password_hash = str(responce_json["master_password_hash"])
master_password = str(responce_json["master_password"])
client_config["pc_token"] = pc_token
client_config["master_password_hash"] = master_password_hash
msgbox = tkinter.messagebox.showinfo(title=f"{app_name} | 初回起動を検出", message=f"初回起動のようです。\nマスターパスワードを記録しておいてください。\nBotが起動している場合は、管理者がDiscordから確認することもできます。\n\n{master_password}\n\n")
client_config["initial"] = False
with open(client_config_path, "w") as w:
json.dump(client_config, w, indent=4)
return 2
else:
msgbox = tkinter.messagebox.showerror(title=f"{app_name} | 登録時にエラー", message=f"登録時にエラーが発生しました。\nワンタイムパスワードが間違っている可能性があります。")
return 2
else:
return 0
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
if client_config["testing"] == True:
pass
else:
self.block_taskmgr()
self.block_key()
shutup_window = keyboard.press_and_release('windows + d')
self.attributes('-fullscreen', True)
self.attributes('-topmost', True)
if client_config["hard_lock"] == True:
exit_explorer = subprocess.run('taskkill /f /im explorer.exe', startupinfo=sp_startupinfo, stdout=subprocess.PIPE, text=True)
if exit_explorer.returncode == 0:
pass
else:
signout_session = subprocess.run('shutdown /l /f /t 3', startupinfo=sp_startupinfo, stdout=subprocess.PIPE, text=True)
error_msgbox = tkinter.messagebox.showerror(title=f"{app_name} | 初回処理のエラー", message=f"初回処理の実行にエラーが発生しました。\n自動的にサインアウトされます。")
self.title(f"{app_name} | ロック中")
self.iconbitmap(default=resource_path + '\\icon\\dislocker.ico')
self.frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent')
self.frame.grid(row=0, column=0, sticky='nsew')
lock = Lock()
def exit(self):
self.unlock_taskmgr()
if client_config["hard_lock"] == True:
self.wake_explorer()
else:
pass
self.toast()
self.destroy()
def block_key(self):
block_keys = ['ctrl', 'alt', 'windows', 'shift', 'delete']
for i in block_keys:
keyboard.block_key(i)
def block_taskmgr(self):
block = subprocess.run('reg add HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System /v DisableTaskMgr /t REG_DWORD /d 1 /f', startupinfo=sp_startupinfo, stdout=subprocess.PIPE, text=True)
print(block)
def unlock_taskmgr(self):
unlock = subprocess.run('reg delete HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System /v DisableTaskMgr /f', startupinfo=sp_startupinfo, stdout=subprocess.PIPE, text=True)
print(unlock)
def wake_explorer(self):
wake_explorer = subprocess.Popen('explorer', startupinfo=sp_startupinfo, stdout=subprocess.PIPE, text=True)
def toast(self):
success = Notification(
app_id='Dislocker',
title='ご協力ありがとうございます!',
msg='パスワード認証に成功しました。\n現在使われたパスワードは削除されます。',
icon=resource_path + r'\success.png'
)
success.set_audio(audio.Default, loop=False)
success.show()
def handler_close(self):
pass
class Lock(customtkinter.CTkToplevel):
def __init__(self):
super().__init__()
if client_config["testing"] == True:
self.title(f'{app_name} | PC番号 {client_config["pc_number"]} | テストモード')
else:
self.title(f'{app_name} | PC番号 {client_config["pc_number"]} | ロックされています')
self.iconbitmap(default=resource_path + '\\icon\\dislocker.ico')
self.window_width = 760
self.window_height = 320
self.screen_width = self.winfo_screenwidth()
self.screen_height = self.winfo_screenheight()
self.center_x = int(self.screen_width/2 - self.window_width/2)
self.center_y = int(self.screen_height/2 - self.window_height/2)
self.geometry(f"{str(self.window_width)}x{str(self.window_height)}+{str(self.center_x)}+{str(self.center_y)}")
self.resizable(height=False, width=False)
self.attributes('-topmost', True)
self.grab_set()
self.lift()
self.protocol("WM_DELETE_WINDOW", self.handler_close)
self.emoji_font = customtkinter.CTkFont(family="Segoe UI Emoji", size=32)
self.title_font = customtkinter.CTkFont(family="meiryo", size=32, weight="bold")
self.pc_number_font = customtkinter.CTkFont(family="meiryo", size=64, weight="bold")
self.title_small_font = customtkinter.CTkFont(family="meiryo", size=16)
self.general_font = customtkinter.CTkFont(family="meiryo", size=18)
self.general_small_font = customtkinter.CTkFont(family="meiryo", size=12)
self.textbox_font = customtkinter.CTkFont(family="meiryo", size=14)
self.button_font = customtkinter.CTkFont(family="meiryo", size=14)
self.cover_img = customtkinter.CTkImage(light_image=Image.open(resource_path + '\\cover\\dislocker_light.png'), dark_image=Image.open(resource_path + '\\cover\\dislocker_dark.png'), size=(160, 320))
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=6)
self.cover_frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent')
self.cover_frame.grid(row=0, column=0, padx=0, pady=0, sticky="nsew", rowspan=4)
self.cover_img_label = customtkinter.CTkLabel(self.cover_frame, image=self.cover_img, text="")
self.cover_img_label.grid(row=0, column=0, padx=0, pady=0, sticky="w")
self.msg_title_frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent')
self.msg_title_frame.grid(row=0, column=1, padx=10, pady=10, sticky="nsew")
#self.icon_title_1 = customtkinter.CTkLabel(self.msg_title_frame, text='😎', font=self.emoji_font, justify="left")
#self.icon_title_1.grid(row=0, column=0, padx=10, sticky="w")
self.msg_title_1 = customtkinter.CTkLabel(self.msg_title_frame, text=f'ちょっと待って!! ', font=self.title_font, justify="left")
self.msg_title_1.grid(row=0, column=0, padx=10, sticky="we")
self.pc_number_title_1 = customtkinter.CTkLabel(self.msg_title_frame, text=f'PC番号 | {client_config["pc_number"]}', font=self.title_font, justify="right")
self.pc_number_title_1.grid(row=0, column=1, padx=10, sticky="e")
self.msg_title_2 = customtkinter.CTkLabel(self.msg_title_frame, text="本当にあなたですか?", font=self.title_small_font, justify="left")
self.msg_title_2.grid(row=1, column=0, padx=10, columnspan=2, sticky="w")
self.msg_subtitle_frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent')
self.msg_subtitle_frame.grid(row=1, column=1, padx=10, pady=0, sticky="nsew")
self.msg_subtitle_frame.grid_columnconfigure(0, weight=1)
self.msg_subtitle_1 = customtkinter.CTkLabel(self.msg_subtitle_frame, text='サインインするには、Discordを開き、Dislockerから送信された\nパスワードを入力してください。', font=self.general_font, justify="left")
self.msg_subtitle_1.grid(row=0, column=0, padx=10, sticky="w")
self.msg_subtitle_2 = customtkinter.CTkLabel(self.msg_subtitle_frame, text='※ パスワードの有効期限は発行から5分間です。期限が切れた場合は、もう一度発行してください。', font=self.general_small_font, justify="left")
self.msg_subtitle_2.grid(row=1, column=0, padx=10, sticky="w")
self.input_frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent')
self.input_frame.grid(row=2, column=1, padx=10, pady=0, sticky="nsew")
self.input_frame.columnconfigure(0, weight=1)
self.password_entry = customtkinter.CTkEntry(self.input_frame, placeholder_text='パスワード', show='*', font=self.textbox_font)
self.password_entry.grid(row=0, column=0, padx=10, sticky="ew")
self.password_entry.bind("<Return>", self.auth_start_ev)
self.button_frame = customtkinter.CTkFrame(self, corner_radius=0, fg_color='transparent')
self.button_frame.grid(row=3, column=1, padx=10, pady=10, sticky="nsew")
self.button_frame.columnconfigure(0, weight=3)
self.button_frame.columnconfigure(1, weight=1)
self.button_frame.columnconfigure(2, weight=1)
self.signin_button = customtkinter.CTkButton(self.button_frame, text='サインイン', command=self.auth_start, font=self.button_font)
self.signin_button.grid(row=0, column=2, padx=10, sticky="e")
self.signout_button = customtkinter.CTkButton(self.button_frame, text='サインアウト', command=self.signout, font=self.button_font)
self.signout_button.grid(row=0, column=1, padx=10, sticky="e")
self.help_button = customtkinter.CTkButton(self.button_frame, text='ヘルプ', command=self.help_dummy, font=self.button_font)
self.help_button.grid(row=0, column=0, padx=10, sticky="w")
self.keyboard_listener_thread = threading.Thread(target=self.keyboard_listener)
self.keyboard_listener_thread.daemon = True
self.keyboard_listener_thread.start()
def help_wakeup(self):
help = Help()
def keyboard_listener(self):
keyboard.add_hotkey('ctrl+shift+q', self.exit)
def hash_genarate(self, source):
hashed = hashlib.sha256(source.encode())
return hashed.hexdigest()
def auth_start(self):
auth_thread = threading.Thread(target=self.auth)
auth_thread.daemon = True
auth_thread.start()
def auth_start_ev(self, event):
auth_thread = threading.Thread(target=self.auth)
auth_thread.daemon = True
auth_thread.start()
def button_disable(self):
self.help_button.configure(state="disabled", fg_color="gray")
self.signin_button.configure(state="disabled", fg_color="gray")
self.signout_button.configure(state="disabled", fg_color="gray")
def button_enable(self):
self.help_button.configure(state="normal", fg_color="#3c8dd0")
self.signin_button.configure(state="normal", fg_color="#3c8dd0")
self.signout_button.configure(state="normal", fg_color="#3c8dd0")
def get_input_devices(self):
try:
pythoncom.CoInitialize()
str_computer = "."
obj_wmi_service = win32com.client.Dispatch("WbemScripting.SWbemLocator")
obj_swem_services = obj_wmi_service.ConnectServer(str_computer, "root\\cimv2")
col_items = obj_swem_services.ExecQuery("Select * from Win32_PnPEntity where PNPDeviceID like 'HID%'")
input_devices = []
for obj_item in col_items:
input_devices.append({
"device_id": obj_item.DeviceID,
"PNPDeviceID": obj_item.PNPDeviceID,
"Description": obj_item.Description,
"device_name": obj_item.Name,
"Manufacturer": obj_item.Manufacturer,
"Service": obj_item.Service,
"FriendlyName": obj_item.Name, # デバイスとプリンターで表示される名前
"device_instance_path": obj_item.DeviceID # デバイスインスタンスパス
})
pythoncom.CoUninitialize()
return input_devices
except pythoncom.com_error as e:
print("Error:", e)
return []
def auth(self):
self.button_disable()
password = str(self.password_entry.get())
#devices = self.get_input_devices()
devices = []
if len(password) == 10:
print("マスターパスワードで認証を試行します。")
master_password_hash = self.hash_genarate(str(self.password_entry.get()))
if client_config["master_password_hash"] == master_password_hash:
print("マスターパスワードで認証しました。")
self.exit()
else:
print("マスターパスワードで認証できませんでした。")
self.withdraw()
msgbox = tkinter.messagebox.showinfo(title=f"{app_name} | 誤ったパスワード", message=f"パスワードが間違っています!")
self.msg_subtitle_1.configure(text='パスワードが間違っています! ')
self.button_enable()
self.deiconify()
print("認証サーバーにアクセスします。")
auth_url = client_config["auth_host_url"] + "/verify"
auth_json = {
"pc_number": int(client_config["pc_number"]),
"pc_uuid": str(client_config["pc_uuid"]),
"pc_token": str(client_config["pc_token"]),
"devices": devices,
"password": self.hash_genarate(str(self.password_entry.get()))
}
try:
responce = requests.post(auth_url, json=auth_json)
if responce.status_code == 200:
print("認証サーバー経由で認証しました。")
self.exit()
elif responce.status_code == 401:
print("認証サーバー経由での認証に失敗しました。")
self.withdraw()
msgbox = tkinter.messagebox.showinfo(title=f"{app_name} | 誤ったパスワード", message=f"パスワードが間違っています!")
self.msg_subtitle_1.configure(text='パスワードが間違っています! ')
self.button_enable()
self.deiconify()
elif responce.status_code == 500:
print("内部エラーにより認証に失敗しました。")
self.withdraw()
msgbox = tkinter.messagebox.showinfo(title=f"{app_name} | 内部エラー", message=f"内部エラーにより認証に失敗しました。")
self.msg_subtitle_1.configure(text='内部エラーにより認証に失敗しました。 ')
self.button_enable()
self.deiconify()
except:
print("認証サーバーにアクセスできません。マスターパスワードで認証を試行します。")
master_password_hash = self.hash_genarate(str(self.password_entry.get()))
if client_config["master_password_hash"] == master_password_hash:
print("マスターパスワードで認証しました。")
self.exit()
else:
print("マスターパスワードで認証できませんでした。")
self.withdraw()
msgbox = tkinter.messagebox.showinfo(title=f"{app_name} | ネットワークエラー", message=f"認証サーバーにアクセスできませんでした。\n続行するには、マスターパスワードを入力してください。")
self.msg_subtitle_1.configure(text='ネットワークエラーが発生しています。\n続行するには、マスターパスワードを入力して下さい。 ')
self.button_enable()
self.deiconify()
def signout(self):
app.unlock_taskmgr()
self.destroy()
signout_command = subprocess.run('shutdown /l /f', startupinfo=sp_startupinfo, stdout=subprocess.PIPE, text=True)
print(signout_command)
def handler_close(self):
pass
def help_dummy(self):
self.withdraw()
msgbox = tkinter.messagebox.showinfo(title=f"{app_name} | 未実装", message=f"ヘルプページは製作途中です。\nDiscordサーバーの指示に従って、認証を進めてください。")
self.deiconify()
def wakeup_shutdown_background(self):
wakeup = subprocess.Popen(f'{dislocker_dir}\\dislocker_client_shutdown.exe', startupinfo=sp_startupinfo)
def exit(self):
try:
self.wakeup_shutdown_background()
except:
pass
self.destroy()
app.exit()
class Help(customtkinter.CTkToplevel):
def __init__(self):
super().__init__()
if client_config["testing"] == True:
self.title(f'{app_name} | ヘルプ | テストモード')
else:
self.title(f'{app_name} | ヘルプ')
self.iconbitmap(default=resource_path + '\\icon\\dislocker.ico')
self.geometry("600x400")
self.resizable(height=False, width=False)
self.attributes('-topmost', True)
self.grab_set()
self.lift()
self.protocol("WM_DELETE_WINDOW", self.handler_close)
msgbox = tkinter.messagebox.showinfo(title=f"{app_name} | 未実装", message=f"ヘルプページは製作途中です。\nDiscordサーバーの指示に従って、認証を進めてください。")
self.destroy()
def handler_close(self):
self.destroy()
class Stop():
def __init__(self) -> None:
pass
def run(self):
stop_thread = threading.Thread(target=self.stop)
stop_thread.run()
def delete_appdata(self, **kwargs):
process_name = kwargs["process_name"]
dir_path = kwargs["dir_path"]
if not os.path.exists(dir_path):
print(f"エラー: 指定されたディレクトリ {dir_path} が存在しません。")
return 1
i = 0
i_max = 10
result = 1
while i != i_max:
i += 1
try:
# プロセスの終了
subprocess.run(f'taskkill /f /t /im {process_name}', startupinfo=sp_startupinfo, stdout=subprocess.PIPE, text=True)
print(f"{process_name} を終了しました。")
time.sleep(0.1)
# ディレクトリの削除
shutil.rmtree(dir_path)
if os.path.isdir(dir_path):
pass
else:
print(f"{dir_path} を削除しました。")
result = 0
i = i_max
except subprocess.CalledProcessError as e:
print(f"プロセス終了エラー: {e}")
except PermissionError as e:
print(f"権限エラー: {e}")
except Exception as e:
print("エラーが発生しました。\nエラー内容:")
print(f"エラータイプ: {e.__class__.__name__}")
print(f"エラー引数: {e.args}")
print(f"エラーメッセージ: {str(e)}")
return result
def shutdown(self):
shutdown_command = subprocess.run('shutdown /s /f /t 0', startupinfo=sp_startupinfo, stdout=subprocess.PIPE, text=True)
def stop(self):
print("停止処理を実行。")
if client_config["eraser"] == True:
appdata_local = os.path.expandvars("%LOCALAPPDATA%")
appdata_roaming = os.path.expandvars("%APPDATA%")
epic_del = self.delete_appdata(process_name="EpicGamesLauncher.exe", dir_path=f"{appdata_local}\\EpicGamesLauncher\\Saved")
chrome_del = self.delete_appdata(process_name="chrome.exe", dir_path=f"{appdata_local}\\Google\\Chrome\\User Data")
discord_del = self.delete_appdata(process_name="discord.exe", dir_path=f"{appdata_roaming}\\discord")
steam_del = self.delete_appdata(process_name="steam.exe", dir_path=f"{appdata_local}\\Steam")
ea_del = self.delete_appdata(process_name="EADesktop.exe", dir_path=f"{appdata_local}\\Electronic Arts")
riot_del = self.delete_appdata(process_name="RiotClientServices.exe", dir_path=f"{appdata_local}\\Riot Games\\Riot Client")
else:
print("削除処理をスキップ。")
stop_url = client_config["auth_host_url"] + "/stop"
stop_json = {
"pc_number": int(client_config["pc_number"]),
"pc_uuid": str(client_config["pc_uuid"]),
"pc_token": str(client_config["pc_token"])
}
try:
responce = requests.post(stop_url, json=stop_json)
if responce.status_code == 200:
print("停止処理は成功しました。")
elif responce.status_code == 401:
print("認証に失敗しました。")
else:
print("内部エラーにより停止処理に失敗しました。")
except:
print("ネットワークエラーにより停止処理に失敗しました。")
finally:
self.shutdown()
if __name__ == '__main__':
args = sys.argv
if len(args) >= 2:
if args[1] == "stop":
init_result = init()
if init_result == 1:
print("多重起動を検出。")
elif init_result == 2:
pass
else:
stop = Stop()
stop.run()
elif args[1] == "setup":
if len(args) == 4:
init_result = init(pc_number=args[2], onetime=args[3])
elif len(args) == 5:
init_result = init(pc_number=args[2], onetime=args[3], host_url=args[4])
else:
print("引数エラー。")
error_msgbox = tkinter.messagebox.showerror(title=f"{app_name} | 引数エラー", message=f"引数が多すぎるか、少なすぎます。\n引数がPC番号、ワンタイムパスワード、ホストURLの順で正しく指定されているか確認してください。")
if init_result == 1:
warning_msgbox = tkinter.messagebox.showwarning(title=f"{app_name} | 多重起動エラー", message=f"すでに {app_name} は実行されています。\n正常に起動しない場合は、既に起動しているプロセスを終了してから、もう一度起動してみてください。")
elif init_result == 2:
pass
else:
pass
elif args[1] == "deviceregister":
init_result = init()
if init_result == 1:
warning_msgbox = tkinter.messagebox.showwarning(title=f"{app_name} | 多重起動エラー", message=f"すでに {app_name} は実行されています。\n正常に起動しない場合は、既に起動しているプロセスを終了してから、もう一度起動してみてください。")
elif init_result == 2:
pass
else:
mode = input('登録するデバイスはキーボードとマウスのどちらですか?(keyboard/mouse): ')
input_devices = get_input_devices()
i = 0
for device in input_devices:
print(f"{str(i + 1)} 番目 | デバイス名: {device['device_name']} \n製造元: {device['Manufacturer']} \nデバイスインスタンスパス: {device['device_instance_path']}")
print("-" * 20)
i += 1
device_num = input('どのデバイスを登録しますか?番号で指定してください: ')
device_register_num = input('そのデバイスは何番目のデバイスとして登録しますか?番号で指定してください: ')
onetime = input('ワンタイムパスワードを入力してください: ')
device_register_result = device_register(onetime=onetime, mode=mode, number=int(device_register_num), device_instance_path=input_devices[int(device_num) - 1]["device_instance_path"], device_name=input_devices[int(device_num) - 1]["device_name"])
if device_register_result["result"] == 0:
print("登録されました。")
elif device_register_result["result"] == 1:
if device_register_result["about"] == "auth_failed":
print("認証に失敗しました。")
else:
print("エラーが発生しました。")
elif args[1] == "guitest":
init_result = init()
client_config["testing"] = True
app = App()
app.mainloop()
else:
print("引数エラー。")
else:
init_result = init()
if init_result == 1:
warning_msgbox = tkinter.messagebox.showwarning(title=f"{app_name} | 多重起動エラー", message=f"すでに {app_name} は実行されています。\n正常に起動しない場合は、既に起動しているプロセスを終了してから、もう一度起動してみてください。")
elif init_result == 2:
pass
else:
app = App()
app.protocol("WM_DELETE_WINDOW", app.handler_close)
app.mainloop()