【问题标题】:Code works perfectly in Powershell 5 but not in Powershell 6代码在 Powershell 5 中完美运行,但在 Powershell 6 中却不行
【发布时间】:2019-09-02 09:10:10
【问题描述】:

我的一项任务需要从文件列表中创建 ISO 映像。我找到了this gist(根据作者的说法,代码在公共领域)。

我的公司只使用 Powershell 6.2.2,这是我必须处理的事实。问题是代码在 Powershell 5.1 中完美运行,但在 Powershell 6.2.2 中却不行!它给了我以下错误:

    Add-Type : A parameter cannot be found that matches parameter name 'CompilerParameters'.
At E:\work\MSPV\New_ISOfile.ps1:19 char:11
+     Add-Type -CompilerParameters $cp -TypeDefinition @"
+              ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Add-Type], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.AddTypeCommand

Unable to find type [My.FileUtil].
At E:\work\MSPV\New_ISOfile.ps1:52 char:2
+     [My.FileUtil]::WriteIStreamToFile($istream, $fileName)
+     ~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (My.FileUtil:TypeName) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound

我发现的唯一一件事是,根据 MS 文档,在 Powershell 6.x 中,对于 Add-Type cmdlet 没有“-CompilerParameters”这样的参数,但在 Powershell 5(即 5.1)中有一个参数。尝试用“-CompilerOptions”替换它,但这没有帮助。同样的错误。

有没有办法让它在 Powershell 6.2 上运行?

【问题讨论】:

    标签: .net class powershell-5.0 incompatibility powershell-6.0


    【解决方案1】:

    实际上在 PS 6+ 中该调用已消失,因为在文档中 -CompilerParameters 已被替换为 -CompilerOptions 并且它需要字符串参数。

    你必须像下面这样直接调用它

    Add-Type -CompilerOptions "/unsafe" -TypeDefinition
    

    如果您来自function New-IsoFile,这里是完整代码

    function New-IsoFile 
    {   
      [CmdletBinding(DefaultParameterSetName='Source')]Param( 
        [parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true, ParameterSetName='Source')]$Source,  
        [parameter(Position=2)][string]$Path = "$env:temp\$((Get-Date).ToString('yyyyMMdd-HHmmss.ffff')).iso",  
        [ValidateScript({Test-Path -LiteralPath $_ -PathType Leaf})][string]$BootFile = $null, 
        [ValidateSet('CDR','CDRW','DVDRAM','DVDPLUSR','DVDPLUSRW','DVDPLUSR_DUALLAYER','DVDDASHR','DVDDASHRW','DVDDASHR_DUALLAYER','DISK','DVDPLUSRW_DUALLAYER','BDR','BDRE')][string] $Media = 'DVDPLUSRW_DUALLAYER', 
        [string]$Title = (Get-Date).ToString("yyyyMMdd-HHmmss.ffff"),  
        [switch]$Force, 
        [parameter(ParameterSetName='Clipboard')][switch]$FromClipboard 
      ) 
      
      Begin {  
        ($cp = new-object System.CodeDom.Compiler.CompilerParameters).CompilerOptions = '/unsafe' 
        if (!('ISOFile' -as [type])) {  
          Add-Type -CompilerOptions "/unsafe" -TypeDefinition @'
    public class ISOFile  
    { 
      public unsafe static void Create(string Path, object Stream, int BlockSize, int TotalBlocks)  
      {  
        int bytes = 0;  
        byte[] buf = new byte[BlockSize];  
        var ptr = (System.IntPtr)(&bytes);  
        var o = System.IO.File.OpenWrite(Path);  
        var i = Stream as System.Runtime.InteropServices.ComTypes.IStream;  
       
        if (o != null) { 
          while (TotalBlocks-- > 0) {  
            i.Read(buf, BlockSize, ptr); o.Write(buf, 0, bytes);  
          }  
          o.Flush(); o.Close();  
        } 
      } 
    }  
    '@  
        } 
       
        if ($BootFile) { 
          if('BDR','BDRE' -contains $Media) { Write-Warning "Bootable image doesn't seem to work with media type $Media" } 
          ($Stream = New-Object -ComObject ADODB.Stream -Property @{Type=1}).Open()  # adFileTypeBinary 
          $Stream.LoadFromFile((Get-Item -LiteralPath $BootFile).Fullname) 
          ($Boot = New-Object -ComObject IMAPI2FS.BootOptions).AssignBootImage($Stream) 
        } 
      
        $MediaType = @('UNKNOWN','CDROM','CDR','CDRW','DVDROM','DVDRAM','DVDPLUSR','DVDPLUSRW','DVDPLUSR_DUALLAYER','DVDDASHR','DVDDASHRW','DVDDASHR_DUALLAYER','DISK','DVDPLUSRW_DUALLAYER','HDDVDROM','HDDVDR','HDDVDRAM','BDROM','BDR','BDRE') 
      
        Write-Verbose -Message "Selected media type is $Media with value $($MediaType.IndexOf($Media))"
        ($Image = New-Object -com IMAPI2FS.MsftFileSystemImage -Property @{VolumeName=$Title}).ChooseImageDefaultsForMediaType($MediaType.IndexOf($Media)) 
       
        if (!($Target = New-Item -Path $Path -ItemType File -Force:$Force -ErrorAction SilentlyContinue)) { Write-Error -Message "Cannot create file $Path. Use -Force parameter to overwrite if the target file already exists."; break } 
      }  
      
      Process { 
        if($FromClipboard) { 
          if($PSVersionTable.PSVersion.Major -lt 5) { Write-Error -Message 'The -FromClipboard parameter is only supported on PowerShell v5 or higher'; break } 
          $Source = Get-Clipboard -Format FileDropList 
        } 
      
        foreach($item in $Source) { 
          if($item -isnot [System.IO.FileInfo] -and $item -isnot [System.IO.DirectoryInfo]) { 
            $item = Get-Item -LiteralPath $item
          } 
      
          if($item) { 
            Write-Verbose -Message "Adding item to the target image: $($item.FullName)"
            try { $Image.Root.AddTree($item.FullName, $true) } catch { Write-Error -Message ($_.Exception.Message.Trim() + ' Try a different media type.') } 
          } 
        } 
      } 
      
      End {  
        if ($Boot) { $Image.BootImageOptions=$Boot }  
        $Result = $Image.CreateResultImage()  
        [ISOFile]::Create($Target.FullName,$Result.ImageStream,$Result.BlockSize,$Result.TotalBlocks) 
        Write-Verbose -Message "Target image ($($Target.FullName)) has been created"
        $Target
      } 
    }  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-13
      • 2018-02-07
      • 2013-10-10
      • 1970-01-01
      • 1970-01-01
      • 2013-01-06
      相关资源
      最近更新 更多