Total Commander Knowledge Base

Есть вопрос?

Поищите ответ в самой большой русскоязычной базе знаний по Total Commander!

Работа с MIME, UUE, XXE

Q: В Total Comander есть команда cm_Encode для разового использования, с одним файлом она вполне приемлема.
Но для удобства автоматизации интересует пакетное кодирование и декодирование сразу нескольких файлов с теми же именами, что и оригиналы.
A: VBS-скрипт (см. описание в шапке):
'==========================================================
' Кодировать/декодировать выбранные файлы в/из MIME (b64)
' Параметры: %WL "<путь получателя>" <упаковывать в zip: 1>
' Примеры:   %WL "%P"  |  %WL "%T" 1  |  %WL C:|Test 1
' Автор:  Flasher ©
'==========================================================
With WScript.Arguments
  C = .Count : If C = 0 Then WScript.Quit
  List = .Item(0) : Path = .Item(1)
End With : L = vbNewLine : Const M = 1
If Right(Path, 1) <> "\" Then Path = Path & "\"
Set XML    = CreateObject("MSXml2.DOMDocument")
Set FSO    = CreateObject("Scripting.FileSystemObject")
Set Stream = CreateObject("ADODB.Stream") : Stream.Type = 1
If C = 3 Then
  Set Shell = CreateObject("Shell.Application")
  Exts = "7z|7zip|zip|rar|cab|bzip|bz2|bzip2|arj|tar|gz|tgz"
  Temp = CreateObject("WScript.Shell").Environment("Process")("TEMP") & "\"
End If
For Each F in Split(FSO.GetFile(List).OpenAsTextStream(1, -1).ReadAll, L)
  If FSO.FileExists(F) Then
    If StrComp(FSO.GetExtensionName(F), "b64", 1) = 0 Then
      Set OF = FSO.OpenTextFile(F) : Code = OF.ReadAll : OF.Close
      LL = InStr(Code, L & L) : NN = InStr(Code, "filename=") + 10
      Set DE = XML.CreateElement("tmp") : DE.Text = Mid(Code, LL + 4)
      Stream.Open : DE.DataType = "bin.base64" : Stream.Write DE.NodeTypedValue
      Name = Mid(Code, NN, LL - NN - 1) : Rename Name
      Stream.SaveToFile Path & Name, 2
      Stream.Close : Set DE = Nothing : Set OF = Nothing
    Else
      If C = 3 Then
        If InStr(Exts, LCase(FSO.GetExtensionName(F))) = 0 Then
          NF = Temp & FSO.GetBaseName(F) & ".zip" : Set ZIP = FSO.CreateTextFile(NF)
          ZIP.Close : Set ZIP = Nothing
          Set IZIP = FSO.CreateTextFile(Temp & FSO.GetFileName(F))
          IZIP.Close
          Set ArchDir = Shell.NameSpace(NF)
          ArchDir.MoveHere(IZIP) : ArchDir.CopyHere F, 20
          Set IZIP = Nothing
          Size = 0 : Set AF = ArchDir.ParseName(FSO.GetFileName(F))
          Do While Err.Number = 424 And Size <> FSO.GetFile(F).Size : Err.Number = 0
            Set AF = ArchDir.ParseName(FSO.GetFileName(F)) : Size = AF.Size
          Loop : On Error Goto 0
          WScript.Sleep 10 : Set AF = Nothing : Set ArchDir = Nothing : F = NF
        End If
      End If
      Stream.Open : Stream.LoadFromFile(F)
      XML.LoadXML "<Base64Data />" : Set E = XML.documentElement
      E.DataType = "bin.base64" : E.NodeTypedValue = Stream.Read
      Stream.Close : Name = FSO.GetFileName(F)
      FName = FSO.GetBaseName(Name) & ".b64" : Rename FName
      Set File = FSO.OpenTextFile(Path & FName, 2, True)
      File.Write "MIME-Version: 1.0" & L & _
      "Content-Type: application/octet-stream; name=""" & Name & """" & L & _
      "Content-Transfer-Encoding: base64" & L & _
      "Content-Disposition: attachment; filename=""" & Name & """" & L & L & E.Text
      File.Close : Set E = Nothing : If C = 3 Then FSO.DeleteFile F, 1
    End If
  End If
Next : Set XML = Nothing : Set FSO = Nothing
Set Stream = Nothing : Set Shell = Nothing : WScript.Quit

Sub Rename(FileName)
  FN = FileName : n = 0
  Do While FSO.FileExists(Path & FileName)
    n = n + 1
    If l < 10^M Then PFix = Right(String(M, "0") & n, M) Else PFix = n
    FileName = FSO.GetBaseName(FN) & " (" & PFix & ")." & FSO.GetExtensionName(FN)
  Loop
End Sub

Flasher
14.12.2014

Q: Возникла идея. Новый скрипт должен:

1. Проверять буфер обмена, если в буфере есть кодированный текст - раскодировать его в активную панель.
2. Если в буфере текст некодированный, то скрипт проверяет файл под курсором. Если файл кодированный, то - раскодирует его в активную панель.

3. Если файл под курсором некодированный, то он кодируется в активную панель.

A: Решение на базе утилит UUDeview и UUEnview (VBScript, описание в шапке):
'================================================================
' 1) Получение в текущей папке файла из кодированного текста
'    буфера обмена вида Base64/MIME/UUE/XXE/BinHex
' 2) Если в буфере нет соотв. кода,
'    то кодировать/декодировать выбранные файлы в панели

' Условие: путь запуска - пустой

' Параметры: %WL <расширение кодировки> <флаг упаковки в zip: 1>

' Возможные расширения кодирования: b64, xxe, uue

' Автор - Flasher ©
'======================= Путь к UUDeView ========================
UUDev = """%COMMANDER_PATH%\Utils\uudeview\uudeview.exe"""
'======================= Путь к UUEnView ========================
UUEnv = """%COMMANDER_PATH%\Utils\uudeview\uuenview.exe"""
'======================== Путь к TCFS2 ==========================
TCFS2 = """%COMMANDER_PATH%\Utils\TCFS2\TCFS2.exe"""
'================================================================
L = vbNewLine
Set SHA = CreateObject("Shell.Application")
Dim WSH : Set WSH = CreateObject("WScript.Shell")
Set FSO = CreateObject("Scripting.FileSystemObject")
P = "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3\1407"
On Error Resume Next
A = WSH.RegRead(P) : If Err.Number <> 0 OR A > 0 Then WSH.RegWrite P, 0, "REG_DWORD"
Clip = Trim(CreateObject("htmlfile").ParentWindow.ClipboardData.GetData("text"))
On Error GoTo 0 : Temp = SHA.NameSpace(WSH.ExpandEnvironmentStrings("%TEMP%")).Self.Path
If Clip <> "" Then
  Clip = Replace(Replace(Clip, " " & L, L), L & " ", L) : Search = InStr(Clip, "begin ")
  If (Search And IsNumeric(Mid(Clip, Search + 8, 2))) Or InStr(Clip, L & "Content-Transfer-Encoding:") Then
    File = Temp & "\" & FSO.GetTempName
    Set F = FSO.OpenTextFile(File, 2, True) : F.Write Trim(Clip) : Set SHA = Nothing : F.Close
    WSH.Run UUDev & " -i -m +o -c """ & File & """", 0, True : WSH.Exec(TCFS2 & " /ef tcm(540)")
    With CreateObject("InternetExplorer.Application")
      .Navigate("about:blank") : .document.parentWindow.clipboardData.setData "text", ""
      .ExecWB 45, 2 : .Quit
    End With : If A > 0 Then WSH.RegWrite P, A, "REG_DWORD"
    Quit
  End If
End If
With WScript.Arguments
  C = .Count : If C = 0 Then Quit
  List = .Item(0) : If C > 1 Then Ext = .Item(1) Else Ext = " "
End With
Do Until Ext = "b64" Or Ext = "xxe" Or Ext = "uue"
  Ext = InputBox(L & "Введите одно из расширений формата возможного кодирования:" & L & _
  "b64, uue, xxe","Кодирование") : If Trim(Ext) = "" Then Quit
Loop : E = "7z|7zip|zip|rar|arc|cab|nz|pea|bz|bzip|bz2|bzip2|arj|tar|gz|gza|gzi|pzip|tgz|ace|uc2"
Select Case Ext
  Case "b64" : Code = " -b " : Case "uue" : Code = " -u " : Case "xxe" : Code = " -x "
End Select
For Each F in Split(FSO.GetFile(List).OpenAsTextStream(1, -1).ReadAll, L)
  If FSO.FileExists(F) Then
    Set File = FSO.GetFile(F).OpenAsTextStream(1, -2) : RF = File.ReadAll
    If InStr(RF, L & "begin ") Or InStr(RF, L & "Content-Transfer-Encoding:") Or _
    InStr(RF, L & "_=_ Part ") Then
      WSH.Run UUDev & " -i -m +o """ & F & """", 0, True
    Else
      If C = 3 Then
        If InStr(E, LCase(FSO.GetExtensionName(F))) = 0 Then
          NF = Temp & "\" & FSO.GetBaseName(F) & ".zip" : Set ZIP = FSO.CreateTextFile(NF)
          ZIP.Close : Set ZIP = Nothing
          Set ArchDir = SHA.NameSpace(NF) : ArchDir.CopyHere F, 20
          Size = 0 : Set AF = ArchDir.ParseName(FSO.GetFileName(F))
          On Error Resume Next : Err.Number = 424
          Do While Err.Number = 424 And Size <> FSO.GetFile(F).Size : Err.Number = 0
            Set AF = ArchDir.ParseName(FSO.GetFileName(F)) : Size = AF.Size
          Loop : On Error Goto 0
          WScript.Sleep 10 : Set AF = Nothing : Set ArchDir = Nothing : F = NF
        End If
      End If : WSH.Run UUEnv & Code & "-o """ & F & """", 0, True
      N = FSO.GetFileName(F) : BN = FSO.GetBaseName(F) : NF = BN & "." & Ext
      If Not FSO.FileExists(NF) Then FSO.GetFile(BN & ".001").Name = NF
      If Ext = "b64" Then
        FN = WSH.CurrentDirectory & "\" & NF : Set CF = FSO.OpenTextFile(FN) : CF.SkipLine
        If CF.ReadLine = "_=_ " Then
          Base = CF.ReadAll : CF.Close : Set CF = Nothing : Set CF = FSO.OpenTextFile(FN, 2)
          CF.Write "MIME-Version: 1.0" & L & _
          "Content-Type: application/octet-stream; name=""" & N & """" & L & _
          "Content-Transfer-Encoding: base64" & L & _
          "Content-Disposition: attachment; filename=""" & N & """" & L & L & _
          Mid(Base, InStr(Base, L & L) + 4)
        End If : CF.Close : Set CF = Nothing : If C = 3 Then FSO.DeleteFile F
      End If
    End If : File.Close : Set File = Nothing : RF = ""
  End If : WSH.Exec(TCFS2 & " /ef tcm(540)")
Next : If A > 0 Then WSH.RegWrite P, A, "REG_DWORD" : Quit
Sub Quit : Set FSO = Nothing : Set WSH = Nothing : Set SHA = Nothing : WScript.Quit : End Sub

Flasher
14.12.2014