前提・実現したいこと
powershellで初めてクラスを作成してみたのですが
メインのスクリプトでクラスが定義してあるスクリプトを読み込んでも
New-object クラス
や[クラス]
のような使い方をしようとしても
インテリセンスに表示されません。
(定義したスクリプト上ではインテリセンスが使える)
クラスの利用自体は問題なくできているのですが
利用時すごく不便です。
今まで作成した関数にクラスを利用したほうが
扱いやすくなるものがいくつかあったので
書き直そうとした矢先にこの問題が発覚したので
困っています。
ご助言をお願い致します。
発生している問題・エラーメッセージ
定義したクラスが
別スクリプト上だとインテリセンスが使えない
該当のソースコード
クラスを定義しているスクリプト
powershell
1<# 2非同期で処理をする 3 情報源 4 guitarrapc_tech 様 5 タイトル : PowerShell による同期処理、非同期処理、並列処理 を考えてみる 6 URL : http://tech.guitarrapc.com/entry/2013/10/29/100946 7 8 *** 様 9 タイトル : [properties] Powershellクラスはget setプロパティを実装します 10 URL : https://code-examples.net/ja/q/25e096e 11#> 12using namespace System.Management.Automation.Runspaces; 13using namespace System.Collections; 14using namespace System.Threading; 15 16# クラスを定義します 17class _MultiThread 18{ 19 20 # ノーマル プロパティ 21 [array] $RunspaceCollection 22 23 # 非表示 プロパティ 24 hidden [RunspacePool] $runspacePool 25 26 # 完了 プロパティ 27 hidden [bool]$_AllCompleted = $($this | Add-Member ScriptProperty -Name 'AllCompleted' -Value { 28 $($this.runspaceCollection.RunSpace | sort IsCompleted -Unique).IsCompleted -eq $true 29 }) 30 31 # コンストラクター 32 _MultiThread ($MyHost) 33 { 34 # create Runspace 35 [initialsessionstate] $sessionstate = [initialsessionstate]::CreateDefault() 36 [int] $minPoolSize = [int] $maxPoolSize = 5000 37 $this.runspacePool = [runspacefactory]::CreateRunspacePool($minPoolSize, $maxPoolSize, $sessionstate, $MyHost) # create Runspace Pool 38 $this.runspacePool.ApartmentState = "STA" 39 $this.runspacePool.Open() # open pool 40 } 41 42 # スレッドの追加 43 [void]AddThread([scriptblock]$ScriptBlock) 44 { 45 # Main Invokation 46 [powershell] $powershell = [PowerShell]::Create().AddScript($ScriptBlock) 47 $powershell.RunspacePool = $this.runspacePool 48 $this.RunspaceCollection += New-Object -TypeName PSObject -Property @{ 49 Runspace = $powershell.BeginInvoke(); 50 powershell = $powershell 51 } 52 $powershell.Dispose() 53 } 54 55 # スレッドの追加 56 [void]AddThread([scriptblock]$ScriptBlock,[psobject]$Parameters) 57 { 58 # Main Invokation 59 [powershell] $powershell = [PowerShell]::Create().AddScript($ScriptBlock).AddParameters($Parameters) 60 $powershell.RunspacePool = $this.runspacePool 61 $this.RunspaceCollection += New-Object -TypeName PSObject -Property $( 62 [ordered]@{ 63 Runspace = $powershell.BeginInvoke(); 64 powershell = $powershell 65 } 66 ) 67 } 68 69 70 # 結果の取得 71 [object]GetResult() 72 { 73 # get process result and end powershell session 74 return $(foreach ($runspace in $this.runspaceCollection) 75 { 76 # get reuslt 77 $runspace.powershell.EndInvoke($runspace.Runspace) 78 }) 79 } 80 81 # デストラクタの代わり手動で実行 82 [void]Dispose() 83 { 84 if (!($this.runspacePool.runspacePool.IsDisposed)) 85 { 86 foreach ($Runspace in $this.RunspaceCollection) 87 { 88 $Runspace.powershell.Dispose() 89 } 90 91 # Dispose Runspace 92 $this.runspacePool.Dispose() 93 } 94 } 95} 96
メイン(利用側)のスクリプト
powershell
1#ここに大タイトルを記入# 2 3$ErrorActionPreference = "Stop" 4$Error.Clear() 5 6try 7{ 8#初期処理# 9 if (!($PSScriptRoot -eq "")) 10 { 11 #カレントディレクトリをスクリプトパスに設定 12 Set-Location -Path($PSScriptRoot) 13 } 14 #ライブラリパスの作成# 15 $PSScriptRoot = $(Convert-Path -Path $(Get-Location)) 16 $Library = "$PSScriptRoot\Library" 17 18 if (Test-Path -Path $Library) 19 { 20 #登録関数の削除 21 Remove-Item Function::_* 22 #ソースの取得 23 $SFuncs = $($(Get-ChildItem -Path $Library) | where {$_.Extension -eq ".ps1"} | foreach {$(Get-Content -Path $_.FullName) -join "`r`n"}) 24 #ソースの読み込み 25 $SFuncs | foreach {Invoke-Expression $_} 26 } 27 else 28 { 29 $PSScriptRoot = "" 30 $Library = "" 31 } 32 33 if ($(Get-Item function::_*).count -eq 0) 34 { 35 36 throw "関数が定義されていません。" 37 } 38 39 #ここに処理を描く# 40 $Thread = New-Object _MultiThread($host) 41 $Block = { 42 param 43 ( 44 [parameter( 45 mandatory, 46 position = 0)] 47 [int] 48 $Start, 49 50 [parameter( 51 mandatory, 52 position = 1)] 53 [int] 54 $End 55 ) 56 [int]$i = 0 57 58 foreach ($item in $Start..$End) 59 { 60 $i += $item 61 } 62 return $i 63 64 } 65 for ($i = 1; $i -le 10; $i++) 66 { 67 $Thread.AddThread( 68 $Block, 69 [ordered]@{ 70 Start = 1 71 End = $i 72 } 73 ) 74 } 75 while(!($Thread.AllCompleted)){} 76 $Thread.GetResult() 77 $Thread.Dispose() 78 Remove-Variable Thread 79} 80catch 81{ 82 Write-Host $Error 83 $null = read-host "Enter を押して終了" 84} 85
試したこと
クラスが定義してあるスクリプトの読み込み
- ドットソースによる読み込み
- Invoke-Expressionを利用した読み込み (記載のスクリプトはこの方法)
--追記--
「Ctrl + J」押したときに出てくるクラスのテンプレート
のクラス名だけ変えて確認しても
同様の状態になりました。
クラスの処理内容は関係ないようです。
補足情報(FW/ツールのバージョンなど)
メインのスクリプトにて
メインのスクリプトと同じ親フォルダ内にあるSys
フォルダを読み込むように
記述してあります。
そのSys
フォルダにクラス定義をしているスクリプトをps1
で保存していただければ
実行できるはずです。
win 10
Name Value
PSVersion 5.1.17134.228
PSEdition Desktop
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/10/19 00:13