返回的整数不适用于 -eq 运算符。

huangapple go评论62阅读模式
英文:

Returned Integer from Function Not Working with -eq Operator

问题

这是您提供的代码的翻译部分:

我有以下函数将导出注册表键并在成功时返回0失败时返回1当我尝试使用 `-eq 0` 进行比较时当函数返回 `0` 时比较失败我甚至尝试将 `return #` 和 `$ExportResult` 都转换为 `[System.Int32]`,但这并没有起作用。有什么想法?

Function Export-Registry{
    param(
        [String]$Path
    )

    $ModifiedPath = $Path -replace "HKEY_CURRENT_USER", "HKCU" -replace "HKEY_LOCAL_MACHINE", "HKLM" -replace "HKCU:", "HKCU" -replace "HKLM:", "HKLM"

    try{
        Start-ProcessStdOutput -File "Reg" -Arguments "export `"$($ModifiedPath)`" `"$($RegBackupLocationPath)\WinHttp_Settings.reg`" /Y "
    }catch{
        Write-CLog $_.Exception.Message -Category 'Exception' -Source 'Reg'
    }

    if (Test-Path -Path "$($RegBackupLocationPath)\WinHttp_Settings.reg"){
        Write-CLog "Registry exported successfully." -Source "Info" -Category "Export-Registry"
        return 0
    }else{
        Write-CLog "Registry export failed" -Source "ERROR" -Category "Export-Registry"
        return 1
    }
}

这是检查部分

$ExportResult = Export-Registry -Path $RegBackupKey
if ($ExportResult -eq 0){
    #做一些事情
}else{
    #注册表导出失败
}

Get-Member -InputObject $ExportResult 输出

 TypeName: System.Object[]

Name           MemberType            Definition
----           ----------            ----------
Count          AliasProperty         Count = Length
Add            Method                int IList.Add(System.Object value)
...
SyncRoot       Property              System.Object SyncRoot {get;}

请注意,$ExportResult 的类型为 System.Object[],而不是预期的整数。这可能是导致比较失败的原因。您可能需要检查 Export-Registry 函数的返回值,确保它返回整数类型而不是数组。

英文:

I've got the following function that will export a registry key and will return 0 for success and 1 for failure. When I attempt to compare the result using -eq 0, the compare fails when the function returns 0. I've even tried casting both the return # and $ExportResult to [System.Int32], however that didn't work. Any ideas?

Function Export-Registry{
    param(
	    [String]$Path
    )

    $ModifiedPath = $Path -replace "HKEY_CURRENT_USER", "HKCU" -replace "HKEY_LOCAL_MACHINE", "HKLM" -replace "HKCU:", "HKCU" -replace "HKLM:", "HKLM"

    try{
	    Start-ProcessStdOutput -File "Reg" -Arguments "export `"$($ModifiedPath)`" `"$($RegBackupLocationPath)\WinHttp_Settings.reg`" /Y "
    }catch{
	    Write-CLog $_.Exception.Message -Category 'Exception' -Source 'Reg'
    }

    if (Test-Path -Path "$($RegBackupLocationPath)\WinHttp_Settings.reg"){
	    Write-CLog "Registry exported successfully." -Source "Info" -Category "Export-Registry"
	    return 0
    }else{
	    Write-CLog "Registry export failed" -Source "ERROR" -Category "Export-Registry"
	    return 1
    }
}

This is the check:

$ExportResult = Export-Registry -Path $RegBackupKey
if ($ExportResult -eq 0){
    #do stuff
}else{
    #registry export failed
}

Get-Member -InputObject $ExportResult output:

 TypeName: System.Object[]

Name           MemberType            Definition                                                                        
----           ----------            ----------                                                                        
Count          AliasProperty         Count = Length                                                                    
Add            Method                int IList.Add(System.Object value)                                                
Address        Method                System.Object&, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a...
Clear          Method                void IList.Clear()                                                                
Clone          Method                System.Object Clone(), 
System.Object ICloneable.Clone()                           
CompareTo      Method                int 
IStructuralComparable.CompareTo(System.Object other, System.Collections.ICo...
Contains       Method                bool IList.Contains(System.Object value)                                          
CopyTo         Method                void CopyTo(array array, int index), void CopyTo(array array, long index), void...Equals         Method                bool Equals(System.Object obj), bool 
IStructuralEquatable.Equals(System.Object ...
Get            Method                System.Object Get(int )                                                           
GetEnumerator  Method                System.Collections.IEnumerator 
GetEnumerator(), System.Collections.IEnumerator ...
GetHashCode    Method                int GetHashCode(), int IStructuralEquatable.GetHashCode(System.Collections.IEqu...
GetLength      Method                int GetLength(int dimension)                                                      
GetLongLength  Method                long GetLongLength(int dimension)                                                 
GetLowerBound  Method                int GetLowerBound(int dimension)                                                  
GetType        Method                type GetType()                                                                    
GetUpperBound  Method                int GetUpperBound(int dimension)                                                  
GetValue       Method                System.Object GetValue(Params int[] indices), System.Object GetValue(int index)...
IndexOf        Method                int IList.IndexOf(System.Object value)                                            
Initialize     Method                void Initialize()                                                                 
Insert         Method                void IList.Insert(int index, System.Object value)                                 
Remove         Method                void IList.Remove(System.Object value)                                            
RemoveAt       Method                void IList.RemoveAt(int index)                                                    
Set            Method                void Set(int , System.Object )                                                    
SetValue       Method                void SetValue(System.Object value, int index), void SetValue(System.Object valu...
ToString       Method                string ToString()                                                                 
Item           ParameterizedProperty System.Object IList.Item(int index) {get;set;}                                    
IsFixedSize    Property              bool IsFixedSize {get;}                                                           
IsReadOnly     Property              bool IsReadOnly {get;}                                                            
IsSynchronized Property              bool IsSynchronized {get;}                                                        
Length         Property              int Length {get;}                                                                 
LongLength     Property              long LongLength {get;}                                                            
Rank           Property              int Rank {get;}                                                                   
SyncRoot       Property              System.Object SyncRoot {get;}           

答案1

得分: 2

答案是,你自定义的函数之一,要么是 Start-ProcessStdOutput 要么是 Write-CLog(很可能是前者),正在写入到成功流(stdout,因此成为函数输出的一部分,这就是为什么你得到一个 object[] 而不是 int32 作为输出类型。

因此,比较 $ExportResult -eq 0 失败,因为一些比较运算符(其中之一是 -eq)在比较的左侧是集合时可以充当_过滤器_,即:

$foo = 0..10
$foo -eq 0 # 输出 `0` 而不是布尔值

然后,0 在强制转换为 boolean 时变为 $false。详见关于布尔值

$foo = 0..10
[bool] ($foo -eq 0) # 变为 `$false`

if 条件的上下文中也是一样的:

$foo = 0..10
if($foo -eq 0) { 'foo' } # 产生没有输出

解决你的问题的方法要么是__捕获或重定向__来自你自定义函数的输出,要么从中写入到不同的流,比如详细或信息流(Write-VerboseWrite-Host),这样你的函数只输出一个 int32

英文:

Answer is, one of your custom functions, either Start-ProcessStdOutput or Write-CLog (presumably the former) is writing to the Success Stream (stdout) thus becoming part of your function's output which is why you are getting an object[] instead of int32 as output type.

In consequence, the comparison $ExportResult -eq 0 fails because some comparison operators (-eq being one of them) can act as filters when there is a collection on the left-hand side of the comparison, i.e:

$foo = 0..10
$foo -eq 0 # outputs `0` instead of a boolean

And then 0 when coerced to a boolean becomes $false. See about Booleans for details:

$foo = 0..10
[bool] ($foo -eq 0) # becomes `$false`

Same happens in the context of an if condition:

$foo = 0..10
if($foo -eq 0) { 'foo' } # produces no output

Solution to your problem is to either capture or redirect the output from your custom functions, or write to a different stream from them, i.e. verbose or information streams (Write-Verbose or Write-Host so that your function only outputs an int32).

huangapple
  • 本文由 发表于 2023年4月20日 04:36:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76058629.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定