5

I've searched but did not find any answer.
The task is register one dll using Powershell ps1, followed by other lines of scripts. I don't want to be interrupted by the dialog, so added the /s parameter. But now the result information is ignored, no matter succeed or fail. I want the result displayed in console. But how?

Lei Yang
  • 3,970
  • 6
  • 38
  • 59

4 Answers4

7

Launch regsvr32.exe /s with Start-Process -PassThru and inspect the ExitCode property:

$regsvrp = Start-Process regsvr32.exe -ArgumentList "/s C:\path\to\your.dll" -PassThru
$regsvrp.WaitForExit(5000) # Wait (up to) 5 seconds
if($regsvrp.ExitCode -ne 0)
{
    Write-Warning "regsvr32 exited with error $($regsvrp.ExitCode)"
}
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
5

Here is a more complete full powershell cmdlet with pipeline support.

function Register-Dll
{
    <#
    .SYNOPSIS
        A function that uses the utility regsvr32.exe utility to register a file
    .PARAMETER Path
        The file path
    .PARAMETER Unregister
        when specified, unregisters instead of registers
    #>
    [CmdletBinding()]
    param (
        [ValidateScript({ Test-Path -Path $_ -PathType 'Leaf' })]       
        [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipeLineByPropertyName=$true)]
        [Alias("FullName")]
        [string[]]$Path,
        [Alias("u")]
        [switch]$Unregister
        )
    begin {
        if ($Unregister)
        {
            $regflag = "-u "
        }
        else
        {
            $regflag = ""
        }
        [int]$NumFailed=0
        $RegExitCodes = @{
            0="SUCCESS";
            1="FAIL_ARGS - Invalid Argument";
            2="FAIL_OLE - OleInitialize Failed";
            3="FAIL_LOAD - LoadLibrary Failed";
            4="FAIL_ENTRY - GetProcAddress failed";
            5="FAIL_REG - DllRegisterServer or DllUnregisterServer failed.";
        }
    }
    process {
        foreach ($p in $path)
        {
            try
            {
                $regsvrp = Start-Process regsvr32.exe -ArgumentList "/s $regflag <code>$p</code>" -Wait -NoNewWindow -PassThru

                if($regsvrp.ExitCode -ne 0)
                {
                    $NumFailed++
                    Write-Error "regsvr32 $regflag for $p exited with error $($regsvrp.ExitCode) - $($RegExitCodes[$regsvrp.ExitCode])"
                }
            } catch {
                $NumFailed++
                Write-Error $_.Exception.Message
            }
        }
    }
    end {
        if ($NumFailed -gt 0)
        {
            if ($Unregister)
            {
                $mode = "unregister"
            }
            else
            {
                $mode = "register"
            }
            Write-Error "Failed to $mode $NumFailed dll's, see previous errors for detail"
        }
    }
}

Usage:

function Register-MyAppDll
{

    param(
        [Parameter(Mandatory=$true,ParameterSetName="Both")]
        [switch]$ReRegister,
        [Parameter(Mandatory=$true,ParameterSetName="UnregisterOnly")]
        [Alias("u")]
        [switch]$UnRegister,
        [Parameter(Mandatory=$true,ParameterSetName="RegisterOnly")]
        [Alias("r")]
        [switch]$Register
    )


    $RegOptions = @()
    if ($UnRegister -or $ReRegister) { $RegOptions += @{Unregister=$true} }
    if ($Register -or $ReRegister) { $RegOptions += @{} }

    $dlltoregister = Get-ChildItem "C:\MyApp\bin" -Filter *.dll | where {$_ -notmatch '^interop'}

    foreach ($RegOpt in $RegOptions)
    {
        $dlltoregister | Register-Dll @RegOpt
    }

}


Register-MyAppDll -UnRegister
Register-MyAppDll -Register
Register-MyAppDll -ReRegister 

Enjoy :)

Justin
  • 1,303
  • 15
  • 30
4

Thank you Justin! I'm using this script and it works great.

There seems to be a typo in the following line of code:

$regsvrp = Start-Process regsvr32.exe -ArgumentList "/s $regflag <code>$p</code>" -Wait -NoNewWindow -PassThru

The code tag shoudn't be there. I changed it to the following with added escaped double quotes around path to support spaces in paths:

$regsvrp = Start-Process regsvr32.exe -ArgumentList "/s $regflag `"$p`"" -Wait -NoNewWindow -PassThru 
0
& regsvr32.exe /s your.dll | Out-Null

if (-Not($?)) { 
   Write-Error "failed: $LASTEXITCODE" 
}

works for me.

From https://ss64.com/ps/out-null.html:

When running an external Windows .EXE executable from a PowerShell script, by default the script will not wait and will immediately continue to the next command. Piping the command to out-null or out-default will force PowerShell to wait for the process to exit before continuing.

riezebosch
  • 1,950
  • 16
  • 29
  • Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P Aug 16 '23 at 20:36