2

名前と日付 (サードパーティ アプリケーションから取得される - この場合は svn.exe) の 2 つの列を持つ情報のテーブルを生成する PowerShell スクリプトを作成しようとしています。

スクリプト全体はうまく機能しますが、サーバーが DataTable に送り返す日付を取得するのに苦労しています。これが私のスクリプトの簡略版です。

# Set up a DataTable and initialise columns
$table = New-Object system.Data.DataTable “Test Table”
$col1 = New-Object system.Data.DataColumn Name,([string])
$col2 = New-Object system.Data.DataColumn DateFromServer,([DateTime])
$table.columns.add($col1)
$table.columns.add($col2)

# Create a new row and add the data
$row = $table.NewRow()
$row.Name = "Test"
$lastCommit = GetDateFromExternalApp
$lastCommit.GetType() # this returns DateTime as I would expect
$row.DateFromServer = $lastCommit # this throws up an error
$table.Rows.Add($row)

# Output the table
$table | Format-Table -AutoSize

# This function simulates what the actual function does
# (the real one goes to SVN and pulls down data, but it
# ends up with the same resulting date)
Function GetDateFromExternalApp
{   
    $externalAppDate = "2012-09-17T16:33:57.177516Z"

    return [DateTime]($externalAppDate)
}

問題 (上記のスクリプトのコメントに記載) は、関数が DateTime インスタンスを喜んで返しているように見えますが、これをテーブル行の DateFromServer 列に追加しようとするとエラーが発生することです:

Exception setting "DateFromServer": "Unable to cast object of type 'System.Management.Automation.PSObject' to type 'System.IConvertible'.Couldn't store <18/09/2012 2:33:57 AM> in DateFromServer  Column.  Expected type is DateTime." At line:13 char:6
+ $row. <<<< DateFromServer = $lastCommit
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyAssignmentException

ただし、 $lastCommit.GetType() への呼び出しは、これが実際に DateTime であることを示しています。実際、スクリプトのどこかに次の行を追加すると、次のようになります。

$lastCommit

次に、適切にフォーマットされた日時を確認できます。これは、実際にそれを解析して正しく変換していることを示しています。

Date        : 18/09/2012 12:00:00 AM
Day         : 18
DayOfWeek   : Tuesday
DayOfYear   : 262
Hour        : 2
Kind        : Local
Millisecond : 177
Minute      : 33
Month       : 9
Second      : 57
Ticks       : 634835324371775160
TimeOfDay   : 02:33:57.1775160
Year        : 2012
DateTime    : Tuesday, 18 September 2012 2:33:57 AM

そのため、上記の例外が発生する理由については非常に困惑しています。PowerShell では関数の戻り値が C# とは異なることに気付きましたが、関数が正しい型を返しているように見えます。

4

3 に答える 3

4

ここでの問題は、PowerShell の型適応システムのバグによるものです (まだ報告していない場合は、Microsoft に報告することをお勧めします)。

PowerShell でオブジェクトを操作する場合、実際にはPSObjectラッパーを操作しています。ほとんどの呼び出し ( などGetType) は基になるオブジェクトに転送されますが、オブジェクト自体と相互作用しないメンバーを追加することもできます。

PS> Get-Date | Add-Member NoteProperty Yowza 'for example' -PassThru | Format-List y*
Yowza : for example
Year  : 2012


PowerShell には広範な型強制機能があるため、通常、これは問題になりません。ただし、プロパティ アクセス構文をサポートするために使用される型DataRowにバグがあるようです。の代わりにインデクサーを直接DataRowAdapter使用すると、値は .NET 型に送信される前に正しくラップ解除されます。$row['DateFromServer'] = $lastCommit$row.DateFromServer

キャストを使用するか ( vonPryz が既に示したように: [DateTime]$lastCommit)、またはBaseObject( ) を取得することで、自分で値をアンラップすることで、これを回避することもできます$lastCommit.PSObject.BaseObject

于 2012-09-29T00:22:32.163 に答える
3

この行動の理由も知りたいです。

とにかく、日付変数を DateTime としてキャストするか、明示的に宣言することで問題を回避できます。そのようです、

...
$row.DateFromServer = [DateTime]$lastCommit # Doesn't throw exception
...

または

...
[DateTime]$lastCommit = GetDateFromExternalApp
$row.DateFromServer = $lastCommit # Doesn't throw exception
...
于 2012-09-19T05:56:52.187 に答える
0

理由はエラーメッセージに記載されているとおりだと思います。

「タイプ'System.Management.Automation.PSObject'のオブジェクトをタイプ'System.IConvertible'にキャストできません...予期されるタイプはDateTimeです。」行:13文字:6

つまり、PowerShellは$ lastCommitを日付と時刻に変換しようとしましたが、失敗しました。vonPryzが示唆しているように、最善の方法は、[datetime]にキャストすることです。

問題をより明確に確認するには、$ lastcommit.gettype()と$ row.DateFromServer.gettype()の両方を調べてみてください。

チェックするGetDateFromExternalAppがありません

于 2012-09-19T09:43:29.033 に答える