为了账号安全,请及时绑定邮箱和手机立即绑定

3 个问题,每个问题都相关...是否可以循环函数声明、调用系统对象以及从字符串加载程序集?

3 个问题,每个问题都相关...是否可以循环函数声明、调用系统对象以及从字符串加载程序集?

C#
慕容3067478 2023-04-29 18:11:27
我有一些我认为很酷的想法,但我不知道如何让它全部发挥作用......所以,我会问......我有一个问题,他们都很相似,所以我觉得他们可能都有相同的答案,但我不确定。我试过使用 TypeDefinitions 、 Add-Type 、 New-Object 等,但这些都不起作用。我一直在搞乱所涉及的数学......尽管我尽了最大的努力?仍然没有弄清楚如何让它工作。我问过其他程序员,但他们可能都对我要完成的事情有错误的想法。所以这里...# Being able to call system objects, or system type objects from an array of common strings ( lets call each one it's own 'lego' ). ## Instead of ... #if ([ Security.Principal.WindowsPrincipal ][ Security.Principal.WindowsIdentity ]::GetCurrent()).IsInRole([ Security.Principal.WindowsBuiltInRole ]'Administrator'){ execute the script... }# You could do this...$0 = "." , "Windows" , "Security" , "Principal" , "Identity" , "BuiltInRole"$1 = -join $0[ 2 , 0 , 3 , 0 , 1 ]$2 = $0[ 3..5 ] | % { New-Object $1 + $_ }if (-join $2[0..1]::GetCurrent()).IsInRole($2[2]){ execute script }# Haven't gotten it working yet though, can't really call methods or types from a string as far as I know, but I know that SID strings are essentially calling types from a numerical index hence "S-1-5-21-...etc"```# Calling assemblies or assembly types from an array of strings (in the same manner as above for loading ASP.Net Assemblies - which are also system objects# Example of how they're loaded now....using System ;using System.Collections.Generic ;using System.Diagnostics ;using System.Linq ;using System.Threading.Tasks ;using Microsoft.AspNetCore.Mvc ;using securedigitsplus.Models ;# and how I'd like to load them in PowerShell and not even need the .cs files$0 = "System" , ".Collections.Generic" ,  ".Diagnostics" , ".Linq" , ".Threading.Tasks" , "#etc.....#"$1 = $0[0] , @( foreach ( $j in 1..4 ) | % { -join $0[0,$j] } )0..$1.count | % { using ( New-Object or Add-Type -TypeDeclaration $_ I've tried both with no success... }```我希望我已经对我正在尝试做的事情给出了足够好的解释或示例。一般的想法是我希望能够在某个时候在循环中创建 CmdLetBinding() ,特别是如果有一堆类似的并且 DefaultParameterSetName 似乎不是一个好的解决方案,但我'我现在只想用简单的功能/开关来做到这一点。如果有人认为“你想在这里重新发明轮子”......我想这有一些优点......但我的看法是,“没有什么是完美的,即使是其他人使用的轮子也不行......你有一个想要成长的想法。请问可以帮助实现这一目标的人。”
查看完整描述

1 回答

?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

从索引+连接字符串的数组中调用系统对象

如果您将.NET 类型名称存储在字符串中,

  • 转换为[type]将它们转换为类型对象;在 PSv5+ 中,您可以在此类类型对象上调用静态::new()方法创建该类型的实例

    • $typeName = 'System.DateTime'; $type = [type] $typeName; $instance = $type::new(0)

  • 或者(PSv4-),将类型名称字符串传递给以New-Object创建一个实例

    • $typeName = 'System.DateTime'; New-Object $typeName -Args 0

注意:在这两种情况下,您都需要知道要传递的适当构造函数参数(如果有)。


从字符串数组调用程序集或程序集类型

您的示例表明您希望将名称空间导入代码中,这样您就可以更方便地仅通过名称(例如,[Encoding])来引用类型,而不必使用类型的全名(例如,[System.Text.Encoding]),C# 将其实现为using <namespace>.

PowerShell 的等效功能是using namespace <type-name>,但它仅适用于文字类型名称(如在 C# 中)。

此外,与类型字面量(如 )不同[Text.Encoding],省略System组件不是可选的,因此using namespace System.Text有效,但using namespace Text没有(它被悄悄接受,但无效)。

Invoke-Expression您可以通过使用(否则应避免使用)来解决此问题:

$namespace = 'System.Collections'


Invoke-Expression "using namespace $namespace"


# Now you can access the types in namespace System.Collections by

# their mere name.

[ArrayList]  # short for: [System.Collections.ArrayList]

冗余相似函数调用的示例......减少冗余的想法


看起来您正在尝试动态定义函数。


由于 PowerShell 函数公开为名为 的PowerShell驱动器Function:,因此您可以使用Set-Content动态定义函数:


$f = "Console" , "Warning" , "Success" , "Error"

$m = "White" , "Yellow" , "Green" , "Red"


0..($f.Count-1) | ForEach-Object {


    if ( $_ -eq 0 ) {  

      Function Log { param($MSG) $MSG | Out-File $LogFile -Append -Force }

    }

    else {

      $funcName = $f[$_]

      Set-Content Function:$funcName @"

        param(`$MSG)

        Write-Host `$MSG -ForegroundColor $($m[$_])

        Log `$MSG

"@

    }


}

这将定义函数Log和包装函数Warning,Success和Error,它们在带有彩色控制台输出的调用之前Log。


请注意使用可扩展的here-string ( @"<newline>...<newline>"@) 将函数体定义为多行字符串(为了便于阅读),以及如何嵌入$字符。不应预先展开的必须转义为`$.


查看完整回答
反对 回复 2023-04-29
  • 1 回答
  • 0 关注
  • 97 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信