win32verstamp.py :  » Windows » pyExcelerator » pywin32-214 » win32 » lib » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Windows » pyExcelerator 
pyExcelerator » pywin32 214 » win32 » lib » win32verstamp.py
""" Stamp a Win32 binary with version information.
"""

from win32api import BeginUpdateResource,UpdateResource,EndUpdateResource

import os
import struct
import glob

import optparse

VS_FFI_SIGNATURE = -17890115 # 0xFEEF04BD
VS_FFI_STRUCVERSION = 0x00010000
VS_FFI_FILEFLAGSMASK = 0x0000003f
VOS_NT_WINDOWS32 = 0x00040004

null_byte = "\0".encode("ascii") # str in py2k, bytes in py3k
#
# Set VS_FF_PRERELEASE and DEBUG if Debug
#
def file_flags(debug):
  if debug:
    return 3  # VS_FF_DEBUG | VS_FF_PRERELEASE
  return 0

def file_type(is_dll):
  if is_dll:
    return 2  # VFT_DLL
  return 1  # VFT_APP

def VS_FIXEDFILEINFO(maj, min, sub, build, debug=0, is_dll=1):
  return struct.pack('lllllllllllll',
                     VS_FFI_SIGNATURE,  # dwSignature
                     VS_FFI_STRUCVERSION,  # dwStrucVersion
                     (maj << 16) | min,  # dwFileVersionMS
                     (sub << 16) | build,# dwFileVersionLS
                     (maj << 16) | min,  # dwProductVersionMS
                     (sub << 16) | build,    # dwProductVersionLS
                     VS_FFI_FILEFLAGSMASK,  # dwFileFlagsMask
                     file_flags(debug),  # dwFileFlags
                     VOS_NT_WINDOWS32,  # dwFileOS
                     file_type(is_dll),  # dwFileType
                     0x00000000,  # dwFileSubtype
                     0x00000000,  # dwFileDateMS
                     0x00000000,  # dwFileDateLS
                     )

def nullterm(s):
  # get raw bytes for a NULL terminated unicode string.
  return (unicode(s) + u'\0').encode('unicode-internal')

def pad32(s, extra=2):
  # extra is normally 2 to deal with wLength
  l = 4 - ((len(s) + extra) & 3)
  if l < 4:
    return s + (null_byte * l)
  return s

def addlen(s):
  return struct.pack('h', len(s) + 2) + s

def String(key, value):
  key = nullterm(key)
  value = nullterm(value)
  result = struct.pack('hh', len(value)/2, 1)  # wValueLength, wType
  result = result + key
  result = pad32(result) + value
  return addlen(result)

def StringTable(key, data):
  key = nullterm(key)
  result = struct.pack('hh', 0, 1)  # wValueLength, wType
  result = result + key
  for k, v in data.iteritems():
    result = result + String(k, v)
    result = pad32(result)
  return addlen(result)

def StringFileInfo(data):
  result = struct.pack('hh', 0, 1)  # wValueLength, wType
  result = result + nullterm('StringFileInfo')
#  result = pad32(result) + StringTable('040904b0', data)
  result = pad32(result) + StringTable('040904E4', data)
  return addlen(result)

def Var(key, value):
  result = struct.pack('hh', len(value), 0)  # wValueLength, wType
  result = result + nullterm(key)
  result = pad32(result) + value
  return addlen(result)

def VarFileInfo(data):
  result = struct.pack('hh', 0, 1)  # wValueLength, wType
  result = result + nullterm('VarFileInfo')
  result = pad32(result)
  for k, v in data.iteritems():
    result = result + Var(k, v)
  return addlen(result)

def VS_VERSION_INFO(maj, min, sub, build, sdata, vdata, debug=0, is_dll=1):
  ffi = VS_FIXEDFILEINFO(maj, min, sub, build, debug, is_dll)
  result = struct.pack('hh', len(ffi), 0)  # wValueLength, wType
  result = result + nullterm('VS_VERSION_INFO')
  result = pad32(result) + ffi
  result = pad32(result) + StringFileInfo(sdata) + VarFileInfo(vdata)
  return addlen(result)

def stamp(pathname, options):
  # For some reason, the API functions report success if the file is open
  # but doesnt work!  Try and open the file for writing, just to see if it is
  # likely the stamp will work!
  try:
    f = open(pathname, "a+b")
    f.close()
  except IOError, why:
    print "WARNING: File %s could not be opened - %s" % (pathname, why)

  ver = options.version
  try:
    bits = [int(i) for i in ver.split(".")]
    vmaj, vmin, vsub, vbuild = bits
  except (IndexError, TypeError, ValueError):
    raise ValueError("--version must be a.b.c.d (all integers) - got %r" % ver)
  
  ifn = options.internal_name
  if not ifn:
    ifn = os.path.basename(pathname)
  ofn = options.original_filename
  if not ofn:
    ofn = os.path.basename(pathname)

  sdata = {
    'Comments' : options.comments,
    'CompanyName' : options.company,
    'FileDescription' : options.description,
    'FileVersion' : ver,
    'InternalName' : ifn,
    'LegalCopyright' : options.copyright,
    'LegalTrademarks' : options.trademarks,
    'OriginalFilename' : ofn,
    'ProductName' : options.product,
    'ProductVersion' : ver,
    }
  vdata = {
    'Translation' : struct.pack('hh', 0x409,1252),
    }
  is_dll = options.dll
  if is_dll is None:
    is_dll = os.path.splitext(pathname)[1].lower() in '.dll .pyd'.split()
  is_debug = options.debug
  if is_debug is None:
    is_debug = os.path.splitext(pathname)[0].lower().endswith("_d")
  # convert None to blank strings
  for k, v in sdata.items():
    if v is None:
      sdata[k] = ""
  vs = VS_VERSION_INFO(vmaj, vmin, vsub, vbuild, sdata, vdata, is_debug, is_dll)

  h = BeginUpdateResource(pathname, 0)
  UpdateResource(h, 16, 1, vs)
  EndUpdateResource(h, 0)

  if options.verbose:
    print "Stamped:", pathname

if __name__ == '__main__':
  parser = optparse.OptionParser("%prog [options] filespec ...",
                                 description=__doc__)

  parser.add_option("-q", "--quiet",
                    action="store_false", dest="verbose", default=True,
                    help="don't print status messages to stdout")
  parser.add_option("", "--version", default="0.0.0.0",
                    help="The version number as m.n.s.b")
  parser.add_option("", "--dll",
                    help="""Stamp the file as a DLL.  Default is to look at the
                            file extension for .dll or .pyd.""")
  parser.add_option("", "--debug", help="""Stamp the file as a debug binary.""")
  parser.add_option("", "--product", help="""The product name to embed.""")
  parser.add_option("", "--company", help="""The company name to embed.""")
  parser.add_option("", "--trademarks", help="The trademark string to embed.")
  parser.add_option("", "--comments", help="The comments string to embed.")
  parser.add_option("", "--copyright",
                    help="""The copyright message string to embed.""")
  parser.add_option("", "--description", metavar="DESC",
                    help="The description to embed.")
  parser.add_option("", "--internal-name", metavar="NAME",
                    help="""The internal filename to embed. If not specified
                         the base filename is used.""")
  parser.add_option("", "--original-filename",
                    help="""The original filename to embed. If not specified
                            the base filename is used.""")
  
  options, args = parser.parse_args()
  if not args:
    parser.error("You must supply a file to stamp.  Use --help for details.")
  
  for g in args:
    for f in glob.glob(g):
      stamp(f, options)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.