当前位置: 首页 > 科技观察

Windows10损坏用户文件?教你解决这个Bug

时间:2023-03-15 08:41:56 科技观察

如果你是音乐发烧友,应该知道Flac这种常见的无损音乐格式。Flac音乐文件支持元数据,用户可以编辑元数据,使音乐文件包含艺术家、专辑、曲目等信息。一般来说,元数据和音频数据没有关联,修改元数据不会影响音频本身。不过近日微软官方宣布Windows10存在一个bug,在Win10中用资源管理器修改Flac文件的元数据居然会造成音频损坏!据WindowsLatest报道,微软发布的一份新的支持文档披露,如果在Windows102004或更高版本中使用文件资源管理器修改Flac音乐文件的元数据,Flac音频文件将会丢失。该错误出现在Windows10专业版、家庭版、企业版、工作站版甚至Windows10的其他版本中。根据微软本月早些时候发布的支持文档,Windows10的文件资源管理器通过破坏ID3框架导致错误,或元数据,包含在Flac文件头中,负责存储音频注释,例如音乐。标题、艺术家、专辑、曲目编号等。在Windows10上,Flac处理程序忽略ID3帧。该程序认为Flac文件使用的是4字节文件头。Windows10编辑Flac文件时,ID3帧被覆盖,导致无起始码。结果,音乐播放器无法识别修改后的文件。因此,在Windows10中,如果直接使用文件资源管理器修改Flac音乐文件的标题、艺术家等元数据,将无法播放该文件。幸运的是,微软已经查明了该漏洞的根源,用户可以通过WindowsUpdate升级KB5003214补丁进行修复。在KB5003214补丁中,微软确认已修复上述错误。修改Flac的标题、艺术家等元数据后,Flac将不再变得无法播放。对于损坏的Flac文件,微软发布了一个PowerShell脚本来修复它们。运行脚本后,可以再次播放Flac文件,但ID3帧丢失的元数据信息无法恢复。下面介绍如何使用PowerShell脚本修复Flac文件。1.打开记事本;2.复制到下字符,粘贴到记事本中:#Copyright2021Microsoft#ThisscriptwillrepairaFLACfilethathasbeencorruptedbyMediaFoundationinreferencetoKB5003430. #RefertoKB5003430forfurtherinformation param( [parameter(Mandatory=$true, HelpMessage="ThepathtotheFLACfilethathasbeencorruptedbyMediaFoundation", ValueFromRemainingArguments=$true)] [ValidateScript({-not[String]::IsNullOrEmpty($_)-and(Test-Path$_)})] [String]$File ) #我们需要备份当前文件,以防出现任何错误 $FileDirectory=Split-Path-Resolve$File $Filename=Split-Path-Leaf-Resolve$File $FullPath=Join-Path-Resolve$FileDirectory$Filename $Filename=[String]::Format("Backup_{0:yyyyMMdd_hhmmss}_{1}",[DateTime]::Now,$Filename) $BackupLocation=Join-Path$FileDirectory$Filename Write-Output"MicrosoftFLACRepairTool。此工具将修复在编辑其详细信息时损坏的FLA音频文件。Write-Output"Abackupofthefilewillbemade:$BackupLocation" Write-Output"Doyouwishtocontinue?" $choice=$host.ui.PromptForChoice("FixingFLACScript","Doyouwishtocontinue",('&Yes','&No'),1) functionParseStreamInfoMetadataBlock([System.IO.FileStream]$stream) { $blockType=$stream.ReadByte() $lastBlock=($blockType-shr7)-ne0 $blockType=$blockType-band0x7F if($blockType-ne0) { return$false } $blockSize=(($stream.ReadByte()-shl16)-bor($stream.ReadByte()-shl8)-bor$stream.ReadByte()) if($blockSize-lt34) { return$false } $minAudioBlockSize=($stream.ReadByte()-shl8)-bor$stream.ReadByte() $maxAudioBlockSize=($stream.ReadByte()-shl8)-bor$stream.ReadByte() if($minAudioBlockSize-lt16-or$maxAudioBlockSize-lt16) { return$false } $minFrameSize=(($stream.ReadByte()-shl16)-bor($stream.ReadByte()-shl8)-bor$stream.ReadByte()) $maxFrameSize=(($stream.ReadByte()-shl16)-bor($stream.ReadByte()-shl8)-bor$stream.ReadByte()) $sampleInfo=(($stream.ReadByte()-shl24)-bor($stream.ReadByte()-shl16)-bor($stream.ReadByte()-shl8)-bor$stream.ReadByte()) $sampleRate=$sampleInfo-shr12 $channelCount=(($sampleInfo-shr9)-band0x7)+1 $bitsPerSample=(($sampleInfo-shr4)-band0x1F)+1 [UInt64]$sampleCount=(($stream.ReadByte()-shl24)-bor($stream.ReadByte()-shl16)-bor($stream.ReadByte()-shl8)-bor$stream.ReadByte()) $sampleCount=(([UInt64]$sampleInfo-band0xF)-shl32)-bor$sampleCount $MD5HashBytes=New-Objectbyte[]16 $stream.Read($MD5HashBytes,0,$MD5HashBytes.Length) $MD5Hash=[Guid]($MD5HashBytes) if($sampleRate-eq0) { return$false } #Passingthesechecksmeansthatwelikelyhaveastreaminfoheaderandcanrebuildthefile Write-Output"FileStreamInformation" WriteRateOutput:"$sampleRate-Output:" 写输出“AudioChannels:$channelCount” 写输出"SampleDepth:$bitsPerSample" 写输出"MD5AudioSampleHash:$MD5Hash" return$true } if($choice-eq0) { Copy-Item$FullPath-Destination$BackupLocation-Force $stream=[System.IO.File]::Open($FullPath,[System.IO.FileMode]::Open) $stream.Seek(4,[System.IO.SeekOrigin]::Begin) while($stream.ReadByte()-eq0){} #WenowneedtofigureoutwhereavalidFLACmetadataframebegins #Wearelikelypointingtothelastbyteofthesizememberssowe'llseekback4bytesandretrystream $flac=DataStartPosition-4 $stream.Seek($flacDataStartPosition,[System.IO.SeekOrigin]::Begin) while(-not(ParseStreamInfoMetadataBlock($stream))) { $flacDataStartPosition=$flacDataStartPosition+1 $stream.Seek($flacDataStartPosition,[System.IO.SeekOrigin]::Begin) } #Insertthestartcode $stream.Seek($flacDataStartPosition,[System.IO.SeekOrigin]::Begin) if(Test-Path"$FullPath.tmp") { Remove-Item"$FullPath.tmp" } $fixedStream=[System.IO.File]::Open("$FullPath.tmp",[System.IO.FileMode]::CreateNew) [byte[]]$startCode=[char[]]('f','L','a','C'); $fixedStream.Write($startCode,0,$startCode.Length) $stream.CopyTo($fixedStream) $stream.Close() $fixedStream.Close() Move-Item-Force"$FullPath.tmp"$FullPath }3.在“另存为”对话框中保存文件,找到你要保存PowerShell脚本的目录;4、在文件名输入框中输入“FixFlacFiles.ps1”,将保存的文件类型改为TextDocuments(*.txt);5.输入保存PowerShell脚本的目录;6、右击刚才保存的脚本,选择“使用PowerShell运行”;7.出现提示时,输入无法播放的Flac文件的文件名,然后按Enter。微软建议您安装本月推送的可选累积更新,以避免修改Flac文件元数据时出现问题。