是否可以创建自己的“自动变量”?

时间:2010-11-17 20:18:03

标签: powershell

我基本上想要创建一个每次都会执行的变量。最简单的例子:

$myvar = `write-host foo`;

然后每当我引用$ myvar时,它都会输出foo:

dir $myvar

Directory of foo:

关键是每次引用$ myvar时都会重新执行write-host foo部分

3 个答案:

答案 0 :(得分:5)

通过创建自己的PSVariable派生类在托管代码(C#/ VB)中可行,但不是直接在纯脚本中,抱歉。我说“纯脚本”,因为在powershell v2中你可以使用add-type内联C#。也就是说,您可以依靠隐式ToString调用在脚本中破解它,但这在每种情况下都不可靠。例如:

# empty custom object
$o = new-object psobject

# override ToString with a PSScriptMethod member
$o.psobject.members.add((new-object `
     System.Management.Automation.PSScriptMethod "ToString", {
         "ticks: $([datetime]::now.ticks)" }))

ps> $o
ticks: 634256043148813794

ps> $o
ticks: 634256043165574752

请注意,每次评估变量时,滴答计数都不同。如果你只是使用常规函数而不是变量,那么这就容易多了。

function Ticks { [datetime]::now.ticks }

# use as a parameter - note the use of ( and )
ps> write-host (ticks)
634256043148813794

# use in a string - note the use of $( and )
ps> write-host "ticks $(ticks)"
ticks 634256043165574752

希望这有帮助

-Oisin

答案 1 :(得分:2)

另一种方法是简单地强制重新计算提示函数,以便每次完成命令并显示提示时更新变量:

$MySecretOldPromptStorage = ${Function:Prompt}
function prompt { $o = $([datetime]::now.ticks); &$MySecretOldPromptStorage }

当然,这会导致它每次运行而不是按需运行

答案 2 :(得分:2)

完成@ x0n提及的内容并不困难。我们可以在代码中嵌入一段C#并获得一个真正的自动变量:

# define a class of my variable, override the Value property
Add-Type @'
using System;
using System.Management.Automation;
public class MyVariable : PSVariable
{
    public MyVariable(string name) : base(name) {}
    public override object Value
    {
        get { return DateTime.Now.Ticks; }
        set { }
    }
}
'@

# install the variable
$ExecutionContext.SessionState.PSVariable.Set((New-Object MyVariable Ticks))

# test
$Ticks
sleep 1
$Ticks
sleep 1
$Ticks

关于PSVariable

http://msdn.microsoft.com/en-us/library/system.management.automation.psvariable