0

我正在编写一个 Powershell 脚本,我必须在其中创建几个临时文件。我偶然发现了一个听起来对管理此任务非常有用的 .net 类:[System.CodeDom.Compiler.TempFileCollection]。

但是由于某些奇怪的原因,我无法创建对象。这是我尝试做的事情:

$a = new-object CodeDom.Compiler.TempFileCollection -argumentlist "C:\folder1\"

调用后 $a 为空。

但是,如果我这样做:

(new-object CodeDom.Compiler.TempFileCollection -argumentlist "C:\folder1\").tempdir

它返回:

C:\folder1\

这意味着已经创建了一个对象。我似乎无法将其保存到变量中!有人知道这是为什么吗?

另一个奇怪的事情:

new-object CodeDom.Compiler.TempFileCollection -argumentlist "C:\folder1\" | gm

回报:

Name          MemberType Definition                                                                                         
----          ---------- ----------                                                                                         
AddExtension  Method     string AddExtension(string fileExtension), string 
...

但是,这会返回一个异常(Get-Member:没有为 get-member cmdlet 指定对象。):

(new-object CodeDom.Compiler.TempFileCollection -argumentlist "C:\folder1\") | gm

我很抱歉把这个问题表述得如此糟糕,我不知道如何更好地解释它。

任何帮助将非常感激。

4

1 回答 1

0

TL;DR:它不是空的。

您如何验证 $a 是否为空?我想如果你真的尝试使用它,它会正常工作:

PS> $a = New-Object CodeDom.Compiler.TempFileCollection -argumentlist "C:\folder1\"
PS> $a.TempDir
C:\folder1\
PS> $a.AddFile("test1.txt",$false)
PS> $a.AddFile("test2.txt",$false)
PS> $a
C:\Users\Jaykul\AppData\Local\Temp\test2.txt
C:\Users\Jaykul\AppData\Local\Temp\test1.txt
PS>

简而言之,您遇到的问题是当您通过管道发送集合时,PowerShell 会展开集合(即输出集合的内容)。那是因为否则,当您键入时:

PS> $a = Get-ChildItem
PS> $a

您只会看到它是一个数组:System.Object[]...

在这种情况下,您几乎总是希望查看数组的内容。顺便说一句:这是一个很好的例子,说明 PowerShell首先是一种 shell 语言,然后是一种脚本语言:它优先考虑 shell 的正确行为。

无论如何,可枚举集合的展开有一些例外(字符串是 IEnumerable,但未展开),事实上,我认为New-Object ... |是特殊情况,这就是为什么它将 New-Object 管道传输到 Get-Member 的原因. 当然,一旦将其包裹在括号中,您就创建了一个单独解析的子表达式,因此当您编写时:

(new-object CodeDom.Compiler.TempFileCollection -argumentlist "C:\folder1\") | gm

你基本上有两个管道,新对象的特殊处理消失了,你的集合被展开,它的内容(什么都没有,因为它是空的)沿着管道传递。

您可以通过使用一元逗号运算符来避免这种情况:

$a = new-object CodeDom.Compiler.TempFileCollection -argumentlist "C:\folder1\"
,$a | gm

或 ,(new-object CodeDom.Compiler.TempFileCollection -argumentlist "C:\folder1\") | 通用汽车

或者直接将其传递给 -InputObject 参数,而不是通过管道。

$a = new-object CodeDom.Compiler.TempFileCollection -argumentlist "C:\folder1\"
gm -InputObject $a

但是,当您使用花哨的集合时,并且想要查看集合对象本身的属性时,您可能需要同时执行以下两个操作:

PS> ft -in (,$a)

    Count TempDir            BasePath                    KeepFiles SyncRoot               IsSynchronized
    ----- -------            --------                    --------- --------               --------------
        3 C:\folder1\        C:\folder1\t22jmahj             False                                 False
于 2013-05-31T04:46:03.983 回答