问题
I have an XML file that has file attachments encoded in Base64 within it (InfoPath). When I use Powershell to decode the Base64 string for the attachment, it seems like I have to write the file path and extension into the WriteAllBytes command but I don't know whether the original file was a PDF, image file, DOCX, etc. - is there a way to have it write the string into the original filename and/or extension and I just specify the folder where it needs to go? Example code:
$b64str = $xml.myRootNode.attachmentNode
$someFileName = somehow get original filename
$someFileExtension = somehow get original extension
$filepath = "C:\myFolder\$someFileName.$someFileExtension"
$bytes = [Convert]::FromBase64String($b64str)
[IO.File]::WriteAllBytes($filepath,$bytes)
EDIT: Found an answer thanks to the efforts of the commentors. For those who have to do this in the future, possibly to use Powershell to extract attachments from InfoPath forms within a library hint hint: InfoPath attachment base64 strings are composed of three parts: a header, the filename, and the file content. The header is 24 bytes long but includes at byte 20 the length of the filename. Use that number times 2 (for Unicode) to then get the filename extracted into a new byte array. Last, create a new array to carry the bytes for the content (the full length minus the beginning header length of 24 and the filename bytes) and THAT is what you convert back from base64. Here is what I ended up doing (only works with InfoPath XML files):
$b64str = $xml.myRootNode.attachmentNode
$bytes = [Convert]::FromBase64String($b64str)
$arrFileNameBytes = @()
$fileNameByteLen = $bytes[20]*2
for($i=0;$i -lt $fileNameByteLen;$i+=2){
$arrFileNameBytes+=$bytes[24+$i]
}
$arrFileContentBytes = @()
$fileContentByteLen = $bytes.length-(24+$fileNameByteLen)
for($i=0;$i -lt $fileContentByteLen;$i++){
$arrFileContentBytes+=$bytes[24+$i+$fileNameByteLen]
}
$fileName = [System.Text.Encoding]::ASCII.GetString($arrFileNameBytes)
$fileName = $filename.trim()
$fileName = $filename.substring(0,$filename.length-1)
$filepath = "C:\MyFolder\$fileName"
[IO.File]::WriteAllBytes($filepath,$arrFileContentBytes)
来源:https://stackoverflow.com/questions/47397185/powershell-determine-base64-string-file-extension