2013-09-27 144 views
9

Tôi có một tập lệnh, xem bên dưới, tìm kiếm tệp thực thi MSDeploy gần đây nhất trên ổ đĩa sys.ParameterArgumentTransformationError

Tuy nhiên, chức năng Compare-FileVersion của tôi không được gọi do các lỗi sau:

Compare-FileVersions : Cannot process argument transformation on parameter 'file1'. Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.IO.FileInfo". At C:\DATA\Git\PowerShell\Test-Command.ps1:32 char:39 
+   $winner = Compare-FileVersions($incumbent, $challenger); 
+          ~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidData: (:) [Compare-FileVersions], ParameterBindingArgumentTransformationException 
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Compare-FileVersions 

Đây là kịch bản:

function Find-Executable() 
{ 
    # Find all MS Deploy executables and then make a table of path and version. Reverse sort and pick top one. 

    pushd; 

    # Workaround for bug in PS where ErrorAction spec'ed in the argument is ignored. http://stackoverflow.com/questions/17489372/ls-recurse-erroraction-silentlycontinue-doesnt-work 

    # Bug is not fixed on build server with this code. 

    $originalEAP = $ErrorActionPreference; 
    $ErrorActionPreference = "SilentlyContinue"; 

    cd $env:SystemDrive; 
    cd \; 
    [System.IO.FileInfo[]]$allExecutables = ls -Include msdeploy.exe -Recurse -Force -ErrorAction SilentlyContinue; 

    $ErrorActionPreference = $originalEAP; 

    popd; 

    if ($allExecutables.Count -lt 1) 
    { 
     throw $("No MS Deploy executables found in folders in " + $env:SystemDrive); 
    }  

    [System.IO.FileInfo]$incumbent = $allExecutables[0]; 
    for($i = 0; $i -lt $allExecutables.Count; $i++) 
    {   
     [System.IO.FileInfo]$challenger = $allExecutables[$i]; 
     $winner = Compare-FileVersions($incumbent, $challenger); 
     $incumbent = $winner; 
    } 

    return $winner; 
} 

function Compare-FileVersions([System.IO.FileInfo]$file1, [System.IO.FileInfo]$file2) 
{ 
    if ($file1.VersionInfo.FileMajorPart -gt $file2.VersionInfo.FileMajorPart) 
    { 
     return $file1; 
    } 
    elseif ($file2.VersionInfo.FileMajorPart -gt $file1.VersionInfo.FileMajorPart) 
    { 
     return $file2; 
    } 

    if ($file1.VersionInfo.FileMinorPart -gt $file2.VersionInfo.FileMinorPart) 
    { 
     return $file1; 
    } 
    elseif ($file2.VersionInfo.FileMinorPart -gt $file1.VersionInfo.FileMinorPart) 
    { 
     return $file2; 
    } 

    if ($file1.VersionInfo.FileBuildPart -gt $file2.VersionInfo.FileBuildPart) 
    { 
     return $file1; 
    } 
    elseif ($file2.VersionInfo.FileBuildPart -gt $file1.VersionInfo.FileBuildPart) 
    { 
     return $file2; 
    } 

    if ($file1.VersionInfo.FilePrivatePart -gt $file2.VersionInfo.FilePrivatePart) 
    { 
     return $file1; 
    } 
    elseif ($file2.VersionInfo.FilePrivatePart -gt $file1.VersionInfo.FilePrivatePart) 
    { 
     return $file2; 
    } 

    # They're both the same at this point. 

    return $file1; 
} 

$version = Find-Executable; 

echo $version; 

Nhưng đây là bằng chứng cho thấy các loại của các biến được truyền như tham số thực sự đúng (rõ ràng là không, bằng cách nào đó, khác tôi sẽ không ở đây trên SO):

Screenshot showing variable types

Cả hai đều là FileInfo, các đối số đều thuộc loại đó. Vì vậy, tôi đang thiếu gì?

Trả lời

17

Bạn sẽ nhận được lỗi này nếu bạn vượt qua đối số như

$winner = Compare-FileVersions($incumbent,$challenger) 

thử này để tách hai biến này với một không gian như thế này và nó sẽ làm việc.

$winner = (Compare-FileVersions $incumbent $challenger) 
+2

Lordy! Tôi ước tôi có thể nói đó là lần đầu tiên tôi làm điều đó nhưng đã trải qua 10 năm qua trong C#, tôi trượt vào 'lưỡi bản địa' của tôi quá dễ dàng. –

+2

Đó là điều đầu tiên tôi gặp phải khi tôi viết hàm PS đầu tiên của mình. – Mitul

+1

Nếu bạn sử dụng Set-StrictMode -v 2, PowerShell sẽ báo cáo lỗi khi bạn sử dụng parens để chuyển nhiều đối số để giúp nắm bắt chính xác vấn đề này. –