import tkinter as tk
from tkinter import simpledialog, messagebox
import sys
import hashlib
import ctypes
import psutil
HASHED_EXIT_PASSWORD = hashlib.sha256(b"123").hexdigest()
USE_KEYBOARD_LIB = True
try:
import keyboard
except Exception:
USE_KEYBOARD_LIB = False
user32 = ctypes.windll.user32
SWP_SHOWWINDOW = 0x0040
SWP_HIDEWINDOW = 0x0080
HWND_TOPMOST = -1
SW_HIDE = 0
SW_SHOW = 5
def hide_taskbar():
try:
tray_hwnd = ctypes.windll.user32.FindWindowW("Shell_TrayWnd", None)
if tray_hwnd:
ctypes.windll.user32.ShowWindow(tray_hwnd, SW_HIDE)
start_hwnd = ctypes.windll.user32.FindWindowW("Button", None)
except Exception:
pass
def show_taskbar():
try:
tray_hwnd = ctypes.windll.user32.FindWindowW("Shell_TrayWnd", None)
if tray_hwnd:
ctypes.windll.user32.ShowWindow(tray_hwnd, SW_SHOW)
except Exception:
pass
def force_topmost_and_cover(root):
try:
width = user32.GetSystemMetrics(0) # SM_CXSCREEN
height = user32.GetSystemMetrics(1) # SM_CYSCREEN
root.update_idletasks()
hwnd = ctypes.windll.user32.FindWindowW(None, root.title())
if not hwnd:
try:
hwnd = ctypes.windll.user32.GetParent(root.winfo_id())
except Exception:
hwnd = root.winfo_id()
ctypes.windll.user32.SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, width, height, SWP_SHOWWINDOW)
except Exception:
pass
root = tk.Tk()
root.title("Kiosk Mode")
root.configure(bg="black")
root.attributes("-fullscreen", True)
root.attributes("-topmost", True)
label = tk.Label(root, text=" (: ", bg="black", fg="green", font=("Arial", 36))
label.pack(expand=True, fill="both")
hint = tk.Label(root, text="Ctrl+Shift+Q : برای خروج امن", bg="black", fg="gray", font=("Arial", 12))
hint.place(relx=0.5, rely=0.95, anchor="s")
HIDED_CURSOR = False
try:
ctypes.windll.user32.ShowCursor(False)
HIDED_CURSOR = True
except Exception:
HIDED_CURSOR = False
TASKBAR_HIDDEN = False
def check_password_input(pw_plain):
if pw_plain is None:
return False
hashed = hashlib.sha256(pw_plain.encode('utf-8')).hexdigest()
return hashed == HASHED_EXIT_PASSWORD
def safe_exit_dialog():
pw = simpledialog.askstring("خروج امن", "رمز خروج را وارد کنید:", show="*")
if pw is None:
return
if check_password_input(pw):
cleanup_and_exit()
else:
messagebox.showerror("رمز اشتباه", "رمز وارد شده صحیح نیست.")
def cleanup_and_exit():
global HIDED_CURSOR, TASKBAR_HIDDEN
try:
if HIDED_CURSOR:
ctypes.windll.user32.ShowCursor(True)
except Exception:
pass
if TASKBAR_HIDDEN:
show_taskbar()
if USE_KEYBOARD_LIB:
try:
keyboard.unhook_all()
except Exception:
pass
try:
root.destroy()
except Exception:
pass
sys.exit(0)
def on_keypress(event):
ctrl_mask = 0x0004
shift_mask = 0x0001
try:
if (event.state & ctrl_mask) and (event.state & shift_mask) and event.keysym.lower() == 'q':
root.after(0, safe_exit_dialog)
except Exception:
pass
root.bind_all("<Key>", on_keypress)
blocked_keys = [
'print_screen',
'alt', 'tab', 'esc', 'alt+tab', 'alt+f4',
'left windows', 'right windows', 'windows', 'win', 'apps',
'ctrl+shift+esc', 'ctrl+esc','widows+tab'
]
def setup_keyboard_blocker_and_hotkey():
if not USE_KEYBOARD_LIB:
return
try:
for key in blocked_keys:
try:
if '+' in key:
continue
keyboard.block_key(key)
except Exception:
pass
try:
keyboard.add_hotkey('ctrl+shift+q', lambda: root.after(0, safe_exit_dialog))
except Exception:
pass
def on_event(e):
return
try:
keyboard.hook(on_event)
except Exception:
pass
except Exception:
pass
def keep_on_top_loop():
try:
root.attributes("-topmost", True)
root.after(500, keep_on_top_loop)
except tk.TclError:
return
def prepare_kiosk_environment():
global TASKBAR_HIDDEN
try:
hide_taskbar()
TASKBAR_HIDDEN = True
except Exception:
TASKBAR_HIDDEN = False
try:
force_topmost_and_cover(root)
except Exception:
pass
def block_task_manager_focus():
for proc in psutil.process_iter(['name']):
if proc.info['name'] and "Taskmgr.exe" in proc.info['name']:
# تلاش برای بستن Task Manager
try:
proc.terminate()
except Exception:
pass
# دوباره این تابع بعد از 500 میلیثانیه اجرا شود
root.after(500, block_task_manager_focus)
prepare_kiosk_environment()
setup_keyboard_blocker_and_hotkey()
keep_on_top_loop()
root.after(500, block_task_manager_focus)
def disable_event():
return
root.protocol("WM_DELETE_WINDOW", disable_event)
try:
root.mainloop()
finally:
try:
if HIDED_CURSOR:
ctypes.windll.user32.ShowCursor(True)
except Exception:
pass
if TASKBAR_HIDDEN:
try:
show_taskbar()
except Exception:
pass
if USE_KEYBOARD_LIB:
try:
keyboard.unhook_all()
except Exception:
pass