Welcome, guest | Sign In | My Account | Store | Cart

This is a way to parse command line from user provided string or try to get the original Argv from Windows OS Platform.

Python, 37 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import sys,os
import ctypes
import win32api
import pprint
import win32con
class cscargv:
	def __init__(self,CommandLine=None):
		if CommandLine==None:
			CommandLine=win32api.GetCommandLine()
		argv_count=ctypes.c_int()
		self.cmd_string=ctypes.c_wchar_p(CommandLine)
		CommandLineToArgvW=ctypes.windll.shell32.CommandLineToArgvW
		self.array_memory_address=CommandLineToArgvW(self.cmd_string,ctypes.byref(argv_count))
		match_array_type=ctypes.c_wchar_p*argv_count.value
		self.raw_result=match_array_type.from_address(self.array_memory_address)
		self.result=[arg for arg in self.raw_result]
		self.argv=self.result[:]
	def __str__(self):
		return pprint.pformat(self.result)
	def __repr__(self):
		return repr(self.raw_result)
	def results(self):
		return self.result
	def argvs(self):
		return self.result
	def __del__(self):
		if self.array_memory_address != win32con.NULL:
			retval = ctypes.windll.kernel32.LocalFree(self.array_memory_address)
			if retval != win32con.NULL:
				raise Exception( "LocalFree() failed." )
		else:
			raise Exception( "CommandLineToArgvW() failed." )
if __name__=='__main__':
	c2a=cscargv()
	print c2a
	print repr(c2a)
	print c2a.argv

Note: It try to show how to use the ctype.from_address to extract Pointer type as return value by DLL function call. It is another trick to parse a command line string ... Please refer link below: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/commandlinetoargv.asp

some correction base on suggestion, Thank a lot !

1 comment

Atul Varma 17 years, 4 months ago  # | flag

Possible Memory Leak. Thank you for this example. However, I believe that you also need to free the memory used by the argument list once you've finished calling CommandLineToArgvW(), e.g.:

if array_memory_address != win32con.NULL:
  retval = ctypes.windll.kernel32.LocalFree( array_memory_address )
  if retval != win32con.NULL:
    raise Exception( "LocalFree() failed." )
else:
  raise Exception( "CommandLineToArgvW() failed." )

I may be mistaken since I'm fairly new to ctypes, however.