Score:0

จัดการข้อยกเว้นด้วยเส้นทางยาวใน Powershell

ธง in
ed7

ฉันใหม่ที่นี่และฉันประสบปัญหากับสคริปต์ PowerShell ที่มีเส้นทางยาว สคริปต์นี้มีจุดมุ่งหมายเพื่อรับเส้นทางสัมพัทธ์และแฮชจากไฟล์/โฟลเดอร์และโฟลเดอร์ย่อย มันใช้งานได้กับบางคน ฉันได้รับข้อผิดพลาดต่อไปนี้:

Get-ChildItem : พาธ ชื่อไฟล์ หรือทั้งสองอย่างที่ระบุยาวเกินไป ชื่อไฟล์แบบเต็มต้องน้อยกว่า 260 อักขระ และชื่อไดเร็กทอรีต้องน้อยกว่า 248 อักขระ

ฉันต้องการทราบวิธีจัดการกับสิ่งนี้และหลีกเลี่ยงการให้ข้อผิดพลาดนี้แก่ฉัน

ฉันได้เปิดใช้งานเส้นทางไฟล์แบบยาวใน Windows Server 2012 ซึ่งฉันกำลังเรียกใช้สคริปต์ แต่ก็ยังใช้งานไม่ได้

ถ้าฉันเพิ่มสิ่งนี้ \\?\ ในตัวแปรพาธ มันล้มเหลวโดยบอกว่ามีอักขระที่ผิดกฎหมายในพาธ แม้ว่าฉันจะเพิ่ม -LiteralPath ก็ตาม

ความช่วยเหลือใด ๆ จะดีมาก

นี่คือสคริปต์ mypowershell:

#ข้อความถึงผู้ใช้
  Write-Output "`nสคริปต์นี้จะรวบรวม FilePathName, Name, RelativePath และแฮชของไฟล์/โฟลเดอร์ที่คุณเลือก"
               "`nในตอนท้าย มันจะบอกคุณว่าใช้เวลานานเท่าใดในการรันสคริปต์"   
  Read-Host - พร้อมท์ "`nPress ENTER เพื่อดำเนินการต่อหรือ CTRL+C เพื่อออก" 
        
  #นับเวลาจากจุดเริ่มต้น
  $starttime = (วันที่รับ)
        
  #ตัวแปร
  #สามารถเพิ่มได้สูงสุด 3 เส้นทางเท่านั้น หากเพิ่มมากกว่า 3 อาจเปลี่ยนเส้นทางญาติ
  $root = "C:\mypath"
        
        
  #Variable สำหรับสร้างไฟล์ CSV
  $report = "mycsvfile.csv"
        
        
  #กระบวนการสร้าง HASH
  $hasher = [System.Security.Cryptography.SHA256]::สร้าง()
  $AllFiles = @() 
        
  "`n"#line space
        
  เขียนโฮสต์ "สร้างแฮชจาก $root" 
        
        
        
  #รับข้อมูลจากไดเร็กทอรี
  foreach (ไฟล์ $ ใน get-childitem $root -recurse | Select-Object FullName, Directory, Name, PSIsContainer, Length)
  {
      $acl = get-acl $file.fullname | เลือกเจ้าของวัตถุ accesstostring กลุ่ม
      $obj = วัตถุใหม่ psObject
        
        
  #กำลังสร้างไฟล์ HASH
      ถ้า(!$file.PsIsContainer)
          {
          $relativePath = $file.FullName.Substring($root.Length)
          โฮสต์เขียน "Debug $relativePath" -ForegroundColor Green
        
          $inputStream = New-Object IO.StreamReader $file.fullname
          $hashBytes = $hasher.ComputeHash($inputStream.BaseStream)
          $inputStream.ปิด()
        
          $builder = New-Object System.Text.StringBuilder
          $hashBytes | Foreach-Object { [void] $builder.Append($_.ToString("X2")) }
        
  #เพิ่มข้อมูลลงในไฟล์ CSV
          $obj | Add-Member -membertype noteproperty -ชื่อ FilePahandName -Value $file.FullName
          $obj | เพิ่มสมาชิก -membertype noteproperty -name Name -Value $file.Name
          $obj | เพิ่มสมาชิก -MemberType noteproperty -Name RelativePath -Value $relativePath #-force
          $obj | เพิ่มสมาชิก -MemberType noteproperty -Name Hash -Value $builder.ToString()
          #$obj | เพิ่มสมาชิก -membertype noteproperty -name CreationTime -Value $file.CreationTime
          #$obj | เพิ่มสมาชิก -MemberType noteproperty -ชื่อ LastAccessTime -ค่า $file.LastAccessTime
          #$obj | เพิ่มสมาชิก -MemberType noteproperty -ชื่อ LastWriteTime -Value $file.LastWriteTime
        
                
      #Variable เพื่อส่งข้อมูลไปยัง CSV
      $AllFiles += $obj
      เส้นทางสัมพัทธ์ของตัวแปรที่ชัดเจน
      }
  ลบตัวแปร obj
  }
        
  #$ไฟล์ทั้งหมด += $obj
        
  #สร้างไฟล์ CSV
  $AllFiles | ส่งออก Csv $report âNoTypeInformation
        
  "`น"
  Write-Host "สร้างไฟล์ $report แล้ว"
        
  "`น"
  พิธีกรนักเขียน "บทพาไป:`n"
  $endTime = รับวันที่
  ช่วงเวลาใหม่ - เริ่ม $startTime - สิ้นสุด $endTime
br flag
[1] หากคุณใช้ win10 หรือ win11 คุณสามารถตั้งค่าระบบปฏิบัติการให้ใช้ชื่อยาวได้ ///// [2] คุณสามารถใช้คำนำหน้า Unicode เพื่ออนุญาตเส้นทางยาวสำหรับการโทรเพียงครั้งเดียว ///// สำหรับข้อมูลทั้งสองอย่าง lookee ... >>> Maximum Path Length Limit - Win32 apps | Microsoft Docs â https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd
Score:1
ธง ru

เพื่อให้ Powershell cmdlets ทำงานได้อย่างถูกต้องโดยใช้ \\?\ คุณต้องติดตั้งคอมโพเนนต์เหล่านี้ในเวอร์ชันขั้นต่ำต่อไปนี้ (ผ่านการทดสอบและตรวจสอบบน Windows Server 2012 R2):

จากนั้น คุณเพียงแค่ต้องเปลี่ยนตัวแปรพาธรูทในสคริปต์ของคุณดังต่อไปนี้ และมันจะทำงานตามที่คาดไว้:

  #ตัวแปร
  #สามารถเพิ่มได้สูงสุด 3 เส้นทางเท่านั้น หากเพิ่มมากกว่า 3 อาจเปลี่ยนเส้นทางสัมพัทธ์
  $root = "\?\C:\mypath\"
        

ไม่จำเป็นต้องเปลี่ยนคีย์รีจิสทรีใดๆ เพื่อเปิดใช้งานการสนับสนุนพาธแบบยาวหรือใช้พารามิเตอร์ -LiteralPath สำหรับ cmdlet ใดๆฉันเคยเห็นการอ้างสิทธิ์เหล่านี้หลายครั้งในบทความและฟอรัมอื่นๆ แต่นั่นไม่ถูกต้อง ยกเว้น Windows รุ่นเก่ามาก


ตอนนี้ หากคุณไม่สามารถติดตั้งเวอร์ชันที่ใหม่กว่านี้ได้ คุณจะต้องใช้วิธีแก้ไขปัญหาชั่วคราว

โปรดทราบว่าในสคริปต์ของคุณ ฟังก์ชันต่อไปนี้ได้รับผลกระทบจากปัญหานี้:

  • Get-ChildItem
  • รับ-Acl
  • ใหม่วัตถุ IO.StreamReader

ทางออกหนึ่งคือการ แทนที่ส่วนหนึ่งของเส้นทางเป็นไดรฟ์ เมื่อมันยาวเกินไปและใช้ไดรฟ์ใหม่เป็นโฟลเดอร์รูท ฉันลองใช้สิ่งนี้ สารบัญ คำสั่ง แต่ควรใช้งานได้โดยใช้ไฟล์ ใหม่ PSDrive ซม. สิ่งนี้จำเป็นต้องเพิ่มตรรกะบางอย่างในสคริปต์ของคุณ แต่ก็ไม่ต้องใช้ความพยายามมากเกินไปและค่อนข้างง่าย

ตอนนี้, หากคุณต้องการดูรายชื่อไฟล์ทั้งหมดก่อนที่จะทำการทดแทนใดๆ (เพื่อให้คุณสามารถตรวจสอบเส้นทางและความยาวของชื่อไฟล์ทั้งหมดได้) คุณสามารถใช้วิธีแก้ไขปัญหาต่อไปนี้:

$root = "C:\mypath\" ;
$AllFiles = cmd /c dir $root /b /s /a-d ;

นี่จะให้รายการไฟล์ (ชื่อเต็ม) แก่คุณ

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา