Proje içerisinde yer alan başlıca fonksiyonlar ve işlevleri aşağıda detaylandırılmıştır:
Özellikler:
- Menü Ekleme: Yeni bir menü adı, komut ve isteğe bağlı ikon yolu ile sağ tıklama menüsüne öğe eklenebilir.
- Menü Düzenleme: Mevcut menü öğeleri düzenlenebilir, komut ve ikon değiştirilebilir.
- Menü Silme: Sağ tıklama menüsünden mevcut öğeler kolayca silinebilir.
- Menü Listeleme: Uygulamanın ana sayfasında, eklenmiş tüm sağ tıklama menü öğeleri listelenir.
Kurulum ve Kullanım Talimatları:
Gerekli Kütüphaneler:
- Flask
- Flask-CORS
- winreg (Windows Kayıt Defteri yönetimi için)
- ctypes (Yönetici yetkisi gerektiren işlemler için)
\"Main.py\" Dosyası
from flask import Flask, render_template, request, jsonify, redirect, url_for, flash
import os
import winreg as reg
import ctypes
import sys
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # Enable CORS
# Yönetici izni kontrol fonksiyonu
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
# Yönetici izni talep fonksiyonu
def run_as_admin():
if is_admin():
app.run(debug=True)
else:
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, "main.py", None, 1) # main.py yerine dosya adınızı yazın
sys.exit()
# Sağ tıklama menüsüne eklenen tüm öğeleri almak için fonksiyon
def get_context_menu_items():
items = []
base_path = r"Directory\\Background\\shell"
try:
key = reg.OpenKey(reg.HKEY_CLASSES_ROOT, base_path)
for i in range(reg.QueryInfoKey(key)[0]):
item = reg.EnumKey(key, i)
command_key = reg.OpenKey(key, item + r"\\command")
command = reg.QueryValueEx(command_key, None)[0]
icon_key = reg.OpenKey(key, item)
try:
icon = reg.QueryValueEx(icon_key, "Icon")[0]
except:
icon = None
# Varsayılan değer (menü adı) alınması
name = reg.QueryValueEx(icon_key, None)[0] # Varsayılan değer olarak menü adı
items.append({
'name': name, # Menü adını varsayılan değer olarak ayarladık
'command': command,
'icon': icon
})
reg.CloseKey(key)
except Exception as e:
print(f"Hata: {e}")
return items
# Yeni menü ekleme ve ana sayfa
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
menu_name = request.form['menu_name']
command = request.form['command']
icon_path = request.form['icon_path']
# Sağ tıklama menüsüne yeni öğe ekle
add_to_context_menu(menu_name, command, icon_path)
return redirect(url_for('index'))
# Mevcut tüm sağ tıklama menülerini listele
items = get_context_menu_items()
return render_template('index.html', items=items)
# Sağ tıklama menüsüne kayıt eklemek için fonksiyon
def add_to_context_menu(menu_name, command, icon_path):
try:
key_path = r"Directory\\Background\\shell\\" + menu_name
key = reg.CreateKey(reg.HKEY_CLASSES_ROOT, key_path)
reg.SetValueEx(key, None, 0, reg.REG_SZ, menu_name)
if icon_path:
reg.SetValueEx(key, "Icon", 0, reg.REG_SZ, icon_path)
command_key = reg.CreateKey(key, r"command")
reg.SetValueEx(command_key, None, 0, reg.REG_SZ, command)
reg.CloseKey(key)
reg.CloseKey(command_key)
except Exception as e:
print(f"Hata: {e}")
@app.route('/delete/<menu_name>', methods=['POST'])
def delete_menu(menu_name):
response = {}
try:
key_path = r"Directory\\Background\\shell\\" + menu_name
# Anahtarın mevcut olup olmadığını kontrol et
try:
reg.OpenKey(reg.HKEY_CLASSES_ROOT, key_path)
except FileNotFoundError:
response = {'status': 'error', 'message': 'Menü öğesi bulunamadı!'}
print(response)
return jsonify(response)
# Anahtarı sil
reg.DeleteKey(reg.HKEY_CLASSES_ROOT, key_path + r"\\command")
reg.DeleteKey(reg.HKEY_CLASSES_ROOT, key_path)
response = {'status': 'success', 'message': 'Menü öğesi başarıyla silindi!'}
print(response)
return jsonify(response)
except Exception as e:
response = {'status': 'error', 'message': str(e)}
print(response)
return jsonify(response)
# Menü öğesini düzenleme fonksiyonu
@app.route('/edit', methods=['POST'])
def edit_menu():
old_name = request.form['old_name']
new_name = request.form['menu_name']
command = request.form['command']
icon_path = request.form['icon_path']
# Önceki menüyü silip yenisini ekle
delete_menu(old_name)
add_to_context_menu(new_name, command, icon_path)
return redirect(url_for('index'))
if __name__ == '__main__':
run_as_admin()
\"templates/index.html\" dosyası
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sağ Menü Düzenleyici</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.2/dist/js/bootstrap.bundle.min.js"></script>
<style>
* {
cursor: default; /* Set cursor to default for all elements */
}
body {
font-family: 'Roboto', sans-serif;
background: #121213; /* Dark background */
color: #f8f9fa; /* Light text color */
padding: 30px;
}
.container {
background: #1e1e1e; /* Dark background */
padding: 40px;
border-radius: 15px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
}
input.form-control,
textarea.form-control {
background-color: #121213; /* Input and textarea background color */
color: #f8f9fa; /* White text color */
border: 1px solid #343a40; /* Border color */
}
input.form-control::placeholder,
textarea.form-control::placeholder {
color: #b0b3b8; /* Placeholder color */
}
input.form-control:focus,
textarea.form-control:focus {
background-color: #121213; /* Keep dark background on focus */
color: #f8f9fa; /* Keep white text on focus */
border-color: #6a11cb; /* Border color on focus */
box-shadow: none; /* Remove box-shadow */
}
.list-group-item {
border: none;
padding: 20px;
transition: background 0.3s;
background-color: #0e0e0e; /* Dark background */
color: white; /* White text color */
}
.list-group-item:hover {
background: #495057; /* Lighter background on hover */
}
.btn-custom,
.btn-info,
.btn-warning,
.btn-danger {
background-color: #121212; /* Button background color */
color: white; /* White text color */
border: 1px solid #343a40; /* Border color */
cursor: default !important; /* Set cursor to default */
}
button {
cursor: default !important; /* Ensure default cursor for buttons */
}
.btn-custom:hover,
.btn-info:hover,
.btn-warning:hover,
.btn-danger:hover {
background-color: #1e1e1e; /* Lighter background on hover */
color: white;
cursor: default !important; /* Ensure cursor stays default on hover */
}
.modal-content {
background-color: #272525; /* Modal background color */
}
.close {
float: right;
font-size: 1.5rem;
font-weight: 700;
line-height: 1;
color: #ffffff;
text-shadow: 0 1px 0 #fff;
}
/* Custom tooltip styles */
.tooltip-inner {
background-color: #000; /* Black background */
color: #fff; /* White text */
}
.tooltip-arrow {
border-top-color: #000; /* Black arrow */
}
</style>
</head>
<body>
<div class="container">
<h2 class="text-center">Sağ Tıklama Menüsü Yönetimi</h2>
<hr>
<form method="POST" action="/">
<div class="form-group">
<label for="menu_name">Menü Adı:</label>
<input type="text" class="form-control" id="menu_name" name="menu_name" required>
</div>
<div class="form-group">
<label for="command">Komut:</label>
<input type="text" class="form-control" id="command" name="command" required>
</div>
<div class="form-group">
<label for="icon_path">İkon Yolu:</label>
<input type="text" class="form-control" id="icon_path" name="icon_path" placeholder="Opsiyonel">
</div>
<button type="submit" class="btn btn-custom" title="Menüyü eklemek için tıklayın" data-toggle="tooltip">Menüye Ekle</button>
<button class="btn btn-info ml-2" data-toggle="modal" data-target="#commandsModal" title="Komutlar listesini görüntülemek için tıklayın" data-toggle="tooltip">Komutlar Listesi</button>
</form>
<hr>
<h3>Mevcut Menü Öğeleri</h3>
<ul class="list-group">
{% for item in items %}
<li class="list-group-item">
<strong>{{ item.name }}</strong> - {{ item.command }}
{% if item.icon %}
<img src="{{ item.icon }}" class="icon-preview" alt="icon">
{% endif %}
<button class="btn btn-warning btn-sm float-right ml-2" data-toggle="modal" data-target="#editModal"
data-name="{{ item.name }}" data-command="{{ item.command }}" data-icon="{{ item.icon }}" title="Menü öğesini düzenlemek için tıklayın" data-toggle="tooltip">
Düzenle
</button>
<button class="btn btn-danger btn-sm float-right" onclick="deleteMenu('{{ item.name }}')" title="Menü öğesini silmek için tıklayın" data-toggle="tooltip">Sil</button>
</li>
{% endfor %}
</ul>
</div>
<!-- Edit Modal -->
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="editModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editModalLabel">Menü Öğesini Düzenle</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span>×</span>
</button>
</div>
<div class="modal-body">
<form id="editForm">
<div class="form-group">
<label for="edit_menu_name">Menü Adı:</label>
<input type="text" class="form-control" id="edit_menu_name" name="menu_name" required>
</div>
<div class="form-group">
<label for="edit_command">Komut:</label>
<input type="text" class="form-control" id="edit_command" name="command" required>
</div>
<div class="form-group">
<label for="edit_icon_path">İkon Yolu:</label>
<input type="text" class="form-control" id="edit_icon_path" name="icon_path" placeholder="Opsiyonel">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Kapat</button>
<button type="button" class="btn btn-primary" id="saveChanges">Değişiklikleri Kaydet</button>
</div>
</div>
</div>
</div>
<script>
// Menü silme fonksiyonu
function deleteMenu(menuName) {
// Confirm deletion with the user
Swal.fire({
title: 'Silmek istediğinize emin misiniz?',
text: "Bu işlem geri alınamaz!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: 'Evet, sil!',
cancelButtonText: 'Hayır'
}).then((result) => {
if (result.isConfirmed) {
// Send the delete request
$.ajax({
url: '/delete/' + encodeURIComponent(menuName), // URL-encode the menu name
type: 'POST', // Set the request type to POST
success: function(response) {
console.log('Response:', response); // Log the response for debugging
if (response.status === 'success') {
Swal.fire('Silindi!', response.message, 'success').then(() => {
location.reload(); // Refresh the page to remove the deleted item
});
} else {
Swal.fire('Hata!', response.message, 'error');
}
},
error: function(xhr, status, error) {
console.error('AJAX Error:', xhr, status, error); // Log AJAX errors for debugging
Swal.fire('Hata!', 'Bir hata oluştu!', 'error');
}
});
}
});
}
// Edit modal data binding
$('#editModal').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget);
var name = button.data('name');
var command = button.data('command');
var icon = button.data('icon');
var modal = $(this);
modal.find('#edit_menu_name').val(name);
modal.find('#edit_command').val(command);
modal.find('#edit_icon_path').val(icon);
});
// Save changes after editing
$('#saveChanges').click(function() {
var name = $('#edit_menu_name').val();
var command = $('#edit_command').val();
var icon = $('#edit_icon_path').val();
// Send the updated data to the server
$.ajax({
url: '/edit/' + encodeURIComponent(name), // URL-encode the menu name
type: 'POST',
data: {
command: command,
icon_path: icon
},
success: function(response) {
console.log('Response:', response);
if (response.status === 'success') {
Swal.fire('Başarılı!', response.message, 'success').then(() => {
location.reload(); // Reload the page to show updated data
});
} else {
Swal.fire('Hata!', response.message, 'error');
}
},
error: function(xhr, status, error) {
console.error('AJAX Error:', xhr, status, error);
Swal.fire('Hata!', 'Bir hata oluştu!', 'error');
}
});
});
// Initialize tooltips
$(function () {
$('[data-toggle="tooltip"]').tooltip();
});
</script>
</body>
</html>