unmovable.fix

main
Satur@it-depot.ru 2025-03-11 11:10:52 +03:00
parent f472d2a6ca
commit 2e1734f5ea
1 changed files with 384 additions and 244 deletions

628
app.py
View File

@ -1,266 +1,406 @@
$ErrorActionPreference = 'silentlycontinue'
from fastapi import FastAPI, HTTPException, File, UploadFile, Form, Query, WebSocket, WebSocketDisconnect
from pydantic import BaseModel
import sqlite3
import datetime
import csv
import markdown
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse, StreamingResponse
import io
import os
from fastapi.middleware.cors import CORSMiddleware
from werkzeug.utils import secure_filename
import json
# Формируем пароль из зашифрованных частей
$p1 = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("cDk4"))
$p2 = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("Nng="))
$p3 = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("Yjc4"))
$rustdesk_pw = $p1 + $p2 + $p3
# Создаем два экземпляра FastAPI
web_app = FastAPI(title="Web Interface") # Для веб-интерфейса (порт 8001)
api_app = FastAPI(title="API Endpoints") # Для API (порт 8002)
# Get your config string from your Web portal and Fill Below
$rustdesk_cfg = "0nI1JnL09GclRWL0lmL0NXdy9yL6MHc0RHaiojIpBXYiwiI9gjYwBjbXVERFRXZiNEVYBjRGdHUZhUUvBVRx52dWlmenlTY6t0U1IlMLhlI6ISeltmIsISdy5CdvBXZk1Cdp5CdzVnciojI5FGblJnIsISdy5CdvBXZk1Cdp5CdzVnciojI0N3boJye"
# Общий код для подключения к базе данных
conn = sqlite3.connect("/db/rustdesk.db", check_same_thread=False)
cursor = conn.cursor()
################################### Please Do Not Edit Below This Line #########################################
# Проверяем и обновляем структуру таблицы installs
cursor.execute("PRAGMA table_info(installs)")
columns = [row[1] for row in cursor.fetchall()]
if 'protocol' not in columns:
cursor.execute("ALTER TABLE installs ADD COLUMN protocol TEXT DEFAULT 'rustdesk'")
conn.commit()
if 'note' not in columns:
cursor.execute("ALTER TABLE installs ADD COLUMN note TEXT DEFAULT ''")
conn.commit()
if 'last_seen' not in columns:
cursor.execute("ALTER TABLE installs ADD COLUMN last_seen TEXT DEFAULT NULL")
conn.commit()
# Run as administrator and stays in the current directory
if (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
Start-Process PowerShell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
Exit;
# Создаем таблицы
cursor.execute("""
CREATE TABLE IF NOT EXISTS folders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
parent_id INTEGER,
FOREIGN KEY (parent_id) REFERENCES folders(id)
)
""")
cursor.execute("""
CREATE TABLE IF NOT EXISTS installs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
rust_id TEXT,
computer_name TEXT,
install_time TEXT,
folder_id INTEGER,
protocol TEXT DEFAULT 'rustdesk',
note TEXT DEFAULT '',
last_seen TEXT DEFAULT NULL,
FOREIGN KEY (folder_id) REFERENCES folders(id)
)
""")
conn.commit()
# Проверяем/создаем папку "Несортированные" и получаем её ID
cursor.execute("SELECT id FROM folders WHERE name = 'Несортированные'")
unsorted_folder = cursor.fetchone()
if not unsorted_folder:
cursor.execute("INSERT INTO folders (name) VALUES ('Несортированные')")
conn.commit()
unsorted_folder_id = cursor.lastrowid
else:
unsorted_folder_id = unsorted_folder[0]
# Папка для загрузки изображений
UPLOAD_FOLDER = "/app/uploads"
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
# Монтируем папку uploads для доступа к изображениям
api_app.mount("/uploads", StaticFiles(directory=UPLOAD_FOLDER), name="uploads")
web_app.mount("/uploads", StaticFiles(directory=UPLOAD_FOLDER), name="uploads")
# Модели данных
class Folder(BaseModel):
name: str
parent_id: int | None = None
class FolderUpdate(BaseModel):
name: str
class InstallData(BaseModel):
rust_id: str | None = None
computer_name: str | None = None
install_time: str | None = None
folder_id: int | None = None
protocol: str | None = 'rustdesk'
note: str | None = ''
last_seen: str | None = None
# Функция форматирования времени
def format_time(time_str):
if not time_str:
return None
try:
dt = datetime.datetime.strptime(time_str, "%Y-%m-%dT%H:%M:%S.%fZ")
return dt.strftime("%Y-%m-%d %H:%M:%S")
except ValueError:
try:
dt = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S")
return dt.strftime("%Y-%m-%d %H:%M:%S")
except ValueError:
return time_str
# Монтируем папки templates и icons
web_app.mount("/templates", StaticFiles(directory="templates"), name="templates")
web_app.mount("/icons", StaticFiles(directory="templates/icons"), name="icons")
# Веб-интерфейс
@web_app.get("/")
async def root():
return FileResponse("templates/index.html")
# WebSocket для отправки обновлений статуса
class ConnectionManager:
def __init__(self):
self.active_connections: list[WebSocket] = []
self.max_connections = 100 # Ограничение числа подключений
async def connect(self, websocket: WebSocket):
if len(self.active_connections) >= self.max_connections:
await websocket.close(code=1008, reason="Too many connections")
return
await websocket.accept()
self.active_connections.append(websocket)
def disconnect(self, websocket: WebSocket):
self.active_connections.remove(websocket)
async def broadcast(self, message: str):
for connection in self.active_connections[:]: # Копируем список для безопасного удаления
await connection.send_text(message)
manager = ConnectionManager()
@api_app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await manager.connect(websocket)
try:
while True:
data = await websocket.receive_text()
except WebSocketDisconnect:
manager.disconnect(websocket)
# API-эндпоинты
@api_app.get("/api/folders")
def get_folders():
cursor.execute("SELECT * FROM folders")
rows = cursor.fetchall()
return [{"id": row[0], "name": row[1], "parent_id": row[2]} for row in rows]
@api_app.post("/api/folders")
def add_folder(folder: Folder):
cursor.execute("INSERT INTO folders (name, parent_id) VALUES (?, ?)",
(folder.name, folder.parent_id))
conn.commit()
return {"status": "success", "id": cursor.lastrowid}
@api_app.put("/api/folders/{folder_id}")
def update_folder(folder_id: int, folder: FolderUpdate):
cursor.execute("UPDATE folders SET name = ? WHERE id = ?", (folder.name, folder_id))
conn.commit()
if cursor.rowcount == 0:
raise HTTPException(status_code=404, detail="Папка не найдена")
return {"status": "success"}
@api_app.delete("/api/folders/{folder_id}")
def delete_folder(folder_id: int):
cursor.execute("SELECT name FROM folders WHERE id = ?", (folder_id,))
folder_name = cursor.fetchone()
if folder_name and folder_name[0] == 'Несортированные':
raise HTTPException(status_code=403, detail="Папка 'Несортированные' не может быть удалена")
cursor.execute("DELETE FROM folders WHERE id = ?", (folder_id,))
conn.commit()
if cursor.rowcount == 0:
raise HTTPException(status_code=404, detail="Папка не найдена")
return {"status": "success"}
@api_app.get("/api/installs")
def get_installs():
cursor.execute("""
SELECT i.id, i.rust_id, i.computer_name, i.install_time, i.folder_id, f.name as folder_name, i.protocol, i.note, i.last_seen
FROM installs i
LEFT JOIN folders f ON i.folder_id = f.id
""")
rows = cursor.fetchall()
return [{"id": row[0], "rust_id": row[1], "computer_name": row[2],
"install_time": format_time(row[3]),
"folder_id": row[4], "folder_name": row[5], "protocol": row[6], "note": row[7], "last_seen": row[8]}
for row in rows]
@api_app.post("/api/install")
async def add_install(data: InstallData):
rust_id = data.rust_id
computer_name = data.computer_name or f"PC_{rust_id}"
install_time = data.install_time or datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
protocol = data.protocol or 'rustdesk'
note = data.note or ''
last_seen = data.last_seen or datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Проверяем, существует ли запись с таким rust_id
cursor.execute("SELECT id, folder_id, protocol, note FROM installs WHERE rust_id = ?", (rust_id,))
existing = cursor.fetchone()
if existing:
# Если запись существует, используем текущий folder_id из базы данных
current_folder_id = existing[1] # Текущий folder_id
current_protocol = existing[2] # Текущий protocol
current_note = existing[3] # Текущая заметка
# Обновляем запись, сохраняя существующий folder_id
cursor.execute("""
UPDATE installs
SET computer_name = ?, install_time = ?, protocol = ?, note = ?, last_seen = ?
WHERE rust_id = ?
""", (computer_name, install_time, current_protocol, current_note, last_seen, rust_id))
else:
# Если записи нет, создаем новую, используя folder_id из запроса или "Несортированные"
folder_id = data.folder_id if data.folder_id is not None else unsorted_folder_id
cursor.execute("""
INSERT INTO installs (rust_id, computer_name, install_time, folder_id, protocol, note, last_seen)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (rust_id, computer_name, install_time, folder_id, protocol, note, last_seen))
conn.commit()
# Получаем обновленную запись для отправки через WebSocket
cursor.execute("""
SELECT id, rust_id, computer_name, install_time, folder_id, protocol, note, last_seen
FROM installs WHERE rust_id = ?
""", (rust_id,))
updated_install = cursor.fetchone()
install_data = {
"id": updated_install[0],
"rust_id": updated_install[1],
"computer_name": updated_install[2],
"install_time": format_time(updated_install[3]),
"folder_id": updated_install[4], # Используем folder_id из базы
"protocol": updated_install[5],
"note": updated_install[6],
"last_seen": updated_install[7]
}
}
# Отправляем обновленную запись через WebSocket
await manager.broadcast(json.dumps({"type": "update", "data": install_data}))
# Проверка наличия установленного RustDesk
$rustdeskInstalled = Test-Path "$env:ProgramFiles\RustDesk\rustdesk.exe"
$rdver = ((Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\RustDesk\" -ErrorAction SilentlyContinue).Version)
return {"status": "success"}
if ($rustdeskInstalled -and $rdver) {
echo "RustDesk $rdver is already installed. Importing configuration..."
cd $env:ProgramFiles\RustDesk
.\rustdesk.exe --config $rustdesk_cfg
.\rustdesk.exe --password $rustdesk_pw
} else {
$localRustDesk = Join-Path $PSScriptRoot "rustdesk.exe"
$rustdeskExistsLocally = Test-Path $localRustDesk
@api_app.put("/api/install/{install_id}")
def update_install(install_id: int, data: InstallData):
cursor.execute("SELECT rust_id, computer_name, install_time, folder_id, protocol, note FROM installs WHERE id = ?", (install_id,))
current = cursor.fetchone()
if not current:
raise HTTPException(status_code=404, detail="Запись не найдена")
new_rust_id = data.rust_id if data.rust_id is not None else current[0]
new_computer_name = data.computer_name if data.computer_name is not None else current[1]
new_install_time = data.install_time if data.install_time is not None else current[2]
new_folder_id = data.folder_id if data.folder_id is not None else current[3]
new_protocol = data.protocol if data.protocol is not None else current[4]
new_note = data.note if data.note is not None else current[5]
if (-not $rustdeskExistsLocally) {
$url = 'https://www.github.com//rustdesk/rustdesk/releases/latest'
$request = [System.Net.WebRequest]::Create($url)
$response = $request.GetResponse()
$realTagUrl = $response.ResponseUri.OriginalString
$RDLATEST = $realTagUrl.split('/')[-1].Trim('v')
echo "RustDesk $RDLATEST is the latest version."
} else {
$RDLATEST = "local"
if new_install_time:
try:
datetime.datetime.strptime(new_install_time, "%Y-%m-%d %H:%M:%S")
except ValueError:
raise HTTPException(status_code=400, detail="Неверный формат времени. Используйте YYYY-MM-DD HH:MM:SS")
else:
new_install_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cursor.execute("""
UPDATE installs
SET rust_id = ?, computer_name = ?, install_time = ?, folder_id = ?, protocol = ?, note = ?
WHERE id = ?
""", (new_rust_id, new_computer_name, new_install_time, new_folder_id, new_protocol, new_note, install_id))
conn.commit()
return {"status": "success"}
@api_app.delete("/api/install/{install_id}")
def delete_install(install_id: int):
cursor.execute("DELETE FROM installs WHERE id = ?", (install_id,))
conn.commit()
if cursor.rowcount == 0:
raise HTTPException(status_code=404, detail="Запись не найдена")
return {"status": "success"}
@api_app.get("/api/export/csv")
async def export_csv(folder_id: int | None = Query(None, description="ID папки для экспорта, если None - экспортировать все папки")):
if folder_id:
cursor.execute("""
SELECT i.rust_id, i.computer_name, i.install_time, f.name as folder_name, i.protocol, i.note, i.last_seen
FROM installs i
LEFT JOIN folders f ON i.folder_id = f.id
WHERE i.folder_id = ?
""", (folder_id,))
else:
cursor.execute("""
SELECT i.rust_id, i.computer_name, i.install_time, f.name as folder_name, i.protocol, i.note, i.last_seen
FROM installs i
LEFT JOIN folders f ON i.folder_id = f.id
""")
rows = cursor.fetchall()
output = io.StringIO()
writer = csv.writer(output, lineterminator='\n')
writer.writerow(['ID подключения', 'Имя компьютера', 'Время установки', 'Папка', 'Протокол', 'Заметка', 'Последнее подключение'])
for row in rows:
install_time = format_time(row[2]) if row[2] else ""
last_seen = format_time(row[6]) if row[6] else ""
writer.writerow([row[0], row[1], install_time, row[3], row[4], row[5], last_seen])
headers = {
'Content-Disposition': 'attachment; filename="rustdesk_data.csv"',
'Content-Type': 'text/csv'
}
return StreamingResponse(iter([output.getvalue()]), headers=headers)
if (!(Test-Path C:\ProgramData\RustDesk)) {
New-Item -ItemType Directory -Force -Path C:\ProgramData\RustDesk > null
}
@api_app.post("/api/import/csv")
async def import_csv(file: UploadFile = File(...), folder_id: int | None = Query(None, description="ID папки для импорта, если None - использовать 'Несортированные'")):
try:
contents = await file.read()
csv_data = io.StringIO(contents.decode('utf-8'))
reader = csv.DictReader(csv_data)
cd C:\ProgramData\RustDesk
target_folder_id = folder_id if folder_id is not None else unsorted_folder_id
if ($rustdeskExistsLocally) {
echo "Found local rustdesk.exe, using it for installation."
Copy-Item -Path $localRustDesk -Destination ".\rustdesk.exe" -Force
} else {
echo "Downloading RustDesk version $RDLATEST."
powershell Invoke-WebRequest "https://github.com/rustdesk/rustdesk/releases/download/$RDLATEST/rustdesk-$RDLATEST-x86_64.exe" -Outfile "rustdesk.exe"
}
for row in reader:
rust_id = row['ID подключения']
computer_name = row['Имя компьютера']
install_time = row['Время установки']
folder_name = row.get('Папка', None)
protocol = row.get('Протокол', 'rustdesk')
note = row.get('Заметка', '')
echo "Installing RustDesk."
Start-Process .\rustdesk.exe --silent-install
Start-Sleep -Seconds 10
cursor.execute("SELECT id FROM installs WHERE rust_id = ?", (rust_id,))
if cursor.fetchone():
continue
$ServiceName = 'rustdesk'
$arrService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if install_time:
try:
dt = datetime.datetime.strptime(install_time, "%Y-%m-%d %H:%M:%S")
install_time = dt.strftime("%Y-%m-%d %H:%M:%S")
except ValueError:
try:
dt = datetime.datetime.strptime(install_time, "%Y-%m-%dT%H:%M:%S.%fZ")
install_time = dt.strftime("%Y-%m-%d %H:%M:%S")
except ValueError:
raise HTTPException(status_code=400, detail=f"Неверный формат времени для записи с ID {rust_id}. Используйте YYYY-MM-DD HH:MM:SS или ISO 8601")
if ($arrService -eq $null) {
echo "Installing service."
cd $env:ProgramFiles\RustDesk
Start-Process .\rustdesk.exe --install-service -wait -Verbose
Start-Sleep -Seconds 20
}
if folder_name:
cursor.execute("SELECT id FROM folders WHERE name = ?", (folder_name,))
folder = cursor.fetchone()
folder_id = folder[0] if folder else unsorted_folder_id
else:
folder_id = target_folder_id
while ($arrService.Status -ne 'Running') {
Start-Service $ServiceName
Start-Sleep -seconds 5
$arrService.Refresh()
}
cursor.execute("""
INSERT INTO installs (rust_id, computer_name, install_time, folder_id, protocol, note)
VALUES (?, ?, ?, ?, ?, ?)
""", (rust_id, computer_name, install_time, folder_id, protocol, note))
conn.commit()
return {"status": "success", "message": "Данные успешно импортированы"}
except Exception as e:
raise HTTPException(status_code=400, detail=f"Ошибка импорта: {str(e)}")
echo "Please wait a few seconds."
Start-Sleep -Seconds 10
Remove-Item -Path "C:\ProgramData\RustDesk\rustdesk.exe" -Force
echo "Temporary installation files have been cleaned up."
cd $env:ProgramFiles\RustDesk
echo "Inputting configuration now."
.\rustdesk.exe --config $rustdesk_cfg
.\rustdesk.exe --password $rustdesk_pw
}
@api_app.post("/api/upload-image")
async def upload_image(install_id: int = Form(...), file: UploadFile = File(...)):
if not file.filename:
raise HTTPException(status_code=400, detail="No file provided")
allowed_extensions = {'png', 'jpg', 'jpeg', 'gif'}
if not secure_filename(file.filename).rsplit('.', 1)[1].lower() in allowed_extensions:
raise HTTPException(status_code=400, detail="Invalid file format. Use png, jpg, jpeg, or gif")
# Добавляем папку RustDesk в исключения Windows Defender
$defenderPath = "C:\Program Files\RustDesk"
try {
Add-MpPreference -ExclusionPath $defenderPath -ErrorAction Stop
echo "Added $defenderPath to Windows Defender exclusions."
} catch {
echo "Failed to add $defenderPath to Windows Defender exclusions: $_"
}
filename = secure_filename(f"{install_id}_{file.filename}")
file_path = os.path.join(UPLOAD_FOLDER, filename)
# Удаляем ярлык с общего рабочего стола
$publicDesktop = "C:\Users\Public\Desktop\RustDesk.lnk"
if (Test-Path $publicDesktop) {
Remove-Item -Path $publicDesktop -Force
echo "Removed RustDesk shortcut from Public Desktop."
}
with open(file_path, "wb") as buffer:
buffer.write(await file.read())
# Создаем папку RustDesk в меню Пуск под Critical Fixes
$startMenuPath = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Critical Fixes\RustDesk"
if (!(Test-Path $startMenuPath)) {
New-Item -ItemType Directory -Force -Path $startMenuPath
}
url = f"/uploads/{filename}"
return {"url": url}
$shortcutPath = "$startMenuPath\RustDesk.lnk"
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut($shortcutPath)
$shortcut.TargetPath = "$env:ProgramFiles\RustDesk\rustdesk.exe"
$shortcut.Save()
echo "Created RustDesk shortcut in Start Menu under Critical Fixes\RustDesk."
# CORS для API
api_app.add_middleware(
CORSMiddleware,
allow_origins=["https://rd.it-depot.ru"], # Обновлено для HTTPS
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Удаляем папку RustDesk из корня Programs
$rustDeskStartMenu = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\RustDesk"
if (Test-Path $rustDeskStartMenu) {
Remove-Item -Path $rustDeskStartMenu -Recurse -Force
echo "Removed RustDesk folder from Start Menu Programs."
}
# Добавляем параметры в конфигурационные файлы
$configPath = "$env:USERPROFILE\AppData\Roaming\RustDesk\config"
$config2Path = "$configPath\RustDesk2.toml"
$configLocalPath = "$configPath\RustDesk_local.toml"
if (!(Test-Path $configPath)) {
New-Item -ItemType Directory -Force -Path $configPath
}
if (!(Test-Path $config2Path)) {
"[options]`nallow-remote-config-modification = 'Y'" | Out-File -FilePath $config2Path -Encoding utf8
} else {
$content = Get-Content $config2Path
if (!($content -match "allow-remote-config-modification")) {
if ($content -match "\[options\]") {
$content = $content -replace "\[options\]", "[options]`nallow-remote-config-modification = 'Y'"
} else {
$content += "`n[options]`nallow-remote-config-modification = 'Y'"
}
$content | Out-File -FilePath $config2Path -Encoding utf8
}
}
if (!(Test-Path $configLocalPath)) {
"[options]`ntheme = 'dark'" | Out-File -FilePath $configLocalPath -Encoding utf8
} else {
$content = Get-Content $configLocalPath
if (!($content -match "theme")) {
if ($content -match "\[options\]") {
$content = $content -replace "\[options\]", "[options]`ntheme = 'dark'"
} else {
$content += "`n[options]`ntheme = 'dark'"
}
$content | Out-File -FilePath $configLocalPath -Encoding utf8
}
}
# Создание BAT-файла для удаления
$uninstallBatPath = "$env:ProgramFiles\RustDesk\Uninstall RustDesk.bat"
$uninstallBatContent = @"
@echo off
echo Stopping RustDeskOnlineCheck task...
schtasks /End /TN "RustDeskOnlineCheck"
timeout /t 2 >nul
echo Deleting RustDeskOnlineCheck task...
schtasks /Delete /TN "RustDeskOnlineCheck" /F
echo Stopping RustDesk service...
sc stop rustdesk
timeout /t 2 >nul
echo Uninstalling RustDesk...
"C:\Program Files\RustDesk\rustdesk.exe" --uninstall
echo Cleaning up files...
rd /s /q "C:\ProgramData\RustDesk"
rd /s /q "%appdata%\RustDesk"
rd /s /q "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Critical Fixes\RustDesk"
echo Removing Windows Defender exclusion...
powershell -Command "Remove-MpPreference -ExclusionPath 'C:\Program Files\RustDesk'" 2>nul
echo RustDesk has been completely removed.
pause
"@
# Удаляем существующий ярлык Uninstall RustDesk, если он есть
$uninstallLnkPath = "$env:ProgramFiles\RustDesk\Uninstall RustDesk.lnk"
if (Test-Path $uninstallLnkPath) {
Remove-Item -Path $uninstallLnkPath -Force
echo "Removed original Uninstall RustDesk shortcut."
}
# Создаем BAT-файл в папке RustDesk
$uninstallBatContent | Out-File -FilePath $uninstallBatPath -Encoding ASCII
echo "Created Uninstall RustDesk.bat in $env:ProgramFiles\RustDesk"
# Копируем BAT-файл в Critical Fixes\RustDesk
Copy-Item -Path $uninstallBatPath -Destination "$startMenuPath\Uninstall RustDesk.bat" -Force
echo "Copied Uninstall RustDesk.bat to $startMenuPath"
$rustdesk_id = .\rustdesk.exe --get-id | Write-Output -OutVariable rustdesk_id
echo "All done! Please double check the Network settings tab in RustDesk."
echo ""
echo "..............................................."
echo "RustDesk ID: $rustdesk_id"
$RustID = $rustdesk_id
$ComputerName = $env:COMPUTERNAME
$InstallTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$ServerURL = "https://rd.it-depot.ru/api/install"
$Body = @{
"rust_id" = $RustID
"computer_name" = $ComputerName
"install_time" = $InstallTime
} | ConvertTo-Json -Compress
Invoke-RestMethod -Uri $ServerURL -Method Post -Body $Body -ContentType "application/json"
echo "Initial entry added to address book."
echo "..............................................."
echo ""
# Создание скрипта для проверки онлайн-статуса
$checkScriptPath = "C:\ProgramData\RustDesk\RustDeskOnlineCheck.ps1"
$checkScriptContent = @"
`$ErrorActionPreference = 'SilentlyContinue'
`$RustID = "$RustID"
`$ComputerName = "$ComputerName"
`$InstallTime = "$InstallTime"
`$ServerURL = "https://rd.it-depot.ru/api/install"
while (`$true) {
`$Body = @{
`"rust_id`" = `$RustID
`"computer_name`" = `$ComputerName
`"install_time`" = `$InstallTime
`"last_seen`" = (Get-Date -Format `"yyyy-MM-dd HH:mm:ss`")
} | ConvertTo-Json -Compress
try {
Invoke-RestMethod -Uri `$ServerURL -Method Post -Body `$Body -ContentType `"application/json`" -ErrorAction Stop
Write-Host "Online ping sent for ID `$RustID at `(Get-Date -Format 'HH:mm:ss')" -ForegroundColor Green
}
catch {
Write-Host "Error sending online ping: `$_" -ForegroundColor Red
}
Start-Sleep -Seconds 30
}
"@
$checkScriptContent | Out-File -FilePath $checkScriptPath -Encoding UTF8
echo "Created online check script at $checkScriptPath"
# Создание задания в Планировщике задач
$taskName = "RustDeskOnlineCheck"
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$checkScriptPath`""
$trigger = New-ScheduledTaskTrigger -AtStartup
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable
Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Settings $settings -User "SYSTEM" -RunLevel Highest -Force
echo "Scheduled task '$taskName' created to check online status at system startup."
Start-ScheduledTask -TaskName $taskName
echo "Scheduled task '$taskName' has been started."
echo "Press Enter to open RustDesk."
pause
.\rustdesk.exe
# CORS для веб-интерфейса
web_app.add_middleware(
CORSMiddleware,
allow_origins=["https://rd.it-depot.ru"], # Обновлено для HTTPS
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)