Что нового

выделение папок в зависимости от наличия в них нередактируемых файлов

Alexey

Новичок
Сообщения
171
Репутация
0
Версия AutoIt: 3.3.0.0

Описание: периодически возникает ситуация, когда некоторые из сотен папок содержат файлы, которые невозможно переименовать (из-за слишком длинного пути), единственный выход в таком случае - сократить название папки

мне нужно знать о наличии таких файлов, чтобы нормально перемещать папки (не хочется больше вручную просматривать папки с самыми длинными названиями)

Примечания: скрипт должен из всех выделенных папок оставить выделение только на тех, которые содержат нередактируемые файлы
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
тема актуальности не теряет. надеюсь, кто-то сможет на неё найти немного времени - мне отчего-то кажется, что тут для сведущих людей ничего сложного быть не должно

всё что я понимаю, так это то, что из этой схожей темы, видимо, надобно взять кусок кода, относящийся к Function to get the path currently being explored by a Windows Explorer window:

Код:
; ==================================================================================================
; Func _GetWindowsExplorerPath($hWnd)
;
; Function to get the path currently being explored by a Windows Explorer window
;
; $hWnd = Handle to the Windows Explorer window
;
; Returns:
;   Success: String - Path being explored by this window
;   Failure: "" empty string, with @error set:
;      @error = 1 = This is not a valid explorer window
;      @error = 2 = DLL call error, use _WinAPI_GetLastError()
;
; Author: WideBoyDixon
; ==================================================================================================
Func _GetWindowsExplorerPath($hWnd)
    Local $pv, $pidl, $return = "", $ret, $hMem, $pid, $folderPath = DllStructCreate("char[260]"), $className
    Local $bPIDL = False 						
    Local Const $CWM_GETPATH = 0x400 + 12;

    ; Check the classname of the window first
    $className = DllCall("user32.dll", "int", "GetClassName", "hwnd", $hWnd, "str", "", "int", 4096)
    If @error Then Return SetError(2, 0, "")
    If ($className[2] <> "ExploreWClass" And $className[2] <> "CabinetWClass") Then Return SetError(1, 0, "")
   
    ; Retrieve the process ID for our process
    $pid = DllCall("kernel32.dll", "int", "GetCurrentProcessId")
    If @error Then Return SetError(2, 0, "")

    ; Send the CWM_GETPATH message to the window
    $hMem = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $CWM_GETPATH, "wparam", $pid[0], "lparam", 0)
    If @error Then Return SetError(2, 0, "")
    If $hMem[0] = 0 Then Return SetError(1, 0, "")
   
    ; Lock the shared memory
    $pv = DllCall("shell32.dll", "ptr", "SHLockShared", "uint", $hMem[0], "uint", $pid[0])
    If @error Then Return SetError(2, 0, "")
    If $pv[0] Then
        $pidl = DllCall("shell32.dll", "ptr", "ILClone", "uint", $pv[0]) ; Clone the PIDL
        If @error Then Return SetError(2, 0, "")
        $bPIDL = True
        DllCall("shell32.dll", "int", "SHUnlockShared", "uint", $pv) ; Unlock the shared memory
    EndIf
    DllCall("shell32.dll", "int", "SHFreeShared", "uint", $hMem, "uint", $pid) ; Free the shared memory
   
    If $bPIDL Then
        ; Retrieve the path from the PIDL
        $ret = DllCall("shell32.dll", "int", "SHGetPathFromIDList", "ptr", $pidl[0], "ptr", DllStructGetPtr($folderPath))
        If (@error = 0) And ($ret[0] <> 0) Then $return = DllStructGetData($folderPath, 1) ; Retrieve the value
        DllCall("shell32.dll", "none", "ILFree", "ptr", $pidl[0]) ; Free up the PIDL that we cloned
        Return SetError(0, 0, $return) ; Success
    EndIf
   
    Return SetError(2, 0, "") ; Failed a WinAPI call
EndFunc

; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_PathIsDirectoryEmpty
; Description....: Determines whether a specified path is an empty directory.
; Syntax.........: _WinAPI_PathIsDirectoryEmpty ( $sPath )
; Parameters.....: $sPath  - The path to be tested.
; Return values..: Success - 1 - The path is an empty directory.
;                            0 - Otherwise.
;                  Failure - 0 and sets the @error flag to non-zero.
; Author.........: Yashied
; Modified.......:
; Remarks........: None
; Related........:
; Link...........: @@MsdnLink@@ PathIsDirectoryEmpty
; Example........: Yes
; ===============================================================================================================================

далее я могу только предположить, что скрипт должен:
- либо перебирать каждый файл в этих папках, просто получая информацию, разрешает ли система его переименовать, и в случае запрета - запоминать папку, а в конце соответствующие папки оставить выделенными
- либо находить файлы с путём свыше 255 (256 ??) (259 ?) (260 ?) символов

второй вариант видится более простым для реализации, но мне лично он совсем не нравится. хотя бы потому, что чётко не ясно, какое именно число указывать - поверхностный гуглёж ответа вразумительного не дал
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Alexey [?]
не ясно, какое именно число указывать
MAXPATH = 256. Так по крайней мере в XP.

Хотя на практике всё немного иначе. Длина включает путь к файлу, и по моим иследованиям, длина пути к файлу, имени файла, и его расширения, не должна привышать 259 символов:

Код:
$sName = @DesktopDir & "\"

For $i = 1 To 202 ;+ 1 ;если добавить 1, то файл уже не будет создан
	$sName &= "x"
Next

$sName &= ".ext"

ConsoleWrite("StringLen: " & StringLen($sName) & @LF)
ConsoleWrite("FileWrite: " & FileWrite($sName, "") & @LF)


Environment(Language:0419 Keyboard:00000409 OS:WIN_XP/Service Pack 3 CPU:X64 OS:X86)
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
только что (с помощью блокнота) проверил на своей xp sp2 pro ru - файл доступен для переименования, если его путь (включая всё) равен 259. если сделать 260, даже команда контекстного меню "переименовать" исчезает. так что и второй вариант скорее всего подходит - нужно, чтобы скрипт искал файлы с путём, содержащим 260 и более символов

впрочем, я тут подумал, что можно ставить хоть 240. всё равно это очень длинный путь и всегда не будет лишним по возможности его сократить
(ведь если сегодня файл с путём 250-259 доступен для редактирования, то завтра он вполне может быть перенесён в папку с чуть более длинным названием. так что 240 послужит своего рода страховкой на будущее)
 
Автор
A

Alexey

Новичок
Сообщения
171
Репутация
0
в справке немного по функциям прошёлся и _PathMake - одна из некоторых, привлёкшая моё внимание. но надо полагать, она здесь не поможет. ничего наподобие, к примеру, _PathCharCount мне не попалось

в поисках набрёл на одну страницу, где лаконично дают понять, насколько просто аналогичный с данной темой вопрос решается средствами сторонней программы. знать бы ещё, как с помощью Auto It это проделать
 
Верх