jas*_*son 24 powershell powershell-5.0
我有一个模块设置就像一个其他脚本的库.我无法弄清楚如何在脚本范围调用中获取类声明Import-Module.我试着Export-Module用一个-class参数安排,比如-function,但是没有-class可用的.我只需要在每个脚本中声明该类吗?
设置:
import-module holidays这是这个类的样子:
Class data_block
{
$array
$rows
$cols
data_block($a,$r,$c)
{
$this.array = $a
$this.rows = $r
$this.cols = $c
}
}
Run Code Online (Sandbox Code Playgroud)
alx*_*x9r 17
using 很容易陷入困境该using关键字是易发生各种缺陷如下:
using语句不适用于不在PSModulePath的模块using.这是相当令人惊讶的,因为虽然一个模块可通过Get-Module该using声明根据模块的加载方式可能无法正常工作.using语句只能在"脚本"的最开头使用.没有组合[scriptblock]::Create()或New-Module似乎克服了这一点.传递给它的字符串Invoke-Expression似乎充当了一种独立的脚本; 一个using在这样的字符串类型的作品的开头声明.也就是说,Invoke-Expression "using module $path"可以成功,但模块内容可用的范围似乎是不可理解的.例如,如果Invoke-Expression "using module $path"在Pester脚本块中使用,则模块内的类不能从相同的Pester脚本块中获得.以上陈述基于这组测试.
ScriptsToProcess 似乎可靠地工作调用绑定到包含该类的模块的scriptblock似乎可靠地工作以导出类的实例,并且不会遇到陷阱ScriptsToProcess.考虑这个包含类并已导入的模块:
# this is like defining c in class.ps1 and referring to it in ScriptsToProcess
class c {
[string] priv () { return priv }
[string] pub () { return pub }
}
# this is like defining priv and pub in module.psm1 and referring to it in RootModule
New-Module {
function priv { 'private function' }
function pub { 'public function' }
Export-ModuleMember 'pub'
} | Import-Module
[c]::new().pub() # succeeds
[c]::new().priv() # fails
Run Code Online (Sandbox Code Playgroud)
ScriptsToProcess在绑定到模块的scriptblock内部调用会生成一个类型为的对象priv:
public function
priv : The term 'priv' is not recognized ...
+ [string] priv () { return priv } ...
Run Code Online (Sandbox Code Playgroud)
ili*_*ili 17
我找到了一种加载类的方法,而无需"使用模块".在MyModule.psd1文件中使用以下行:
ScriptsToProcess = @('Class.ps1')
Run Code Online (Sandbox Code Playgroud)
然后将您的类放在Class.ps1文件中:
class MyClass {}
Run Code Online (Sandbox Code Playgroud)
更新:虽然您不必在此方法中使用"使用模块MyModule",但您仍需要:
Lar*_*ens 14
根据此处和此处,您可以通过在PowerShell 5中执行以下操作来使用模块中定义的类:
using module holidays
Run Code Online (Sandbox Code Playgroud)
你几乎不能。根据about_Classes帮助:
类关键字
定义一个新类。这是真正的 .NET Framework 类型。类成员是公共的,但仅在模块范围内是公共的。您不能将类型名称作为字符串引用(例如,New-Object 不起作用),并且在此版本中,您不能在脚本外部使用类型文字(例如,[MyClass])/定义类的模块文件。
这意味着,如果您想获取一个data_block实例或使用操作这些类的函数,请创建一个函数,New-DataBlock并使其返回一个新data_block实例,然后您可以使用该实例来获取类方法和属性(可能包括静态方法和属性) 。
这当然不会按预期工作。
PowerShell 5 的想法是,您可以在扩展名为 .psm1 的单独文件中定义类。
然后您可以使用以下命令加载定义(例如):
using module C:\classes\whatever\path\to\file.psm1
Run Code Online (Sandbox Code Playgroud)
这必须是脚本中的第一行(在注释之后)。
造成如此痛苦的原因是,即使从脚本调用类定义,也会为整个会话加载模块。您可以通过运行看到这一点:
Get-Module
Run Code Online (Sandbox Code Playgroud)
您将看到您加载的文件的名称。无论您再次运行该脚本,它都不会重新加载类定义!(它甚至不会读取 psm1 文件。)这会导致很多人咬牙切齿。
有时 -有时- 您可以在运行脚本之前运行此命令,这将使用刷新的类定义重新加载模块:
Remove-Module file
Run Code Online (Sandbox Code Playgroud)
其中 file 是不带路径或扩展名的名称。不过,为了保证您的理智,我建议您重新启动 PowerShell 会话。这显然很麻烦;微软需要以某种方式清理这个问题。
在使用的语句是去它是否适合你的方式。否则这似乎也有效。
使用函数传递类
class abc{
$testprop = 'It Worked!'
[int]testMethod($num){return $num * 5}
}
function new-abc(){
return [abc]::new()
}
Export-ModuleMember -Function new-abc
Run Code Online (Sandbox Code Playgroud)
class abc{
$testprop = 'It Worked!'
[int]testMethod($num){return $num * 5}
}
function new-abc(){
return [abc]::new()
}
Export-ModuleMember -Function new-abc
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13261 次 |
| 最近记录: |