Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell doesn't load System.Net.Http assembly and ignore Add-Type within script

I'm trying to use HttpClient with a custom HttpClientHandler (to fix a Cookie issue not correctly managed with redirection).

Both are into the System.Net.Http assembly (and namespace) and Powershell (and ISE) can't see the classes (nor the namespace) most of the time.

It does find a class System.Net.Http (in fact it is WebRequestMethods.Http) which I won't be surprised breaks everything.

So I created this KISS sample:

using namespace System.Net.Http

class Wtf : HttpClientHandler {
}

$t = [HttpClient]::new()

If I run it, it will tell me the type doesn't exist. (It also does if I use the full namespace instead of using).

What is funny however is what comes next. If I use the same code within ISE, the IDE will only tell me the base class HttpClient can't be found. (Nothing about the instantiation)

I found that Add-Type can help me here, so I add

Add-Type -AssemblyName System.Net.Http

Write-Host "Hello World"

between using namespace System.Net.Http and class Wtf : HttpClientHandler {

I still got the same error when trying to run it - but I don't see my "Hello World" at all! So it seems to fail when parsing it and it doesn't even try to run it. ISE still displays the same error within the IDE.

Then if I run Add-Type -AssemblyName System.Net.Http before running the script again (both from a PowerShell prompt or the ISE) everything runs without an issue. Also from then, the ISE IDE intellisense can list everything within the System.Net.Http namespace.

So how can a user only start my PowerShell script instead of having to both run Add-Type and my script?

I'm using PS 5.1 on Win10 and I'm new with the PowerShell environment, though I do have a C# background.

EDIT1: Use HttpClientHandler instead of HttpClient (but whatever the issue is the same)

EDIT2: Here what I'm using right now

using assembly System.Net.Http
using namespace System.Net.Http

class Test : HttpClient {
}

[HttpClient]::new()

Here's the output:

Au caractère C:\Users\0xdcdcdcd\Desktop\Test.ps1:4 : 14
+ class Test : HttpClient {
+              ~~~~~~~~~~
Type [HttpClient] introuvable.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TypeNotFound
like image 599
0xCDCDCDCD Avatar asked Aug 22 '19 02:08

0xCDCDCDCD


2 Answers

# test.ps1
Add-Type -AssemblyName System.Net.Http

class Test : system.Net.Http.HttpClient {
}


At C:\users\admin\test.ps1:3 char:14
+ class Test : system.Net.Http.HttpClient {
+              ~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [system.Net.Http.HttpClient].
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : TypeNotFound

I understand now. It's crazy that it doesn't work in a script. I believe some solutions are offered here: Powershell: Unable to find type when using PS 5 classes

EDIT: Actually, this works for me in PS 6. If you're in Windows 10 1809, a lot of the commands work again in PS 6.

like image 156
js2010 Avatar answered Nov 15 '22 04:11

js2010


So how can a user only start my PowerShell script instead of having to both run Add-Type and my script?

It's pretty common to see advanced PowerShell scripts begin with a few using statements, so you could begin your script like so:

using assembly System.Net.Http
using namespace System.Net.Http
#your code here

But most of the time in modern PowerShell, especially for web commands you can and should begin by using the PowerShell cmdlet.

My question to you then is what is it you're looking to do with HttpClient? Let me know what you want to do and I will be happy to show you the 'PowerShell' way to do it :)

like image 40
FoxDeploy Avatar answered Nov 15 '22 03:11

FoxDeploy