Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell Add-Type : Cannot add type. already exist

I'm using PowerShell script to run C# code directly in the script. I've run in to an error a particular error a few times. If I make any changes to the C# code in the PowerShell ISE and try to run it again I get the following error.

Add-Type : Cannot add type. The type name 'AlertsOnOff10.onOff' already exists.
At C:\Users\testUser\Desktop\test.ps1:80 char:1
+ Add-Type -TypeDefinition $Source -ReferencedAssemblies $Assem
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (AlertsOnOff10.onOff:String) [Add-Type], Exception
    + FullyQualifiedErrorId : TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand

The way I have been resolving this error is by changing the namespace and the command to call the C# method [AlertsOnOff10.onOff]::Main("off"). I there a way I can prevent this error from happening without having to change namespace and method call?

like image 593
zingwing Avatar asked Sep 08 '14 18:09

zingwing


3 Answers

For those who want to avoid the error or avoid loading the type if it's already been loaded use the following check:

if ("TrustAllCertsPolicy" -as [type]) {} else {
        Add-Type "using System.Net;using System.Security.Cryptography.X509Certificates;public class TrustAllCertsPolicy : ICertificatePolicy {public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) {return true;}}"
        [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}

I post this because you get the error OP posted if you make even superficial (e.g. formatting) changes to the C# code.

like image 180
Marc Avatar answered Oct 12 '22 14:10

Marc


To my knowledge there is no way to remove a type from a PowerShell session once it has been added.

The (annoying) workaround I would suggest is to write your code in one ISE session, and execute it in a completely different session (separate console window or separate ISE if you want to be able to debug).

This only matters if you're changing $Source though (actively developing the type definition). If that's not the part that's changing, then ignore the errors, of if it's a terminating error use -ErrorAction to change it.

like image 31
briantist Avatar answered Oct 12 '22 14:10

briantist


You can execute it as a job:

$cmd = {    

    $code = @'
        using System;

        namespace MyCode
        {
            public class Helper
            {
                public static string FormatText(string message)
                {
                    return "Version 1: " + message;
                }
            }
        }
'@

    Add-Type -TypeDefinition $code -PassThru | Out-Null

    Write-Output $( [MyCode.Helper]::FormatText("It Works!") )
}

$j = Start-Job -ScriptBlock $cmd

do 
{
    Receive-Job -Job $j

} while ( $j.State -eq "Running" )
like image 42
Jeff D Avatar answered Oct 12 '22 12:10

Jeff D