home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Shareware / Comunicatii / jyte / jyte.exe / verstamp.py < prev    next >
Text File  |  2003-10-24  |  6KB  |  200 lines

  1. #
  2. # stamp a file with version information
  3. #
  4. # USAGE: python verstamp.py <major> <minor> <version> <fname> <desc> \
  5. #                           [<debug>] [<is_dll>]
  6. #
  7. # For example:
  8. #  C> python verstamp.py 1 4 103 pywintypes.dll "Common Python types for Win32"
  9. #
  10. #  This will store version "1.4.0.103" (ie, build 103 for Python 1.4)
  11. #
  12. #
  13. # <debug> : 0 or 1 based on whether it's a debug build (DEFAULT == 0)
  14. # <is_dll> : 0 or 1 to indicate the file type: DLL vs EXE (DEFAULT == 1)
  15. #
  16.  
  17. from win32api import BeginUpdateResource, UpdateResource, EndUpdateResource, Unicode
  18. import win32api
  19. #print "Win32api is at", win32api.__file__
  20. U = Unicode
  21.  
  22. import os
  23. import sys
  24. import struct
  25. import string
  26. import win32api
  27. import pythoncom
  28.  
  29. VS_FFI_SIGNATURE = 0xFEEF04BD
  30. VS_FFI_STRUCVERSION = 0x00010000
  31. VS_FFI_FILEFLAGSMASK = 0x0000003f
  32. VOS_NT_WINDOWS32 = 0x00040004
  33.  
  34. g_productname = 'Python'
  35. g_company = ''
  36. g_copyright = 'Copyright (C) A Few Assorted People 1995-1998.  All rights reserved.'
  37. g_trademarks = ''
  38.  
  39. #
  40. # Set VS_FF_PRERELEASE and DEBUG if Debug
  41. #
  42. def file_flags(debug):
  43.   if debug:
  44.     return 3    # VS_FF_DEBUG | VS_FF_PRERELEASE
  45.   return 0
  46.  
  47. def file_type(is_dll):
  48.   if is_dll:
  49.     return 2    # VFT_DLL
  50.   return 1    # VFT_APP
  51.  
  52. def VS_FIXEDFILEINFO(maj, min, sub, build, debug=0, is_dll=1):
  53.   return struct.pack('lllllllllllll',
  54.                      VS_FFI_SIGNATURE,    # dwSignature
  55.                      VS_FFI_STRUCVERSION,    # dwStrucVersion
  56.                      (maj << 16) | min,    # dwFileVersionMS
  57.                      (sub << 16) | build,# dwFileVersionLS
  58.                      (maj << 16) | min,    # dwProductVersionMS
  59.                      (sub << 16) | build,        # dwProductVersionLS
  60.                      VS_FFI_FILEFLAGSMASK,    # dwFileFlagsMask
  61.                      file_flags(debug),    # dwFileFlags
  62.                      VOS_NT_WINDOWS32,    # dwFileOS
  63.                      file_type(is_dll),    # dwFileType
  64.                      0x00000000,    # dwFileSubtype
  65.                      0x00000000,    # dwFileDateMS
  66.                      0x00000000,    # dwFileDateLS
  67.                      )
  68.  
  69. def nullterm(s):
  70.   try:
  71.     return buffer(unicode(s)) + "\0\0"
  72.   except NameError: # No unicode builtin
  73.     return U(s).raw + '\0\0'
  74.  
  75. def pad32(s, extra=2):
  76.   # extra is normally 2 to deal with wLength
  77.   l = 4 - ((len(s) + extra) & 3)
  78.   if l < 4:
  79.     return s + ('\0' * l)
  80.   return s
  81.  
  82. def addlen(s):
  83.   return struct.pack('h', len(s) + 2) + s
  84.  
  85. def String(key, value):
  86.   key = nullterm(key)
  87.   value = nullterm(value)
  88.   result = struct.pack('hh', len(value)/2, 1)    # wValueLength, wType
  89.   result = result + key
  90.   result = pad32(result) + value
  91.   return addlen(result)
  92.  
  93. def StringTable(key, data):
  94.   key = nullterm(key)
  95.   result = struct.pack('hh', 0, 1)    # wValueLength, wType
  96.   result = result + key
  97.   for k, v in data.items():
  98.     result = result + String(k, v)
  99.     result = pad32(result)
  100.   return addlen(result)
  101.  
  102. def StringFileInfo(data):
  103.   result = struct.pack('hh', 0, 1)    # wValueLength, wType
  104.   result = result + nullterm('StringFileInfo')
  105. #  result = pad32(result) + StringTable('040904b0', data)
  106.   result = pad32(result) + StringTable('040904E4', data)
  107.   return addlen(result)
  108.  
  109. def Var(key, value):
  110.   result = struct.pack('hh', len(value), 0)    # wValueLength, wType
  111.   result = result + nullterm(key)
  112.   result = pad32(result) + value
  113.   return addlen(result)
  114.  
  115. def VarFileInfo(data):
  116.   result = struct.pack('hh', 0, 1)    # wValueLength, wType
  117.   result = result + nullterm('VarFileInfo')
  118.   result = pad32(result)
  119.   for k, v in data.items():
  120.     result = result + Var(k, v)
  121.   return addlen(result)
  122.  
  123. def VS_VERSION_INFO(maj, min, sub, build, sdata, vdata, debug=0, is_dll=1):
  124.   ffi = VS_FIXEDFILEINFO(maj, min, sub, build, debug, is_dll)
  125.   result = struct.pack('hh', len(ffi), 0)    # wValueLength, wType
  126.   result = result + nullterm('VS_VERSION_INFO')
  127.   result = pad32(result) + ffi
  128.   result = pad32(result) + StringFileInfo(sdata) + VarFileInfo(vdata)
  129.   return addlen(result)
  130.  
  131. def stamp(vars, pathname, desc, verbose=0, debug=0, is_dll=1):
  132.   # For some reason, the API functions report success if the file is open
  133.   # but doesnt work!  Try and open the file for writing, just to see if it is
  134.   # likely the stamp will work!
  135.   try:
  136.     f = open(pathname, "a+b")
  137.     f.close()
  138.   except IOError, why:
  139.     print "WARNING: File %s could not be opened - %s" % (pathname, why)
  140.  
  141.   try:
  142.     maj = int(vars.get("major"))
  143.     min = int(vars.get("minor"))
  144.     sub = int(vars.get("sub", 0))
  145.     build = int(vars.get("build"))
  146.   except (IndexError, TypeError):
  147.     raise RuntimeError, "The version params must be integers"
  148.  
  149.   company = vars.get("company", g_company)
  150.   copyright = vars.get("copyright", g_copyright)
  151.   trademarks = vars.get("trademarks", g_trademarks)
  152.   productname = vars.get("product", g_productname)
  153.  
  154.  
  155.   vsn = '%s.%s.%s.%s' % (maj, min, sub, build)
  156.   dir, fname = os.path.split(pathname)
  157.   fname = string.upper(fname)
  158.   sdata = {
  159.     'Comments' : desc,
  160.     'CompanyName' : company,
  161.     'FileDescription' : desc,
  162.     'FileVersion' : vsn,
  163.     'InternalName' : fname,
  164.     'LegalCopyright' : copyright,
  165.     'LegalTrademarks' : trademarks,
  166.     'OriginalFilename' : fname,
  167.     'ProductName' : productname,
  168.     'ProductVersion' : vsn,
  169.     }
  170.   vdata = {
  171.     'Translation' : struct.pack('hh', 0x409, 1200),
  172.     }
  173.   vs = VS_VERSION_INFO(maj, min, sub, build, sdata, vdata, debug, is_dll)
  174.  
  175.   h = BeginUpdateResource(pathname, 0)
  176.   UpdateResource(h, 16, 1, vs)
  177.   EndUpdateResource(h, 0)
  178.  
  179.   if verbose:
  180.     print "Stamped:", pathname
  181.  
  182. if __name__ == '__main__':
  183.   if len(sys.argv) < 6:
  184.     print "ERROR: incorrect invocation. See comments in header of script."
  185.     sys.exit(1)
  186.  
  187.   maj = string.atoi(sys.argv[1])
  188.   min = string.atoi(sys.argv[2])
  189.   ver = string.atoi(sys.argv[3])
  190.  
  191.   verbose = 0
  192.   is_dll = 1
  193.   if len(sys.argv) > 6:
  194.     debug = string.atoi(sys.argv[6])
  195.     if len(sys.argv) > 7:
  196.       is_dll = string.atoi(sys.argv[7])
  197.  
  198.   v={'major':maj,'minor':min,'build':ver}
  199.   stamp(v, sys.argv[4], sys.argv[5], verbose, is_dll)
  200.