in reply to A little help with Win32::API?
Below is how I would have implemented the solution. In short, I'd use constants instead of magical values, and I'd hide C-ish bits in a sub that provides an interface better suited to Perl.
use v5.10.0; use strict; use warnings; use Win32::API qw( ); use constant MAX_PATH => 260; use constant MAX_FEATURE_CHARS => 38; use constant { INSTALLSTATE_NOTUSED => -7, # component disabled INSTALLSTATE_BADCONFIG => -6, # configuration data corrupt INSTALLSTATE_INCOMPLETE => -5, # installation suspended or in p +rogress INSTALLSTATE_SOURCEABSENT => -4, # run from source, source is una +vailable INSTALLSTATE_MOREDATA => -3, # return buffer overflow INSTALLSTATE_INVALIDARG => -2, # invalid function argument INSTALLSTATE_UNKNOWN => -1, # unrecognized product or featur +e INSTALLSTATE_BROKEN => 0, # broken INSTALLSTATE_ADVERTISED => 1, # advertised feature INSTALLSTATE_REMOVED => 1, # component being removed (actio +n state, not settable) INSTALLSTATE_ABSENT => 2, # uninstalled (or action state a +bsent but clients remain) INSTALLSTATE_LOCAL => 3, # installed on local drive INSTALLSTATE_SOURCE => 4, # run from source, CD or net INSTALLSTATE_DEFAULT => 5, # use default, local or source }; my %INSTALLSTATE_DESC = ( INSTALLSTATE_NOTUSED() => 'The component being requested is d +isabled on the computer', INSTALLSTATE_BADCONFIG() => '[configuration data corrupt]', INSTALLSTATE_INCOMPLETE() => '[installation suspended or in prog +ress]', INSTALLSTATE_SOURCEABSENT() => 'The component source is inaccessib +le', INSTALLSTATE_MOREDATA() => '[return buffer overflow]', INSTALLSTATE_INVALIDARG() => 'One of the function parameters is +invalid', INSTALLSTATE_UNKNOWN() => 'The product code or component ID i +s unknown', INSTALLSTATE_BROKEN() => '[broken]', INSTALLSTATE_ADVERTISED() => '[advertised feature]', INSTALLSTATE_REMOVED() => '[component being removed (action s +tate, not settable)]', INSTALLSTATE_ABSENT() => 'The component is not installed', INSTALLSTATE_LOCAL() => 'The component is installed locally +', INSTALLSTATE_SOURCE() => 'The component is installed to run +from source', INSTALLSTATE_DEFAULT() => '[use default, local or source]', ); { # UINT MsiGetShortcutTarget( # __in LPCTSTR szShortcutTarget, # __out LPTSTR szProductCode, # __out LPTSTR szFeatureId, # __out LPTSTR szComponentCode # ); my $MsiGetShortcutTarget = Win32::API->new( 'msi.dll', 'MsiGetShortcutTarget', 'PPPP', 'N'); sub MsiGetShortcutTarget { my ($szShortcutTarget) = @_; $szShortcutTarget .= "\0"; my $szProductCode = "\0" x 39; my $szFeatureId = "\0" x (MAX_FEATURE_CHARS+1); my $szComponentCode = "\0" x 39; return () if $^E = $MsiGetShortcutTarget->Call( $szShortcutTarget, $szProductCode, $szFeatureId, $szComponentCode, ); s/\0.*//s for $szProductCode, $szFeatureId, $szComponentCode; return ( $szProductCode, $szFeatureId, $szComponentCode ); } } { # INSTALLSTATE MsiGetComponentPath( # __in LPCTSTR szProduct, # __in LPCTSTR szComponent, # __out LPTSTR lpPathBuf, # __inout DWORD *pcchBuf # ); my $MsiGetComponentPath = Win32::API->new( 'msi.dll', 'MsiGetComponentPath', 'PPPP', 'I'); sub MsiGetComponentPath { my ($szProduct, $szComponent) = @_; $szProduct .= "\0"; $szComponent .= "\0"; my $lpPathBuf = "\0" x MAX_PATH; my $pcchBuf = pack('L', MAX_PATH); my $rv = $MsiGetComponentPath->Call( $szProduct, $szComponent, $lpPathBuf, $pcchBuf, ); return ( $rv, substr($lpPathBuf, 0, unpack('L', $pcchBuf)) ); } } { my $shortcut = 'Microsoft Office Word 2007.lnk'; my ($product, $feature, $component) = MsiGetShortcutTarget($shortc +ut) or die("MsiGetShortcutTarget: $^E\n"); say "product: $product"; say "feature: $feature"; say "component: $component"; my ($install_state, $path) = MsiGetComponentPath($product, $component); say "install state: $INSTALLSTATE_DESC{$install_state}"; say "install path: $path"; }
Untested (since I don't know of what advertised shortcuts exist on my machine).
Update: Changed +CONSTANT to CONSTANT() for hash keys.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: A little help with Win32::API? (cleanup)
by flamey (Scribe) on Apr 25, 2010 at 08:54 UTC | |
by ikegami (Patriarch) on Apr 25, 2010 at 16:11 UTC | |
by flamey (Scribe) on Apr 26, 2010 at 14:31 UTC | |
|
Re^2: A little help with Win32::API? (cleanup)
by flamey (Scribe) on Apr 25, 2010 at 09:00 UTC |