System.CodeDom.Compiler.CompilerParameters
(1)
Microsoft.CSharp.CSharpCodeProvider
(1)
UnmanagedType.LPTStr
(1)
CSharpCodeProvider.CompileAssemblyFromSource
(1)
System.IO.FileInfo
(1)
System.Runtime.InteropServices
(1)
ServerKey.PSPath
(1)
GetShortPathName
(1)

ProgID of a exe

Asked By Mugunth
14-Sep-07 03:54 AM
Is it possible to get the ProgID of an executable whose path is
known?
For example, I want to get
InternetExplorer.Application if I pass iexplore.exe (full path)...

Regards,
Mugunth

ProgID of a exe

Asked By Jeff
14-Sep-07 08:58 AM
I'm sure there is a better way to do this, but this is what I came up
with:

param( [string]$filePath = $( throw "You must provide a path to a COM
server." ), [switch]$ShowProgress )

if ( !( Test-Path "$( Get-Location)\PathShortener.dll" ) )
{
$code = @'
using System;
using System.Text;
using System.Runtime.InteropServices;

public class PathShortener
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto,
SetLastError = true)]
public static extern int GetShortPathName(
[MarshalAs( UnmanagedType.LPTStr )] string lpszLongPath,
[MarshalAs( UnmanagedType.LPTStr )] StringBuilder
lpszShortPath,
uint cchBuffer);

public static string GetShortPath( string longPath )
{
string shortPath = longPath;
StringBuilder shortPathBuilder = new StringBuilder(260);

int result = GetShortPathName( longPath,
shortPathBuilder,

(uint)shortPathBuilder.Capacity );

if ( result > 0 )
{
shortPath = shortPathBuilder.ToString();
}

return shortPath;
}
}
'@

$cSharpCodeProvider = New-Object
Microsoft.CSharp.CSharpCodeProvider

$parameters = New-Object
System.CodeDom.Compiler.CompilerParameters
$parameters.GenerateInMemory = $true
$parameters.GenerateExecutable = $false
$parameters.OutputAssembly = "$( Get-Location)\PathShortener.dll"

$compilerResults =
$cSharpCodeProvider.CompileAssemblyFromSource( $parameters, $code )

if ( $results.Errors.Count -gt 0 )
{
Throw "Could not compile PathShortener class"
}
}

[System.Reflection.Assembly]::LoadFile( "$( Get-Location)
\PathShortener.dll" ) | Out-Null

$longPath = $filePath.ToLower()
$shortPath = [PathShortener]::GetShortPath( $filePath ).ToLower()

if ( ( New-Object System.IO.FileInfo $longPath ).Extension.ToLower() -
eq ".exe" )
{
$serverKeys = Get-Item HKLM:\SOFTWARE\Classes\CLSID\*
\LocalServer32
}
else
{
$serverKeys = Get-Item HKLM:\SOFTWARE\Classes\CLSID\*
\InProcServer32
}

$serverCount = $serverKeys.Length
$serverProgress = 0;

foreach ( $serverKey in $serverKeys )
{
if ( $ShowProgress )
{
Write-Progress -Activity "Searching servers for
'$filePath'..." `
-Status "Progress:" `
-PercentComplete ( ( $serverProgress++ /
$serverCount ) * 100 )
}

if ( $serverKey.GetValue( "" ) )
{
$foundPath = $serverKey.GetValue( "" ).ToLower() -replace '"'

if ( $foundPath -eq $longPath -or $foundPath -eq $shortPath )
{
if ( $serverKey.PSPath -match "\\([^\\]+)\\[^\\]+$" )
{
$clsid = $matches[ 1 ].ToLower()

$clsidKeys = Get-Item HKLM:\SOFTWARE\Classes\*\CLSID

$clsidCount = $clsidKeys.Length
$clsidProgress = 0

foreach ( $clsidKey in $clsidKeys )
{
if ( $ShowProgress )
{
Write-Progress -Activity "Searching CLSIDs for
'$clsid'..." `
-Status "Progress:" `
-PercentComplete
( ( $clsidProgress++ / $clsidCount ) * 100 )`
-Id 1
}

if ( $clsidKey.GetValue( "" ) -and
$clsidKey.GetValue( "" ).ToLower() -eq $clsid )
{
if ( $clsidKey.PSPath -match "\\([^\\]+)\\CLSID
$" )
{
$matches[ 1 ]
}
}
}
}
}
}
}

Use it like this:

PSH$ .\Get-ProgId.ps1 'C:\Program Files\Internet Explorer
\iexplore.exe' -ShowProgress

This attempts to list all ProgIds associated with the file passed in
as a parameter.  I say "attempts" because I am sure I missed
something.  I had to put the GetShortPathName call in because short
paths are used quite often in the registry.  It is really slow, but it
seems to do the trick.  I added a switch parameter that determines
whether progress is displayed, since Write-Progress calls slow it down
so much more.

Jeff

Since I've started playing with WMI I've found that there is a class which

Asked By BobLanda
14-Sep-07 10:54 AM
Since I've started playing with WMI I've found that there is a class which
will list literally ANYTHING which is on a machine.

get-WMIObject  Win32_ClassicCOMClassSetting | ? {$_.ProgId -like "*expl*"}

will get you started. This class has all the properites you need.

The hard part of course if _finding_ which class to use. This appears to
take experience and looking through the doc's.

get-WMIObject -list  | ? {$.name -like "*<sub string of the thing your
after>*"

can help.

Good luck
bob

ProgID of a exe

Asked By Tao Ma
14-Sep-07 10:55 AM
I hope this trivial code may help you.

PS C:\> Get-Process | ?{$_.path -eq 'C:\Program Files\Alcohol Soft\Alcohol
120\StarWind\StarWindService.exe'} | %{$_.id}


Tao Ma
Best wishes!
ProgID of a exe
Asked By Tao Ma
14-Sep-07 11:16 AM
sorry, this is wrong answer...
Post Question To EggHeadCafe