/ / “Você não pode chamar um método em uma expressão de valor nulo” ao passar parâmetros para o powershell - c #, powershell, cmd

“Você não pode chamar um método em uma expressão de valor nulo” ao passar parâmetros para o PowerShell - c #, PowerShell, cmd

Estou tentando analisar alguns parâmetros para um script que estou executando no PowerShell. Mas estou recebendo erros ao executar o script dizendo que eles estão vazios.

Estou começando o processo assim:

string input1 = "Powershell.exe -File " + Config.Directory + "/ICS.ps1" + " -toggle "" + toggle + "" -par1 "" +
par1 + "" -par2 "" + par2 + "" -connectionInterface "" + connectionInterface + """;

//(for readability) input1 will look something like this:
//Powershell.exe -File map/to/ICS.ps1 -toggle "EnableSharing" -par1 "0" -par2 "1" -connectionInterface "Ethernet"

string[] output = CmdProcess.Exec(input1);

CmdProcess.Exec é um método que criei para executar rapidamente um processo cmd. funciona assim

public static string[] Exec(params string[] parameters)
{
Process cmd = new Process
{
StartInfo =
{
UseShellExecute = false,
Verb = "runas",
FileName = @"cmd.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
}
};
cmd.Start();

foreach (string parameter in parameters)
{
cmd.StandardInput.WriteLine(parameter);
}
cmd.StandardInput.WriteLine("exit");
return Regex.Split(cmd.StandardOutput.ReadToEnd(), "rn");
}

a razão de eu usar o cmd para executar o PowerShell éporque tentei com uma instância do PowerShell *, mas travou por um motivo desconhecido em computadores muito rápidos (embora seja executado normalmente se você executá-lo manualmente). *System.Management.Automation.Powershell

no script eu escrevi isto: (No início do script)

Param( [string]$toggle, [string]$par1, [string]$par2, [string]$connectionInterface )

Mas dá um erro de que os parâmetros são nulos:

You cannot call a method on a null-valued expression.
At C:UsersJeremyAppDataRoamingHotspotLauncherICS.ps1:10 char:1
+ $config.$toggle($par1)
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

Recebo erros como este com todos os parâmetros. Não apenas $toggle ou $par1.


Eu tentei correr Powershell.exe e -File ..... separadamente, mas isso fez com que meu fio pendurasse.
Também tenho 100% de certeza toggle, par1 e o resto (no código C #) não são nulos
Eu também tentei adicionar [CmdletBinding()] antes de o params no script, mas isso não fez nada:

[CmdletBinding()]Param( [string]$toggle, [string]$par1, [string]$par2, [string]$connectionInterface )


Aqui está o script do PowerShell:

[CmdletBinding()]Param( [string]$toggle, [string]$par1, [string]$par2, [string]$connectionInterface )

regsvr32 hnetcfg.dll /s
$m = New-Object -ComObject HNetCfg.HNetShare
$m.EnumEveryConnection |% { $m.NetConnectionProps.Invoke($_) }
$c = $m.EnumEveryConnection |? { $m.NetConnectionProps.Invoke($_).Name -eq $connectionInterface }
$config = $m.INetSharingConfigurationForINetConnection.Invoke($c)
Write-Output $config.SharingEnabled
Write-Output $config.SharingConnectionType
$config.$toggle($par1)

$m2 = New-Object -ComObject HNetCfg.HNetShare
$m2.EnumEveryConnection |% { $m2.NetConnectionProps.Invoke($_) }
$c2 = $m2.EnumEveryConnection |? { $m2.NetConnectionProps.Invoke($_).DeviceName -Match "Microsoft Hosted Network Virtual Adapter" }
$config2 = $m2.INetSharingConfigurationForINetConnection.Invoke($c2)
Write-Output $config2.SharingEnabled
Write-Output $config2.SharingConnectionType
$config2.$toggle($par2)

Este script ativa / desativa o compartilhamento da Internet para o $connectionInterface que pode ser algo como Ethernet ou Wifi, e definir como público ($par1) / ou nada se tiver que ser desativado. e faz o mesmo para microsoft hostingnetwork e define-o como privado ($par2).

Respostas:

1 para resposta № 1

Não bifurque um novo processo com powershell.exe - usar a API em vez de:

using System.Collections.ObjectModel;
using System.IO;
using System.Management.Automation;
//...

using(PowerShell ps = PowerShell.Create())
{
ps.AddScript(Path.Combine(Config.Directory, "ICS.ps1"))
.AddParameter("toggle", toggle)
.AddParameter("par1", par1)
.AddParameter("par2", par2)
.AddParameter("connectionInterface", connectionInterface);
Collection<PSObject> results = ps.Invoke();
}

Lembre-se de adicionar uma referência ao System.Management.Automation.dll montagem para o seu projeto