3

I need to read the first n bytes from a file, to make sure a file is really a Word file (.docx) (disregarding the extension).

How can I do this?

lbrunolx
  • 33
  • 5
  • 2
    how do you want to distiguish between `.docx` and `.zip`? – Stephan May 25 '16 at 16:10
  • `powershell -command Get-Content -encoding Byte -TotalCount 20 "'file name.docx'"` but have in mind @Stephan's right notice. – JosefZ May 25 '16 at 16:33
  • JosefZ, your solution works like a charm. Thank you! Do you think there is an alternative for batch? (I have to embed this code on a existing batch script). – lbrunolx May 25 '16 at 17:34
  • I don't see any restriction. E.g. you can read and handle the output using [`for /F` loop](http://ss64.com/nt/for_cmd.html). – JosefZ May 25 '16 at 22:04

1 Answers1

2

Read 1st n bytes by fsutil file truncation (make a copy of original first):

FSUTIL file seteof <file> <n bytes>

Or just fc /b the first few bytes you're after:

set n=3
set file=test.one
fsutil file createnew A %n%
fc /b A %file% > B & del A
set /a n=%n%-1 >Nul
for /l %j in (0,1,%n%) do cmd /c exit /b %j & set hex=!=exitcode:~-2!& (find "!hex!: "<B || echo doh: la 00)>> A
(for /f "tokens=3" %i in (A) do set /p=%i <nul) & del A & del B

Note: Either generate binary/null characters from codepage 437 with makecab & built-in cmd commands, or fsutil the null bytes.

Update:

Here's a VBatch hybrid code to get first 3 bytes of a file:

@echo off
echo Set fso=CreateObject("Scripting.FileSystemObject") > some.vbs
echo Set f=fso.OpenTextFile("%~1"):buf=f.Read(3):f.Close >> some.vbs
REM OpenTextFile opens any file as a binary stream; f.read(n) reads the first n bytes of that stream
echo wscript.echo Hex(ASCb(mid(buf,1,1))) ^& "," ^& Hex(ASCb(mid(buf,2,1))) ^& "," ^& Hex(ASCb(mid(buf,3,1))) >> some.vbs

for /f "tokens=1-3 delims=," %%A in ('cscript //nologo some.vbs') do (
   set byte1=0%%A
   set byte2=0%%B
   set byte3=0%%C
   )
echo %byte1:~-2% %byte2:~-2% %byte3:~-2%

Tested in Win 10 CMD

Zimba
  • 2,854
  • 18
  • 26
  • The first one `FSUTIL file seteof` only works with admin privileges, but the second sample works after some modifications – jeb Mar 29 '21 at 12:36
  • I'm on Win 10.0.17134 and it works at user level, no elevation. The 2nd one I copied/pasted code after running test, without modification; some systems might need `cmd /v:on` on Win 10 before pasting code, others might need to include extra line: `SETLOCAL EnableDelayedExpansion` – Zimba Mar 29 '21 at 13:14
  • I've just tested it with 10.0.18363.1379 and fsutil fails without elevation. The second could be converted to a batch file to work always. On the command line, delayed expansion is disabled by default – jeb Mar 29 '21 at 13:30
  • I see, mine works without elevation; I've also read some posts for others who managed to run without elevation too. You're right about the default setting of delayed expansion; [we discussed](https://stackoverflow.com/questions/38805476/enable-delayed-expansion-doesnt-work) this last year. My answer on that post enables the default. – Zimba Mar 29 '21 at 13:48