2010-11-17 10 views
6

Básicamente quiero crear una variable que se ejecute cada vez. Para el ejemplo más sencillo:¿Es posible crear mi propia 'variable automática'?

$myvar = `write-host foo`; 

Entonces cada vez que se hace referencia $ mivar, sería foo de salida:

dir $myvar 

Directory of foo: 

El punto es que la parte write-host foo podría ser re-ejecutado cada vez que me refiero $ mivar

+1

por qué no usar un método? http://www.computerperformance.co.uk/powershell/powershell_functions.htm – asawyer

+0

En su ejemplo, dir $ myvar no funcionaría, porque write-host no se generaría para dir. Desea escribir-salida, pero realmente no necesita eso, solo necesita '$ myvar = 'foo'' – Jaykul

Respuesta

5

Es posible en código administrado (C#/VB) al crear su propia clase PSVariable, pero no directamente en script puro, lo siento. Digo "script puro" porque en powershell v2 puedes alinear C# con add-type. Dicho esto, podría hackearlo en secuencias de comandos confiando en llamadas ToString implícitas, pero esto no sería confiable en todas las situaciones. Ejemplo:

# 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 

Tenga en cuenta que el conteo de ticks es diferente en cada evaluación de la variable. Si, por supuesto, si solo usa una función normal en lugar de una variable, esto es mucho más fácil.

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 

Esperanza esto ayuda

-Oisin

+1

. Me encanta que haya pensado en usar la anulación de ToString para eso. Si sigue así, asegúrese de crear la variable ReadOnly, Constant, AllScope para que no se sobrescriba, y recuerde que es solo eso cuando la convierte en cadena. De lo contrario, es algo más. x0n: Eres un genio enfermo, enfermo :) – Jaykul

+0

Por alguna razón, no funciona igual que una variable automática, pero realmente cerca. Por ejemplo: "dir c: \; dir $$" hará lo mismo. Pero con su método anterior "dir c: \; dir $ o" no lo hace. Requiere que haga "dir c: \; dir ($ o)" que es cómico: P – esac

+0

para el registro: $$ es como $ o en mi ejemplo (que acabo de agregar a continuación) no se calcula a pedido , se establece después de ejecutar cada comando. Quería mencionar esa alternativa ayer, pero me distraí. – Jaykul

2

La otra manera se puede implementar este tipo de cosas, simplemente es para forzar un nuevo cálculo de la función pronto para que la variable se actualiza cada vez que una orden es y aparezca el símbolo:

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

por supuesto, que se traduce en que se ejecutan cada vez en lugar de a la carta

2

No es tan difícil completar lo que @ x0n menciona. Podemos insertar un trozo de C# en nuestro código y obtener una verdadera variable automática:

# 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 

Sobre PSVariable:

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

Cuestiones relacionadas