This is a creation in Article, where the information may have evolved or changed.
Go to get exe, DLL, APK version number, support Kua platform, can cross-compile.
A little bit uncomfortable, modify a format also to review, wasting mood.
Golang implementation read EXE DLL APK version number package Mainimport ("Flag" "FMT" "Log" "OS" "Path/filepath") Import ("Gith Ub.com/lunny/axmlparser ") var (file fileInfo) const (MZ =" mz "PE =" PE "RSRC =". RSRC "TYP ET = Peoffset = "Machine = 332 DEFAULT = ' C:\Windows\System32\cmd.exe ') type fileInfo struct {Filepa Th string Version string Debug bool}func (f *fileinfo) CheckError (err error) {if err! = Nil {log. Fatalln (ERR)}}//gets the exe DLL version of func (f *fileinfo) getexeversion (err Error) {file, err: = OS. Open (F.filepath) f.checkerror (ERR)//read byte buffer for the first time: = Make ([]byte, _) _, err = file. Read (buffer) F.checkerror (ERR) defer file. Close () str: = string (Buffer[0]) + string (buffer[1]) if str! = MZ {log. Fatalln ("Read EXE error, unable to find MZ.", F.filepath)} Peoffset: = F.unpack ([]byte{buffer[60], buffer[61], buffer[62], buffer[63]} ) If Peoffset < Peoffset {log. Fatalln ("PeOFfset read error. ", F.filepath)}//read from the beginning of the file shifted to Peoffset, the second read of the byte _, err = file. Seek (Int64 (Peoffset), 0) buffer = make ([]byte, _) _, err = file. Read (buffer) f.checkerror (err) str = string (Buffer[0]) + string (buffer[1]) if str! = PE {log. Fatalln ("read EXE error, cannot find PE.", F.filepath)} machine: = F.unpack ([]byte{buffer[4], buffer[5]}) if machine! = Machine {log. Fatalln ("Machine read error.", F.filepath)} nosections: = F.unpack ([]byte{buffer[6], Buffer[7]}) opthdrsize: = F.unpac K ([]byte{buffer[20], buffer[21]})//read from the current position shifted to Opthdrsize, the third time to read the four byte file. Seek (Int64 (opthdrsize), 1) Resfound: = False for I: = 0; i < int (nosections); i++ {buffer = make ([]byte, +) file. Read (buffer) str = string (Buffer[0]) + string (Buffer[1]) + string (buffer[2]) + string (Buffer[3]) + string (Buffer[4] If str = = RSRC {Resfound = True Break}} if!resfound {log. Fatalln ("Read EXE error,Cannot find. rsrc. ", F.filepath)} infovirt: = F.unpack ([]byte{buffer[12], buffer[13], buffer[14], buffer[15]}) infosize : = F.unpack ([]byte{buffer[16], buffer[17], buffer[18], buffer[19]}) Infooff: = F.unpack ([]byte{buffer[20], buffer[21], BUFFER[22], buffer[23]})//reads from the beginning of the file to Infooff, and reads the infosize byte file for the fourth time. Seek (Int64 (Infooff), 0) buffer = make ([]byte, Infosize) _, err = file. Read (buffer) f.checkerror (err) Nameentries: = F.unpack ([]byte{buffer[12], buffer[13]}) Identries: = F.unpack ([]by TE{BUFFER[14], buffer[15]}) var infofound bool Var suboff, I int64 for i = 0; I < (nameentries + identries); i++ {typet: = F.unpack ([]byte{buffer[i*8+16], buffer[i*8+17], buffer[i*8+18], buffer[i*8+19]}) if Typet = = Typet {Infofound = True Suboff = Int64 (F.unpack ([]byte{buffer[i*8+20], buffer[i*8+21], buffer[i*8+2 2], buffer[i*8+23]})) break}} if!infofound {log. Fatalln ("read EXE error, cannot find Typet = =", F.filepath)} Suboff = Suboff & 0x7fffffff Infooff = F.unpack ([]byte{buffer[suboff+20], buffer[suboff+2 1], buffer[suboff+22], buffer[suboff+23]})//offset of first FILEINFO Infooff = infooff & 0x7fffffff Infooff = f . unpack ([]byte{buffer[infooff+20], buffer[infooff+21], buffer[infooff+22], buffer[infooff+23]})//offset to Data Dataoff: = F.unpack ([]byte{buffer[infooff], buffer[infooff+1], buffer[infooff+2], buffer[infooff+3]}) DataOff = DataOf F-infovirt Version1: = F.unpack ([]byte{buffer[dataoff+48], buffer[dataoff+48+1]}) Version2: = F.unpack ([]byte{buff ER[DATAOFF+48+2], buffer[dataoff+48+3]}) Version3: = F.unpack ([]byte{buffer[dataoff+48+4], buffer[dataoff+48+5]}) ve Rsion4: = F.unpack ([]byte{buffer[dataoff+48+6], Buffer[dataoff+48+7]}) Version: = FMT. Sprintf ("%d.%d.%d.%d", Version2, Version1, Version4, version3) f.version = Version return Nil}func (f *fileinfo) UNP ACK (b []byte) (num Int64) {for i: = 0; i < Len (b); i++ { num = 256*num + Int64 ((B[len (b) -1-i] & 0xff)} return}//get APK version func (f *fileinfo) getapkversion () (Er R error) {Listener: = new (Axmlparser.appnamelistener) _, Err = axmlparser.parseapk (F.filepath, listener) F.check Error (err) f.version = listener. Versionname return Nil}func init () {flag. Stringvar (&file. FilePath, "path", DEFAULT, "Get exe or DLL or APK version information.") Flag. Boolvar (&file. Debug, "D", False, "if true print exe or DLL file name.")} Func main () {flag. Parse () Suffix: = filepath. Ext (file. FilePath) switch suffix {case ". exe", ". dll": file. Getexeversion () case ". apk": File. Getapkversion () Default:log. Fatalln ("Can only get exe, DLL, APK version number, please re-enter the program path."), file. FilePath)} switch {case file. Debug:fmt. Printf ("%s's version number is:", file.) FilePath) case file. FilePath = = Default:flag. Printdefaults () fmt. Printf ("%s's version number is:", file.) FilePath)} FMT. Printf ("%s", file. Version)}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.