2011/12/19

はじめに

PowerShell Advent Calendar 2011の19日目の記事、そしてこれが私の記事では3回目となります。今回も前々回前回からの引き続きでバックグラウンドジョブについての話題です。前回までは現行バージョンであるPowerShell 2.0におけるバックグラウンドジョブの機能の使い方を解説してきましたが、今回はPowerShellの次期バージョンである3.0に追加される予定の機能のうち、ジョブ関係のものをピックアップしてみます。現在PowerShell 3.0を含むWindows Management Framework(WMF)3.0のCTP2が公開されています。またWindows 8 Developer Preview / Windows Server 8 Developer PreviewにはWMF3.0 CTP1相当のPowerShell 3.0が含まれています。

注意:本記事で取り上げた内容は製品のプレビュー版をもとに記述しています。そのためリリース版では内容が一致しない可能性があることをご承知おきください。

using:ラベル

前回、ジョブに値を渡す方法について解説しましたが、-argumentListに引数として渡すというのは正直めんどうです。呼び出し元のグローバル変数を直接ジョブ側から参照したいですよね。そこでPowerShell v3では新たに変数に付けるusing:ラベルというのが追加されました。このラベルをジョブのスクリプトブロック内で使うと、呼び出し元の変数を参照することができます。具体例。

$test="PowerShell 3.0"
Start-Job {$using:test}|Wait-Job|Receive-Job

とすると、「PowerShell 3.0」と表示され、たしかにジョブのスクリプトブロックから呼び出し元の変数を参照できていることがわかります。これは便利ですね。ただし残念ながらこの方法を使ってもスクリプトブロックをジョブに渡すことはできないようです。相変わらず文字列にキャストされてしまいました。

Receive-Jobコマンドレットの変更点

前々回に、Invoke-Command -asJobで複数リモートコンピュータに対してジョブを走らせた場合、そのジョブに対して$job|Receive-Jobがなぜか機能しない、と書きましたがこの問題が解決されています。そもそもなんでこの問題が発生していたのか、面白いのでちょっと解説します。

実はReceive-Jobコマンドレットの-locationパラメータに「パイプライン入力を許可する   true (ByPropertyName)」フラグがついていたのが原因でした。複数コンピュータに対して実行したジョブは子ジョブを複数持ちますが、親ジョブ自体は配列ではありません。そしてそのLocationプロパティには子ジョブが実行されているコンピュータ名が"remote01,remote02,remote03"のようなカンマ区切りの文字列として格納されています。よってこのジョブオブジェクトをパイプラインを通じてReceive-Jobコマンドレットに渡すと、ValueFromPipelineByPropertyName属性が付いている-locationパラメータにジョブオブジェクトのLocationプロパティの値が渡されますが、その値はカンマ区切りの文字列なので正しく解釈されず、結果として期待の動作をしなかったわけです。

v3ではReceive-Job -locationのValueFromPipelineByPropertyName属性が取り除かれ、問題なく動作するようになりました。

他の変更点としてはReceive-Jobにジョブが完了するまで待つための-waitパラメータが追加されました。が、$job|Wait-Job|Receive-Jobと違いが分からないかも…。

Get-Jobコマンドレットの変更点

Get-Jobに-filterパラメータが追加されました。連想配列でジョブにフィルタをかけられるものです。

Get-Job -filter @{State="Completed";Location="localhost"}

where-objectを使わずともフィルタできるので便利、かも。しかし個人的には-filterパラメータはいろんなコマンドレットで定義されているものの、使い方がそれぞれ異なるのがとてもとてもイヤです。まず覚えられないのでヘルプを引くところから始まっちゃいますので。パフォーマンスの関係上、Where-Objectを使うよりコマンドレット内部でフィルタしたほうが速くなるというのはわかるのですが、もう少しフィルタ方式に統一性を持たせられなかったんだろうかとか思いますね。

Get-Jobにはほかに-afterと-beforeというパラメータが追加されています。これは後述するPSScheduledJobの完了時刻をDateTimeで範囲指定し、フィルタするものです。

PowerShell Workflow

PowerShell3.0というかWMF3.0のおそらく目玉機能の一つがPowerShell Workflowです。文字通り、PowerShellでワークフローが記述できるようになります。

Workflowは関数の一種なのですが、長時間を要するタスクやリモート実行や並列実行などで使うことを主目的としているようです。functionキーワードの代わりにworkflowキーワードでワークフローを定義すると、自動的に実行対象コンピュータ名や資格情報といったパラメータが複数定義されるので、これらのパラメータを特に定義なしで利用することができます。またworkflow内ではparallelブロックを定義でき、その中に記述された各行は並列に実行されます。またfor/foreachステートメントで-parallelパラメータが利用可能になり、繰り返し処理やコレクションの列挙を並列して行うことができるようになります。

自動定義されるパラメータに-asJobがあり、これを利用するとworkflowをジョブとして実行できます。このジョブは通常のジョブとは違い、新たに追加されたSuspend-JobコマンドレットとResume-Jobを使うことによって、ジョブの一時中断と再開ができます。このジョブの中断と再開は、リモートコンピュータ上でワークフローを走らせてるときでも可能ですし、中断後リモートセッションが切断されたあとに再開することもできますし、リモートコンピュータがシャットダウンしても再起動後にジョブを再開することまでできてしまいます。これらはWMFにおけるリモート基盤を支えているWinRMの最新バージョン、WinRM3.0が実現している機能です。このようにセッションを再接続してもタスクを継続できるような接続をrobust(堅牢な), resilient(弾力性のある、障害から容易に回復する) connectionと称しているようです。

PowerShell WorkflowはWindows Workflow Foundation(WF)と密接な関係があり、WFのデザイナで作ったxamlをPS Workflowに変換したり(逆もできる?)、Invoke-Expressionでxamlを実行したりできるらしいです。WF側でもPowerShellの多くの機能がアクティビティとして使用できたりして、WFとPowerShellがWMFというシステム管理フレームワークの主要なパーツとして密に連携していくようです。このあたりの話はWFの専門家であるAhfさんがPSアドベントカレンダーの23日目にしてくださる予定なので、楽しみですね!

なおPS Workflowは従来のPSスクリプトとは異なった利用状況を想定しているため、あるいはWFの機能と合わせるため、PSスクリプトではできるのにPS Workflowではできないことがとてもたくさんあります。forの中でbreakやcontinueステートメントが使えないとかStart-Sleepは-Secondパラメータしか指定できない(ミリ秒単位でスリープかけられない)とか色々あります。そのうちPS WorkflowとPSスクリプトの違いというドキュメントが公開されるんじゃないかと思います。

ちなみにWinRM3.0のおかげでワークフローではない通常のリモートジョブでも、New-PSSessionで作成したセッションの中でジョブを実行した場合、そのジョブが動作しているコンピュータへのセッションを切断(Disconnect-PSSession)したあと、セッションに再接続(Connect-PSSessionやReceive-PSSession)すればジョブの結果を取得したりすることができます。またセッションを作製したインスタンス(powershell.exe)でそのセッションを切断すると、それ以降は別のインスタンスやコンピュータからそのセッションにConnect-PSSessionで接続することができます。

ScheduledTasksモジュール

PowerShell3.0が含まれる次期Windowsでは大量のモジュールが追加され、それらのモジュールに含まれるコマンドレットの総数はWindows 8でも2000を超える膨大な量になります。これはWindows 8やWindows Server 8では従来のコマンドプロンプトから実行するコンソールexeコマンドのほとんどすべてをPowerShellコマンドレットに置き換える措置のためです。もちろん従来のコマンドは互換性のために残されますが、netsh.exeなど一部のコマンドではPowerShellへの移行を促すメッセージが表示されたりするようになるようです。参考:Window 8の機能の概要 − @IT

ScheduledTasksモジュールというタスクスケジューラを扱うモジュールもWindows 8 / Windows Server 8に新しく追加されるモジュールの一つで、schtasks.exeを置き換えるものとなります。これまでPowerShellでタスクスケジューラを扱うにはschtasks.exeを使うか、WMIのWin32_ScheduledJobを使う必要があり面倒でしたが、このモジュールに含まれるコマンドレットを用いるとそれが容易に行えるようになります。たとえば「notepad.exeを毎日朝10:00に起動する。バッテリ駆動のときでも実行」というタスクを「test」という名前で登録するには、

$action = New-ScheduledTaskAction -Execute "notepad.exe"
$trigger = New-ScheduledTaskTrigger -At "10AM" -Daily
$setting = New-ScheduledTaskSettings -AllowStartIfOnBatteries 
New-ScheduledTask -action $action -trigger $trigger -setting $setting|Register-ScheduledTask -TaskName test

とすれば可能であるはずです。実はServer 8 Developer Preview版ではこのコードは機能しません。タスクのトリガを作成するNew-ScheduledTaskTriggerコマンドレットが正しいオブジェクトを作ってくれないのです。これは将来のバージョンできっと修正されるかと思います。ただトリガを定義する部分をはずせば(あんまり意味はないですが)このコードは動作するので、やり方はたぶんあってると思います。

Register-ScheduledTaskコマンドレットには-asJobパラメータがあり、タスクスケジューラへの登録をジョブとしてバックグラウンドで行うことができます。ScheduledTasksモジュールはWMIを利用してタスクスケジューラを操作するので、ほかのWMI関係のコマンドレットと同様ですね。

なおScheduledTasksモジュールはデフォルトでは読み込まれていないので、使用するには本来Import-Moduleコマンドレットを使用しなければならないところですが、PowerShell3.0のCmdlet Discoveryという機能によりImport-Moduleは実行しなくてもScheduledTasksモジュールに含まれるコマンドレットを利用することができます。Cmdlet Discoveryとは現在読み込まれていて実行可能なコマンドレットの中にない、未知のコマンドレットを実行しようとしたとき、Modulesフォルダに存在するモジュールから同名のコマンドレットが定義されているものを探し出し、発見できたらそのモジュールを読み込んだうえでコマンドレットを実行するという優れた機能です。初回だけモジュールの検索とロードの手順が実行されるので待たされますが、一度Cmdlet Discoveryによってモジュールがシェルに読み込まれればあとは快適にコマンドレットを実行できるようになります。

PSScheduledJobモジュール

ScheduledTasksモジュールは-asJobパラメータが定義されているくらいで実はそれほどPowerShellのジョブとは関係ないのですが、ScheduledTasksモジュールが内包しているPSScheduledJobモジュールはPowerShellのジョブ機能と大いに関係があります。

従来PowerShellスクリプトをタスクスケジューラに登録するにはコマンドラインに"powershell.exe"を、引数に"-file hoge.ps1"を指定して、みたいなまわりくどいことをする必要がありました。しかし新しく追加されるPSScheduledJobモジュールに含まれるコマンドレット群はこの問題を解消します。PowerShellスクリプト(.ps1)あるいはスクリプトブロックをPSScheduledJobとして直接タスクスケジューラに登録できるようになり、PowerShellとタスクスケジューラのシームレスな連携を実現します。こちらはWindows 8/Server 8に付属のモジュールではなく、PowerShell 3.0に付属のモジュールなので、Win7などでも使用可能になる予定です。

使用例を見ていきましょう。

$triggers = @()
$triggers += New-JobTrigger -at "2012/01/01 11:11:10" -Once
$triggers += New-JobTrigger -at "10:00" -Daily

$sb = {
    "This is Scheduled Job."
    Get-Date
}

Register-ScheduledJob -ScriptBlock $sb -Trigger $triggers -Name ScheduledJobTest1

まずNew-JobTriggerコマンドレットによってトリガー(具体的には実行時刻など)を定義します。ここでは決められた時刻に1回実行するものと、毎日同じ時刻に実行するものの2つを定義してみました。そしてこれらの時刻に実行したい内容をスクリプトブロックに記述し、これらをRegister-ScheduledJobコマンドレットで登録してやります。

するとこのスクリプトブロックはタスクスケジューラに登録され、指定時刻になると指定したスクリプトブロックの内容が実行されます。このタスクは「タスクスケジューラ― ライブラリ\Microsoft\Windows\PowerShell\ScheduledJobs」に登録されています。

このタスクのアクションは具体的には次のようになっています。

powershell.exe -NoLogo -NonInteractive -WindowStyle Hidden -Command "Import-Module PSScheduledJob; Start-Job -DefinitionName 'ScheduledJobTest2' -DefinitionPath 'C:\Users\Administrator\AppData\Local\WindowsPowerShell\ScheduledJobs' -WriteToStore | Wait-Job"

これによると、指定時刻に実際にタスクスケジューラによって実行されるのはpowershell.exeであり、Start-Jobコマンドレットを使って登録したスケジュールをPowerShellのジョブとして実行していることがわかります。Start-Jobコマンドレットの-DefinitionNameパラメータなどはPSScheduledJobのために追加されたもので、これによりRegister-ScheduledJobが出力したPSScheduledJob定義をファイルから読み込んでジョブとして実行できるようになっています。PSScheduledJob定義とジョブの出力は-DefinitionPathで指定されているフォルダの下にxmlファイルとして保存されているので興味がある方は覗いてみるといいかもしれません。

さて、スケジュールしたジョブの実行結果はどうやって受け取ればいいのでしょうか。実はこれはすごく簡単で、PSScheduledJob(ここではScheduledJobTest1という名前で定義しました)がタスクスケジューラによって一度以上実行された後は、

$job=Get-Job -name ScheduledJobTest1

とすることでJobオブジェクトとして取得することができるようになります。あとは通常のジョブと同じ取り扱いができるので、

$job|Receive-Job

などで実行結果を取得できます。

ちなみにPSScheduledJobはそれを定義したインスタンス以外でも参照することができます。具体的にはpowershell.exeでジョブをスケジューリングして終了→また別のpowershell.exeを立ち上げてimport-module PSScheduledJobしたあとGet-Job|Receive-JobしてPSScheduledJobの結果を参照、みたいなことができます。

ここで紹介した一連の操作ではスクリプトブロックをPSScheduledJobにしましたが、Register-ScheduledJobコマンドレットの-FilePathパラメータを用いれば.ps1ファイルをPSScheduledJobとして登録することも可能です。

現行バージョンのPowerShellはとにかく起動が遅いため、タスクスケジューラにスクリプトを登録しても実行が始まるまで何十秒も待たされるなどはざらでしたが、PSv3は起動がずいぶん速くなり、スペックや状況にもよるとは思いますがpowershell.exeの起動後ほんの数秒でスクリプトが走り始めます。この速度のおかげもあってPSScheduledJobはきっととても有効に機能するんじゃないかと思います。

おわりに

今回はPowerShell 3.0で増強されるバックグラウンドジョブ関係の機能をまとめてみました。これらの新機能のおかげで、時間のかかる処理や定期実行する処理を扱うのが飛躍的にやりやすくなりそうです。PowerShell 3.0で追加される機能は他にもたくさんあって、このブログでもいつか全部紹介したいと思ってるのですが、今回取り上げたジョブ関係はその中でもかなり重要な機能増加を多く含んでいると言えるでしょう。PowerShell 3.0やWindows 8/Server 8のリリースに備えてジョブ関係から予習しておくのは悪くないと思いますよ。

なんか25日のアドベントカレンダーのうち3回もバックグラウンドジョブネタをやって、PSアドベントカレンダーというより私だけ一人でPSジョブアドベントカレンダーをやってる感じでちょっと申し訳ないんですが、どうか許してください。そして前回は今回で終了するって言ってたんですが、実はまだジョブ関係の小ネタが残ってるので最終日25日にさせてください。では今日のところはこのへんで。明日はwaritohutsuさんの登場です。よろしくお願いします。

2009/10/06

PowerShell v2のバックグラウンドジョブ機能は便利ですが、

$job=Start-Job {Start-Sleep -sec 10;”done”}

などとした場合、このジョブが終了したかどうかをまず

$job

で調べ、終了していたら

Receive-Job $job

のようにしないと結果を表示できません。これはわりかし不便なので、ジョブが終了したらダイアログを出すように工夫してみました。

function StartAndNotify-Job
{
	param([scriptblock]$ScriptBlock)
	$jobId = "JobWatcher"
	$global:job = Start-Job $ScriptBlock
	
	$global:watcherJob = Register-ObjectEvent -EventName StateChanged -InputObject $job -SourceIdentifier $jobId -Action `
	{
		[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
		$recievedString = Receive-Job $job
		if($recievedString -eq $null){$recievedString = ""}
		if($job.State -eq "Completed")
		{
			[System.Windows.Forms.MessageBox]::Show($recievedString,$job.Command,"OK","Asterisk")
		}
		else
		{
			[System.Windows.Forms.MessageBox]::Show($job.Command + "は失敗しました。`r`n詳細はReceive-Job -id " + $job.Id  + " を実行し確認してください。",$job.Command,"OK","Error")
		}
		Unregister-Event "JobWatcher"
		Remove-Job $global:watcherJob
	}
}

使用例

StartAndNotify-Job {Start-Sleep -sec 10;”done”}

このように、スクリプトブロックを渡しておくとバックグラウンド処理が走り、終わるとメッセージボックスが出て、出力結果があるとそれを表示します。エラーが発生した場合はその旨を表示します。便利です。

本当はエラーが出た場合はエラー内容を表示させたいんですがやり方がわかりませんでした。なので、エラーを表示させる方法のみ表示します。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2009/10/06/181919.aspx

2008/12/03

Outlook2007は、メールアドレスに.の連続(hoge...hoge@example.com)や@の前に.がある場合(hoge.hoge.@example.com)にはメールを送信することができません。受信トレイに「システム管理者」から送信不能と通知メッセージが入ります。

これは別にOutlook2007が悪いんじゃなくて、RFCに準拠しているためです。でもDocomoやauなど、このRFCに準拠していないキャリアがあって、結構、よく見ます。その辺の詳しい事情はこちらなどをどうぞ。

で、Outlookユーザーはじゃあこれらのメアドにはメールを送れないのか、と言うとそうではなく、実は裏技があって、@の前の部分を""(ダブルクォーテーション)でくくることで送信可能になります。

"hoge...hoge"@example.comや"hoge.hoge."@example.comなどのようにします。これはOKとRFCで規定されてるらしいですね。

でも毎回これを手で入力するのはメンドイ!

ということでなんとかしてみました。

Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
    Dim oMailItem As MailItem
    Dim bExistInvalidAddress As Boolean
    
    If TypeName(Item) = "MailItem" Then
        Set oMailItem = Item
        
        Dim reAddress As New RegExp
        reAddress.Pattern = "([a-zA-Z0-9\-\_\.]+)\@([a-zA-Z0-9\-\_\.]+)"
        reAddress.Global = True
            
        sMailAddresses = Split(oMailItem.To, ";")
        
        For I = 0 To UBound(sMailAddresses)
            If (InStr(sMailAddresses(I), "..") Or InStr(sMailAddresses(I), ".@")) And _
            InStr(sMailAddresses(I), """") = 0 Then
                sMailAddresses(I) = reAddress.Replace(sMailAddresses(I), """$1""@$2")
                bExistInvalidAddress = True
            End If

        Next
        
        If bExistInvalidAddress Then
            oMailItem.To = Join(sMailAddresses, ";")
            Cancel = True
        End If
        
    End If
End Sub

このようなコードをThisOutlookSessionに埋め込みます。VBエディタでF2キーを押してMicrosoft VBScript Regular Expression 1.0と5.5を参照設定してください。ただしマクロなんで毎回起動時にマクロを有効にするか聞かれます。(以上の意味が分からない方は使わないほうが無難です)

すると、問題あるメールアドレスのメールを送信しようとすると、正しくクォーテーションがつけられたメールアドレスに変換します。ただしTo:だけです。Cc:やBcc:にも対応してもよかったんですがそれは宿題ということで。

Cancel=Trueは要らないと思ったんですが、これを取るとなんかさらに''でクォートされて送信トレイに残骸が残ってしまいます。ので、一度メール編集画面に戻るようにしています。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/12/03/162596.aspx

2008/02/19

先日エルおおさかで行われたわんくま勉強会におこし頂きありがとうございました。

ご報告が遅れましたがレポートです。

ふたコマいただいたんですが、ひとコマ目は音楽とDTM(MIDI)の基礎のお話をやりました。ドレミとは、音符とは、音階とは、和音とは、とかごく基礎のところを触れただけなので初心者の方には喜んでいただけたようですが、上級者の方には物足りなかったようで少し工夫をすべきでしたね。

後半はテキスト音楽「サクラ」を用いて実際に曲を作るところを3分間クッキング形式でどんどん作っていきました(実際はデータ作成に7,8時間かかっています)。なにより、ずったずったでドラムを打ち込めるところがウケてましたねwミク講演といっておきながらよく考えるとオケを作る方が時間かかるので実質サクラ講演に近くなってしまいました。でもミクの歌唱力に驚いた方もいらっしゃったようでよかったかなと。ミクの濃い話は私はちょっと無理なのでできればどなたかやっていただけると嬉しいなぁ、と思ったり。ミク単体で歌わせるのもいいですが、オケをつけるとぐっと「それっぽく」なることが示せたかな、と思います。

Audacityのファイルが壊れていた原因はよくわからないのですが、制作環境とデモ環境が違うといろいろ問題のようですね。どこかのファイルが絶対パスでデータを持ってたのが原因みたいです。一回デモ機でやったときはうまくいったんですけどねー?古いファイルを上書きしたのかも?

でもミク&サクラでこれだけのことができるということが示せてよかったように思います。アンケートもおおむね高評価をいただきました。ありがとうございます。これを機にDTMやってみよう、あるいは再開してみよう、サクラを触ってみようという方が結構おられたのがうれしかったです。あとミクのかわいい絵をアンケートに描いてくれた方どうもありがとうございますv

DTMと化学とスクリプトの関係は何かあるのかと聞かれたんですがとくにないですw

春編夏編とか、応用編とか、DTM本執筆とかわんくまテーマソング作曲とかいろいろ振られたんですけどごめんなさい、当分実現しそうにないですw

あと私の講演がやまにょんの濃いー講演にうまくつながったようでよかったです。私だけの話だと物足りなかった方もいたようですし。やまにょん遠いところからありがとー

 

講演資料、データ(完成版、作りかけのも含む)は一足先に自宅サーバーで公開しておきます。

mutaの作った音楽
http://winscript.jp/music/ (下の方)

ソフトのDL・紹介サイト

テキスト音楽「サクラ」 http://oto.chu.jp/

VOCALOID2 初音ミクhttp://www.crypton.co.jp/mp/pages/prod/vocaloid/cv01.jsp

Audacity http://audacity.sourceforge.net/

 

追伸。

この講演はまぁ、ちゃっぴさんが私をそそのかしたことがきっかけで実現したんですが、実はちゃっぴさんから贈り物が届いていました。最後にちょっとだけみなさんにお見せしたんですけど家で写真撮りました。

080219-092146

こんなメッセージが入っていました。これ会場で読むべきだったんですがてんぱってて読めませんでした、ごめんなさい

080219-092500

えーと。これ、「式場 エルおおさか」 で届いたんですけど・・・wwwww

というか、これはあれですね、結婚したいしたいと某所でわめいていた私に、じゃあミクと結婚しちゃえばというちゃっぴ先生のきっついシャレですなw

 

というわけで、みなさんどうもありがとうございました。

次回は3/29 PowerShellの話をやりますのでよろしくお願いします。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/02/19/123810.aspx

2007/09/11

ひろえむさんところより。

ネタ元:フィールドSEあがりの安納です

Windows Script Host ( WSH ) 5.7 (英語版) が公開されています。

Windows XP 用はこちら
Windows 2000 用はこちら
Windows Server 2003 用はこちら

Vistaには5.7が載っているのですが、ほかの現行OSも5.6から5.7にバージョンアップとのことです。内容は、フィールドSEあがりの安納ですさんところより

が変わったかといいますと、大部分はバグフィックスとセキュリティ向上です。これまでリリースされてきたセキュリティパッチも含まれています。

追加された機能としては、およそ以下の通りです。 

JScript 関連

ガベージコレクションの性能改善
ECMA 327 Standard
新サマータイム対応

※すいません、JScriptに関して私が語れることはありませんです...はい...

VBScript 関連

GetUILanguage ファンクションによる現在の表示言語取得
→Vista だと簡単に言語変更できますからそれに対応したものでしょう。
  言語を確認してからメッセージを表示するといったことが可能になりますね。

共通事項

2GB 以上のアドレスへのアクセス

このほかに、メモリリークへの対応やデッドロック対応なども含まれているので、意味不明のエラーに悩まされたことのあるかたがたは日本語版のリリースをもうちょっと待ってみてください。

ということなので、マイナーチェンジですね。ようやく5.7の正体がつかめました。たしかにサマータイムの制度が変わったりしましたからねー。日本語版が出たら入れてみようかと思います。Windows Updateで入るかもしれませんが。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2007/09/11/95263.aspx


Copyright © 2005-2018 Daisuke Mutaguchi All rights reserved
mailto: mutaguchi at roy.hi-ho.ne.jp
プライバシーポリシー

Twitter

Books