#!/usr/bin/python
# -*- coding: cp1250 -*-
__version__ = '$Id: which_dll.py 516 2008-10-03 08:51:44Z mn $'

"""
Returns the pathnames of the file (.exe or .dll)
which would be loaded/executed in the current environment
it uses some dirs from configuration (SystemDir, WindowsDir)
and dirs from PATH.

It uses code from Python Cookbook recipe 67682 by Joshua W. Biagio from:
http://code.activestate.com/recipes/67682/
so it could also show version info. Simply:
-download it, 
-save as version.py in PYTHONPATH directory
-comment line "print 'No Version Information Available'"

Example of usage:
c:\tools\pyscripts\scripts>which_dll.py libpq.dll
2008-06-09 02:58:26	  167936 [b]	c:\postgresql\8.3\bin\libpq.dll	ver:8.3.3.8160
2008-03-17 01:47:50	  167936 [b]	c:\tools\libpq.dll	ver:8.3.1.8075
2008-03-17 01:47:50	  167936 [b]	g:\public\libpq.dll	ver:8.3.1.8075
	trying to load "libpq.dll" ...
	c:\postgresql\8.3\bin\libpq.dll loaded

Author: Michal Niklas
"""

USAGE = 'Usage:\n\twhich_dll.py dll_name/exe_name'

import sys
import time
import os
import os.path
import win32api


VERCHECKER_ERR = 0


def get_file_info(file_path):
	"""returns string with file name, its modification time and size"""
	global VERCHECKER_ERR
	s = os.stat(file_path)
	f_date = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(s[8]))
	f_size = s[6]
	fv = ''
	try:
		if VERCHECKER_ERR == 0:
			import verchecker
			try:
				fv = '\tver:' + verchecker.calcversioninfo(file_path)
			except:
				pass
	except:
		if VERCHECKER_ERR == 0:
			print "\tNo verchecker.py module! Look at: http://code.activestate.com/recipes/67682/"
			VERCHECKER_ERR = 1
	return "%s\t%8s [b]\t%s%s" % (f_date, f_size, file_path, fv)



def which(fname):
	"""searches fname in PATH dirs"""
	if not which_file(fname):
		if not '.' in fname:
			# no extension, so we try some "executable" extensions
			for ext in ('.exe', '.com', '.bat', '.cmd'):
				fname2 = fname + ext
				if which_file(fname2):
					break


def which_file(fname):
	"""prints paths for fname where fname can be found,
	in case of .dll loads it"""
	files = []
	path = win32api.GetEnvironmentVariable('PATH')
	# try paths as described in MSDN
	dirs = [os.getcwd(), win32api.GetSystemDirectory(), win32api.GetWindowsDirectory()] + path.split(';')
	for d in dirs:
		fname2 = os.path.join(d, fname)
		if os.path.exists(fname2):
			if not fname2 in files:
				files.append(fname2)
	if files:
		print '\n'.join([get_file_info(f) for f in files])
	h = 0
	if fname.lower().endswith('.dll'):
		print '\ttrying to load "%s" ...' % (fname)
		try:
			h = win32api.LoadLibrary(fname)
			if h:
				dll_name = win32api.GetModuleFileName(h)
				print '\t%s loaded' % (dll_name)
		except:
			print '\tCannot load "%s" !!!' % (fname)


def main():
	if '--version' in sys.argv:
		print __version__
		return
	elif '--help' in sys.argv:
		print USAGE
		return
	elif '--test' in sys.argv:
		which('libpq.dll')
		which('libeay32.dll')
		which('msvcr71.dll')
		which('ssleay32.dll')
		which('cmd.exe')
		which('grep')
		which('non_existient.dll')
		return
	if len(sys.argv) < 2:
		print USAGE
	else:
		which(sys.argv[1])


main()
