NTLinks + NTLinksMaker: создание и инфо о ссылках NTFS
Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер
Моя кнопка:
Тоже никаких никаких "матрёшек".
Сохранять части путей... - выключено.
Кол-во уровней... 0
Тип ссылок... 1. Точки соединения
В папке утилиты только 2 ехе, 2 ini и папка Language, в которой только Russian.lng .
NTLinksMaker.ini и NTLinksMaker64.ini одинаковые и содержат только:
[NTLinks Maker]
Language=Russian
ConfirmSymlinkElevation=1
Код: Выделить всё
TOTALCMD#BAR#DATA
NTLinksMaker64.exe
/b /sf2 /r="%P" "@%WL" "%T"
%COMMANDER_PATH%\Plugins\NTLinksMaker\NTLinksMaker64.exe
NTLinksMaker64
%COMMANDER_PATH%\Plugins\NTLinksMaker\
0
-1
Сохранять части путей... - выключено.
Кол-во уровней... 0
Тип ссылок... 1. Точки соединения
В папке утилиты только 2 ехе, 2 ini и папка Language, в которой только Russian.lng .
NTLinksMaker.ini и NTLinksMaker64.ini одинаковые и содержат только:
[NTLinks Maker]
Language=Russian
ConfirmSymlinkElevation=1
TC 11.58 32/64, Win10x64
Cuda уехал text, он был ещё вчераа...
Cuda уехал text, он был ещё вчераа...
Дело не в дедукции. Нужно воспроизвести проблему, а сделать это не получается.Destiny писал(а):Просто дедукция тут не поможет
Вы пробовали на чистом ТС и чистом NTLinksMaker без ini? Это минутное дело.
Если и там есть проблема, то только с правами и системой безопасности самой винды разбираться надо, наверное.
Ну мы же не знаем ЧЕМ оперирует утилита, когда создает эти объекты?
Когда я делаю "вроде бы тоже", но через утилиту mklink - то никаких матрешек нет.
А значит права ОС, безопасность и что-то типа этого - не при делах.
на пустом ТС и тока с одним ехе утилиты - всё 64 бит пробовал - та же матрешка.
Версия если что 1.4.2.436. А то вдруг я пропустил какое-то обновление)))
ini файлов от утилиты кстати у меня нет. Вообще нигде.
И тестить прошу только 3 вариант из комбобокса выбора - Симлинки.
Когда я делаю "вроде бы тоже", но через утилиту mklink - то никаких матрешек нет.
А значит права ОС, безопасность и что-то типа этого - не при делах.
на пустом ТС и тока с одним ехе утилиты - всё 64 бит пробовал - та же матрешка.
Версия если что 1.4.2.436. А то вдруг я пропустил какое-то обновление)))
ini файлов от утилиты кстати у меня нет. Вообще нигде.
И тестить прошу только 3 вариант из комбобокса выбора - Симлинки.

Вот тоже наткнулся на явную ошибку формирования GUI самописного диалога.
И еще другая ошибка. Берете и удаляете в поле "Создать ссылки для..." имя сопсно будущей ссылки. Оставьте там лишь родительскую папку\.
И что? А ничего - диалог просто закроется((( Причем сломалось что-то там или выполнилось удачно - ничего не известно и не понятно.
Добавлено спустя 7 минут:
Orion9
О! кстати - вы же вроде писали как-то, что у вас получилось от ИИ что-то полезное заполучить?
А можете просто вот проверить идею создания схожей программы в рамках питоновского скрипта, к примеру?
Я б потестил))))
Так он же явно пишет, что файл существует, поэтому ссылка не может быть создана. Можно добавить на конец что-нибудь типа _1 и посмотреть, что получится и где.Destiny писал(а): Вот тоже наткнулся на явную ошибку формирования GUI самописного диалога.
Так ведь для ссылки нужно имя указать, без этого не будет работать. Например .\ не работает, а .\test или ..\test работает.Destiny писал(а):И еще другая ошибка. Берете и удаляете в поле "Создать ссылки для..." имя сопсно будущей ссылки. Оставьте там лишь родительскую папку\.
Получалось. И не раз )Destiny писал(а):вы же вроде писали как-то, что у вас получилось от ИИ что-то полезное заполучить?
Ну, на счет питоновского скрипта не знаю (нет возможности проверить), а для Autohotkey 2 пожалуйстаDestiny писал(а): А можете просто вот проверить идею создания схожей программы в рамках питоновского скрипта, к примеру?
[cut]
Код: Выделить всё
#Requires AutoHotkey v2.0
#SingleInstance Force
; Проверяем права администратора (они нужны ТОЛЬКО для символических ссылок)
if !A_IsAdmin {
MsgBox("Внимание: Создание СИМВОЛИЧЕСКИХ ссылок требует прав администратора.`nСкрипт будет перезапущен с повышенными правами.", "Инфо", "IconInformation")
Run('*RunAs "' A_ScriptFullPath '"')
ExitApp
}
; Создаем GUI
MyGui := Gui("+AlwaysOnTop", "NTFS Ссылки через DllCall")
MyGui.SetFont("s10", "Segoe UI")
MyGui.AddText("w300", "Выберите тип ссылки:")
RadioHard := MyGui.AddRadio("vLinkType Checked", "Жесткая ссылка (Файл -> Файл)")
RadioSymFile := MyGui.AddRadio("", "Символическая ссылка (Файл -> Файл)")
RadioSymDir := MyGui.AddRadio("", "Символическая ссылка (Папка -> Папка)")
RadioJunction := MyGui.AddRadio("", "Точка соединения / Junction (Папка -> Папка)")
MyGui.AddText("w300 xs y+15", "Путь к оригиналу (Target):")
EditTarget := MyGui.AddEdit("w350 vTarget")
BtnSelectTarget := MyGui.AddButton("x+5 w50", "...")
MyGui.AddText("w300 xs y+15", "Путь для новой ссылки (Link):")
EditLink := MyGui.AddEdit("w350 vLink")
BtnSelectLink := MyGui.AddButton("x+5 w50", "...")
BtnCreate := MyGui.AddButton("xs y+20 w405 Default", "Создать ссылку через API")
; Привязка событий
BtnSelectTarget.OnEvent("Click", SelectTarget)
BtnSelectLink.OnEvent("Click", SaveLink)
BtnCreate.OnEvent("Click", ActionCreateLink)
MyGui.Show()
; --- ФУНКЦИИ ВЫБОРА ПУТЕЙ ---
SelectTarget(*) {
GuiValues := MyGui.Submit(false)
if (GuiValues.LinkType >= 3)
Selected := DirSelect(, 3, "Выберите исходную папку")
else
Selected := FileSelect(3,, "Выберите исходный файл")
if Selected
EditTarget.Value := Selected
}
SaveLink(*) {
GuiValues := MyGui.Submit(false)
if (GuiValues.LinkType >= 3)
Selected := DirSelect(, 3, "Выберите, где создать папку-ссылку")
else
Selected := FileSelect("S16",, "Сохранить ссылку как")
if Selected
EditLink.Value := Selected
}
; --- ОСНОВНАЯ ЛОГИКА DLLCALL ---
ActionCreateLink(*) {
GuiValues := MyGui.Submit(false)
if (GuiValues.Target == "" || GuiValues.Link == "") {
MsgBox("Заполните оба поля!", "Ошибка", "IconExclamation")
return
}
Result := 0
switch GuiValues.LinkType {
case 1: ; Жесткая ссылка (Hard Link) на файл
; CreateHardLinkW(lpFileName, lpExistingFileName, lpSecurityAttributes)
Result := DllCall("CreateHardLinkW", "Str", GuiValues.Link, "Str", GuiValues.Target, "Ptr", 0, "Int")
case 2: ; Символическая ссылка на файл
; CreateSymbolicLinkW(lpSymlinkFileName, lpTargetFileName, dwFlags)
; Флаг 0x0 = Файл, Флаг 0x2 = Разрешить несвежие пути (SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE если включен DevMode)
Result := DllCall("CreateSymbolicLinkW", "Str", GuiValues.Link, "Str", GuiValues.Target, "UInt", 0x0, "UChar")
case 3: ; Символическая ссылка на папку
; Флаг 0x1 = Каталог
Result := DllCall("CreateSymbolicLinkW", "Str", GuiValues.Link, "Str", GuiValues.Target, "UInt", 0x1, "UChar")
case 4: ; Точка соединения (Junction)
; Флаг 0x1 (каталог) + 0x2 (создание виртуального имени/свойства связи) = 0x3
Result := DllCall("CreateSymbolicLinkW", "Str", GuiValues.Link, "Str", GuiValues.Target, "UInt", 0x3, "UChar")
}
if (Result != 0) {
MsgBox("Ссылка успешно создана через Win32 API!", "Успех", "IconInformation")
EditTarget.Value := ""
EditLink.Value := ""
} else {
; Получаем код ошибки Windows, если API вернул 0 (неудача)
ErrorCode := A_LastError
MsgBox("Ошибка API! Не удалось создать ссылку.`nКод ошибки Windows (System Error Code): " ErrorCode, "Ошибка", "IconStop")
}
}Я проверил. Работает. Только имена ссылкам нужно давать в поле для новой ссылки.
А что мешает? [s]Человек болвану друг, это знают все вокруг[/s] Болван - друг человекаDestiny писал(а): Я б потестил))))
[cut]
Код: Выделить всё
import sys
import ctypes
from tkinter import Tk, Label, Button, Radiobutton, Entry, StringVar, IntVar, messagebox, filedialog
# Проверка прав администратора (символические ссылки требуют повышенных прав)
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if not is_admin():
# Перезапускаем скрипт с правами администратора
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
sys.exit()
# Инициализация главного окна GUI
root = Tk()
root.title("NTFS Ссылки через Win32 API")
root.geometry("450x380")
root.resizable(False, False)
# Переменные для хранения путей и выбора типа ссылки
link_type = IntVar(value=1)
target_path = StringVar()
link_path = StringVar()
# --- ФУНКЦИИ ВЫБОРА ПУТЕЙ ---
def select_target():
if link_type.get() >= 3:
selected = filedialog.askdirectory(title="Выберите исходную папку")
else:
selected = filedialog.askopenfilename(title="Выберите исходный файл")
if selected:
target_path.set(selected.replace("/", "\"))
def select_link():
if link_type.get() >= 3:
selected = filedialog.askdirectory(title="Выберите, где создать папку-ссылку")
else:
selected = filedialog.asksaveasfilename(title="Сохранить ссылку как")
if selected:
link_path.set(selected.replace("/", "\"))
# --- ОСНОВНАЯ ЛОГИКА WIN32 API ---
def create_link():
target = target_path.get()
link = link_path.get()
if not target or not link:
messagebox.showwarning("Ошибка", "Заполните оба поля!")
return
result = 0
t_type = link_type.get()
# Вызовы Win32 API функций через ctypes
if t_type == 1:
# CreateHardLinkW(lpFileName, lpExistingFileName, lpSecurityAttributes)
result = ctypes.windll.kernel32.CreateHardLinkW(link, target, None)
elif t_type == 2:
# CreateSymbolicLinkW(lpSymlinkFileName, lpTargetFileName, dwFlags) | 0x0 = Файл
result = ctypes.windll.kernel32.CreateSymbolicLinkW(link, target, 0x0)
elif t_type == 3:
# 0x1 = Символическая ссылка на каталог
result = ctypes.windll.kernel32.CreateSymbolicLinkW(link, target, 0x1)
elif t_type == 4:
# 0x3 = Точка соединения / Junction (Каталог + Виртуальное имя)
result = ctypes.windll.kernel32.CreateSymbolicLinkW(link, target, 0x3)
if result != 0:
messagebox.showinfo("Успех", "Ссылка успешно создана через Win32 API!")
target_path.set("")
link_path.set("")
else:
# Получаем код ошибки Windows
error_code = ctypes.windll.kernel32.GetLastError()
messagebox.showerror("Ошибка API", f"Не удалось создать ссылку.\nКод ошибки Windows (System Error Code): {error_code}")
# --- ИНТЕРФЕЙС (WIDGETS) ---
Label(root, text="Выберите тип ссылки:", font=("Segoe UI", 10, "bold")).pack(anchor="w", px=15, py=5)
Radiobutton(root, text="Жесткая ссылка (Файл -> Файл)", variable=link_type, value=1).pack(anchor="w", px=20)
Radiobutton(root, text="Символическая ссылка (Файл -> Файл)", variable=link_type, value=2).pack(anchor="w", px=20)
Radiobutton(root, text="Символическая ссылка (Папка -> Папка)", variable=link_type, value=3).pack(anchor="w", px=20)
Radiobutton(root, text="Точка соединения / Junction (Папка -> Папка)", variable=link_type, value=4).pack(anchor="w", px=20)
# Поле Target
Label(root, text="Путь к оригиналу (Target):", font=("Segoe UI", 10)).pack(anchor="w", px=15, py=(15, 0))
target_frame = Entry(root, textvariable=target_path, width=45)
target_frame.pack(side="top", anchor="w", px=15, ipy=3)
Button(root, text="...", command=select_target, width=5).place(x=390, y=183)
# Поле Link
Label(root, text="Путь для новой ссылки (Link):", font=("Segoe UI", 10)).pack(anchor="w", px=15, py=(15, 0))
link_frame = Entry(root, textvariable=link_path, width=45)
link_frame.pack(side="top", anchor="w", px=15, ipy=3)
Button(root, text="...", command=select_link, width=5).place(x=390, y=253)
# Кнопка создания
Button(root, text="Создать ссылку через API", command=create_link, font=("Segoe UI", 10, "bold"), bg="#e1e1e1", width=47).pack(anchor="w", px=15, py=25)
root.mainloop()Дык я же старался ЧЕТКО указать, что пишу проблему формирования GUI диалога, а не сути сообщения об ошибке.Orion9 писал(а):Так он же явно пишет, что файл существует, поэтому ссылка не может быть создана. Можно добавить на конец что-нибудь типа _1 и посмотреть, что получится и где.
ВИЗУАЛ там накрылся тазом!
Так я же акцент делал не на том, ЧТО неправильно сделал, а что защиты от дурака в программе НЕТ.Orion9 писал(а):Так ведь для ссылки нужно имя указать, без этого не будет работать. Например .\ не работает, а .\test или ..\test работает.
Вот нажал я ОК в диалоге и что? Никаких проверок там нет что ли? Почему диалог просто закрылся и всё?
Кстати - если укажите объект, что существует - и получите этот диалог со сломанным GUI.
Autohotkey я как-то не очень.... понимаю и не очень... уважаю(((
Попробуйте лучше задать вашем болванчику переделку на питон - вот это я бы посмотрел...
А где гарантии, что клавиша не была нажата два раза? Или что диалог не был запущен в автоматическом режиме?Destiny писал(а):пишу проблему формирования GUI диалога
Ошибка вполне конкретная: "файл уже существует". Т.е. невозможно создать символическую ссылку с таким именем, поскольку это имя уже занято.
Выходит, что нет.Destiny писал(а): защиты от дурака в программе НЕТ.
У вас тоже режим ИИ в гугле не работает? Я один что ли такой счастливый?Destiny писал(а):Попробуйте лучше задать вашем болванчику переделку на питон
P.S.
Вы утилиту NTLinks Maker от CaptainFlint пробовали? Там правда симлинки на файлы нельзя создавать, но чисто для проверки.
Работает. Но те пару попыток, что я сделал в попытке перевести на питон - привели к куче сообщений об ошибках, которые Болван сам решить в одно мгновение не смог.Orion9 писал(а):У вас тоже режим ИИ в гугле не работает?
Не думаю, что его можно в таком случае использовать на постоянку.
еще раз - речь о проблемах в GUI! Где там белая/серая/белая зоны? Зачем это деление? Где там кнопки? Особенно четвертая, вышедшая за все границы... Вы вообще такую последовательность видели кнопок? Я так точно нет.Orion9 писал(а):А где гарантии, что клавиша не была нажата два раза? Или что диалог не был запущен в автоматическом режиме?
Ошибка вполне конкретная: "файл уже существует". Т.е. невозможно создать символическую ссылку с таким именем, поскольку это имя уже занято.
Явно какой-то офигенно особенный диалог, создаваемый в попытке сделать переход на новый стиль какой-то винды? Но не вышедший в серию?
да, работает в меру своих заявленных возможностей.Orion9 писал(а):Вы утилиту NTLinks Maker от CaptainFlint пробовали?
Сложные готовые решения он выдать не сможет, за такое удовольствие нужно платить) Но если заказывать небольшими частями, он лучше справляется.Destiny писал(а): Не думаю, что его можно в таком случае использовать на постоянку.
Код на Питоне, который был выше, работает? Вроде он повторяет код на AHK, а тот код рабочий (я проверял).
Видел. У меня такие же )Destiny писал(а):Где там кнопки? Особенно четвертая, вышедшая за все границы... Вы вообще такую последовательность видели кнопок?
Видимо автор использовал свой Dialog Box, поэтому так. Но суть в ошибке. Объект существует, поэтому создать ссылку с таким именем нельзя.