Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access a file's properties on Windows?

People also ask

How do I open folder properties in Windows 10?

To access the properties of a file or folder, right-click on it and select Properties. You can also Alt-click on a file or folder to access its properties.

How do I access properties dialog box?

To open a properties dialog box where you can add or edit all the properties at once and view document information, click Properties at the top of the page, and then click Advanced Properties.

How do I open properties file with keyboard?

Alt+Enter opens the file properties so you can view file size, sharing settings, and creation date.


Here is a function which reads all file attributes as a dictionary:

import win32api

#==============================================================================
def getFileProperties(fname):
#==============================================================================
    """
    Read all properties of the given file return them as a dictionary.
    """
    propNames = ('Comments', 'InternalName', 'ProductName',
        'CompanyName', 'LegalCopyright', 'ProductVersion',
        'FileDescription', 'LegalTrademarks', 'PrivateBuild',
        'FileVersion', 'OriginalFilename', 'SpecialBuild')

    props = {'FixedFileInfo': None, 'StringFileInfo': None, 'FileVersion': None}

    try:
        # backslash as parm returns dictionary of numeric info corresponding to VS_FIXEDFILEINFO struc
        fixedInfo = win32api.GetFileVersionInfo(fname, '\\')
        props['FixedFileInfo'] = fixedInfo
        props['FileVersion'] = "%d.%d.%d.%d" % (fixedInfo['FileVersionMS'] / 65536,
                fixedInfo['FileVersionMS'] % 65536, fixedInfo['FileVersionLS'] / 65536,
                fixedInfo['FileVersionLS'] % 65536)

        # \VarFileInfo\Translation returns list of available (language, codepage)
        # pairs that can be used to retreive string info. We are using only the first pair.
        lang, codepage = win32api.GetFileVersionInfo(fname, '\\VarFileInfo\\Translation')[0]

        # any other must be of the form \StringfileInfo\%04X%04X\parm_name, middle
        # two are language/codepage pair returned from above

        strInfo = {}
        for propName in propNames:
            strInfoPath = u'\\StringFileInfo\\%04X%04X\\%s' % (lang, codepage, propName)
            ## print str_info
            strInfo[propName] = win32api.GetFileVersionInfo(fname, strInfoPath)

        props['StringFileInfo'] = strInfo
    except:
        pass

    return props

Better to add a try/except in case the file has no version number attribute.

filever.py


from win32api import GetFileVersionInfo, LOWORD, HIWORD

def get_version_number (filename):
    try:
        info = GetFileVersionInfo (filename, "\\")
        ms = info['FileVersionMS']
        ls = info['FileVersionLS']
        return HIWORD (ms), LOWORD (ms), HIWORD (ls), LOWORD (ls)
    except:
        return 0,0,0,0

if __name__ == '__main__':
  import os
  filename = os.environ["COMSPEC"]
  print ".".join ([str (i) for i in get_version_number (filename)])

yourscript.py:


import os,filever

myPath="C:\\path\\to\\check"

for root, dirs, files in os.walk(myPath):
    for file in files:
        file = file.lower() # Convert .EXE to .exe so next line works
        if (file.count('.exe') or file.count('.dll')): # Check only exe or dll files
            fullPathToFile=os.path.join(root,file)
            major,minor,subminor,revision=filever.get_version_number(fullPathToFile)
            print "Filename: %s \t Version: %s.%s.%s.%s" % (file,major,minor,subminor,revision)

Cheers!


You can use the pyWin32 module from https://github.com/mhammond/pywin32:

from win32com.client import Dispatch

ver_parser = Dispatch('Scripting.FileSystemObject')
info = ver_parser.GetFileVersion(path)

if info == 'No Version Information Available':
    info = None

Here is a version that also works in non-Windows environments, using the pefile module:

import pefile

def LOWORD(dword):
    return dword & 0x0000ffff
def HIWORD(dword): 
    return dword >> 16
def get_product_version(path):

    pe = pefile.PE(path)
    #print PE.dump_info()

    ms = pe.VS_FIXEDFILEINFO.ProductVersionMS
    ls = pe.VS_FIXEDFILEINFO.ProductVersionLS
    return (HIWORD (ms), LOWORD (ms), HIWORD (ls), LOWORD (ls))


if __name__ == "__main__":
    import sys
    try:
        print "%d.%d.%d.%d" % get_product_version(sys.argv[1])
    except:
        print "Version info not available. Maybe the file is not a Windows executable"

I found this solution at "timgolden" site. Works fine.

from win32api import GetFileVersionInfo, LOWORD, HIWORD

def get_version_number (filename):
  info = GetFileVersionInfo (filename, "\\")
  ms = info['FileVersionMS']
  ls = info['FileVersionLS']
  return HIWORD (ms), LOWORD (ms), HIWORD (ls), LOWORD (ls)

if __name__ == '__main__':
  import os
  filename = os.environ["COMSPEC"]
  print ".".join ([str (i) for i in get_version_number (filename)])

I found that the only cross-platform answer (using pefile) couldn't find the version string I was looking for, which is the one shown in the 'Details' tab of the 'View properties' of a .DLL file on Windows. However, this code, based on the dump_info() function in pefile, is able to find those attributes, which include original filename, copyright, company name, and file and product versions.

You may need to replace encoding with a different encoding if they are not encoded using UTF-8.

import pefile

PATH_TO_FILE = 'C:\...'
pe = pefile.PE(PATH_TO_FILE)

if hasattr(pe, 'VS_VERSIONINFO'):
    for idx in range(len(pe.VS_VERSIONINFO)):
        if hasattr(pe, 'FileInfo') and len(pe.FileInfo) > idx:
            for entry in pe.FileInfo[idx]:
                if hasattr(entry, 'StringTable'):
                    for st_entry in entry.StringTable:
                        for str_entry in sorted(list(st_entry.entries.items())):
                            print('{0}: {1}'.format(
                                str_entry[0].decode('utf-8', 'backslashreplace'),
                                str_entry[1].decode('utf-8', 'backslashreplace')))