Use an external program like psinfo to pull out a list of registered programs.
Scan every .exe on the machine and pull out the publisher, program name and version. You can do this with File::Find::Rule and Win32::AdminMisc. This is the approach taken with SMS 2003 and many other vendors in commercial inventory/patching systems. There's a code example for this up at codeproject.com.