ラベル .Net Framework の投稿を表示しています。 すべての投稿を表示
ラベル .Net Framework の投稿を表示しています。 すべての投稿を表示

2019年11月13日水曜日

◆パス(文字列)から拡張子なしのファイル名を取り出す方法

数年ぶりにPowerShellのお仕事をしているので浦島太郎状態。

ファイルオブジェクトだとプロパティで色々用意されていたように思うが、文字列だと「Split-Path」では用が足りなさそう。

力業でやっても大したことは無いのだが誰かに見られると恥ずかしいのでちょっと調べてみた。(笑)

「System.IO.Path」のStaticで色々と用意されているらしい。

パスの文字列から拡張子やファイル名を取り出す方法

2016年8月26日金曜日

◆PowerShellでWebサイトをホストする

http://powershell.com/cs/blogs/tips/archive/2016/08/11/creating-powershell-web-server.aspx

IISとか無しにWebサイトをPowerShellだけでホストしちゃいましょって感じ。(URL更新?)

https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/creating-powershell-web-server

このサンプルを実行しておいて、http://localhost:8080/ にアクセスすると「Here is PowerShell」という文字を表示、http://localhost:8080/services にアクセスするとGet-Serviceした内容を返すというもの。
http://localhost:8080/hoge といった存在しないアドレスにアクセスすると404を返してサービス終了といった仕様になっているようだ。

こんなに簡単にできちゃうんですね。

2016年6月8日水曜日

◆バージョンをソートする

strip off data from variable

Win32_Product から .NET Frameworkのバージョンを調べたい。
複数のバージョン戻り値から最新を取り出すにはどうすれば良いですかね・・・。

といった感じの質問だろうか。

バージョンが文字列で返ってきているのでどうやってソートしましょうか。

以前、以下のサンプルで使ったVersionクラスにキャストすると良さそう。
◆IPアドレスをソートする

PowerShell的にはそれだけのお話。

ちょっと気になるのが、.NET Frameworkのバージョンを調べるのに本当にWin32_Productで良いのだろうか。

以下にかなりの力作があるので実行してみたところ、若干(だいぶ?)異なる。
.NET Frameworkのバージョンを確認する方法

以前以下の様な例も見たことがあるが、これもちょっと違う。

PS> dir  $env:windir\microsoft.net\framework\v* –name

それではと、VisualStudioを立ち上げてみたが結局どれとも異なる。

まぁ、いいか。(笑)

2016年3月17日木曜日

◆配列操作を速く行う

PowerShellで行う処理にシビアな速度を要求されることは多くないので、私は、PowerShellの処理速度をあまり気にしていない。

今回の話は、単純な配列を使うより「ArrayList」を使うと早いよってお話。
確かに速度は圧倒的に違うようだ。
Faster Array Manipulations - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

それでも1万回ループでの話なのでそれほど気にする局面は無いかも。
まぁ、覚えておいて損はない。

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015

# SLOW
Measure-Command {
  $ar = @()
  for ($x = 1; $x -lt 10000; $x += 1) {
    $ar += $x
  }
}


# FAST
Measure-Command {
  [System.Collections.ArrayList]$ar = @()
  for ($x = 1; $x -lt 10000; $x += 1) {
    $null = $ar.Add($x)
  }
}

2016年3月15日火曜日

◆バージョンを比較する

Compare Versions - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

以前もほぼおなじ内容のTipsが出ていた。
Comparing Versions - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

特に大した話ではなく、Versionは文字列なので単純に比較すると意図した結果にならない。そこで、.NETのVersionクラスに変換して比較すると良いよってお話。

その時に、式の左側だけにキャスト指定をすれば、右側はPowerShellが自動的に合わせてくれる。(PowerShellは通常そういう動作をしたような気がする)

>[System.Version] '3.4.22.12' -gt '22.1.4.34'

2015年10月30日金曜日

◆OSバージョンを調べる

Finding Operating System Version - Power Tips - PowerShell.com – PowerShell Scripts, Tips, Forums, and Resources

[Environment]クラスのstaticプロパティで取ってこれるよってだけの話。

 

メンバーの値を一覧表示するにはどうするんだろう・・・。

とりあえずベタにやるとこんな感じ?

>[environment] | gm -static -type property | ?{$_.name -ne "stacktrace"} |
    %{$_.name + " = " + [Environment]::($_.name)}

stacktraceは結果が長くなるのでとりあえず除外している。

image

2014年12月17日水曜日

◆WindowsキーをSendする

以前以下の様なIEを表示するスクリプトを作った。
PowerShell: ◆IE画面をアクティブにして最大化

色々と事情があって最近はChromeを半分以上の割合で使っている。

そこで、Chromeも最大化したくなった。
幸い、ChromeはIEと違って、単純に「Win + 1」とかで前回表示していたタブのまま復帰してくれるので、これをSendできれば簡単だ。

WindowsキーのSendは前回調べて挫折したのだが、もう一度探してみてや~っと見つけました。
PowerShell/WinKeys.ps1 at master · stefanstranger/PowerShell · GitHub

結局のところは、PowerShellでは難しいのでC#で作っているのね。
しかも.NETFrameworkでもないのね。

Windows8ではそのまま動いたが、Widnows7ではLinqとTasksのusingを消したほうがよさそうだ。

WindowsキーがSendできるのは、結構嬉しい。

2014年10月30日木曜日

◆WPF(XAML)を使う

PowerShellからXAMLで作ったウインドウを扱ってみる。

XAML自体は直接作るのは面倒なのでVisualStudioからコピーする。
image

Windowのx:Classの指定はエラーになるようなので削除する(行削除)

後はXAMLの記述をヒア文字列で定義してWindows.Markup.XamlReaderクラスのParseメソッドで変換してあげるだけのようだ。

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024

$xaml = @"
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Content="Button"
            HorizontalAlignment="Left" VerticalAlignment="Top"
   Width="75" Margin="230,138,0,0" Name="button1"/>
        <Label Content="Label" HorizontalAlignment="Left" Height="34"
   Margin="198,202,0,0" VerticalAlignment="Top"
   Width="171" Name="label1"/>

    </Grid>
</Window>
"@


Add-Type -AssemblyName PresentationFramework, PresentationCore, WindowsBase
$window = [Windows.Markup.XamlReader]::Parse($xaml)
$button = $window.FindName("button1")
$label = $window.FindName("label1")
$button.add_Click({$label.Content = "Hello World"})

$window.ShowDialog() | Out-Null

実行すると以下のウインドウが表示されて、

image

ボタンをクリックすると「Hello World」が表示される。

image

Windowsフォームより使いやすいかも。

2013年10月25日金曜日

◆C#からPowerShellを使う

昔どこかで見かけたことはあるが、あまり使い道は無いのかと思っていた。

ふと思い立って、一応使い方を確認しておくことにした。

まずは、DLL(System.Management.Automation.dll)が必要なようなので参照を追加する。私のWindows8環境では以下の場所にあった。

"C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll"

Get-Processを使うにはこんな感じでOKだった。

namespace PowerShellTest

{

    class Program

    {

        static void Main(string[] args)

        {

            PowerShell ps = PowerShell.Create();

            ps.AddCommand("Get-Process");

            var results = ps.Invoke();

            results.ToList().ForEach(

                p => Console.WriteLine(p.Properties["ProcessName"].Value));

           

        }

    }

}

image

Get-ProcessからPSObjectが返ってきてしまうので、プロパティが文字列参照になってしまうあたりが今1つな感じ・・・。

2013年3月13日水曜日

◆見出しタグを拾って目次をつける

以下のようなブログの見出しを拾って目次をつけてあげようかと思う。
HTMソースをクリップボードにコピーしてPowerShellで編集して貼り付けなおす。

image

結果はこんな感じに

image

必要に迫られて「えいや」と書いたのでちょっと力技チックだが、とりあえず動く。
ここでは<h5>を拾う仕様としている。

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026

$cp = [Windows.Forms.Clipboard]

#ClipBoardから取得
$cp::GetText() 

$ctr = 1
$h5word = @()
$oString = $cp::GetText() -split "`r`n" |
 
 
%{  if($_ -match "<h5>(.*)</h5>"
){
       
$h5word += $Matches[1]
        $stCtr = ($ctr++).ToString("000"
)
       
$_ -replace "<h5>","<h5 id=`"id$($stCtr)`">"
      }else
{
       
$_
      }
    }


$outString = @()
$outString += "<ul>"
$h5word | %{$i=1
}{
   
$iSt=($i++).ToString("000"
)
   
$outString += "<li><a href=""#id{0}"">{1}</a></li>" -f $iSt,$_
}
$outString += "</ul>"
$outString += 
$oString
$cp
::SetText($outString -join "`r`n")

2013年2月14日木曜日

◆型名のエイリアス(アクセラレータ)表示

PowerShellでは.Netクラスへのアクセスを簡易にすべく「TypeAccelerators」なるものが用意されている。

どんな時に使われるかというと、[System.Xml.XmlDocument]なんてクラスにアクセスする時に[xml]といった短い名前でのアクセスを提供してくれる。

C#言語が提供する「int」や「string」といった型名と同じ感じだ。

どんなものが用意されているかは以下で確認できる。

001
002

$clsAccelerators = "System.Management.Automation.TypeAccelerators"
[psobject].Assembly.GetType($clsAccelerators)::Get

image

ここで、「Get」というのは「TypeAccelerators」クラスのStaticプロパティだ。

また、自分でこの名前を追加することもできる。
以下の例では[System.IO.Path]に[Path]という名前を付けている。

001
002
003
004

$clsAccelerators = "System.Management.Automation.TypeAccelerators"
[psobject].Assembly.
GetType(
 
$clsAccelerators)::Add("Path",[System.IO.Path])
[Path]::DirectorySeparatorChar

2013年2月8日金曜日

◆全角の日付を計算する

全角の日付に対して演算をするには日付型に変換してから計算し、元に戻してあげる。(そのまま計算する方法なんてあるのだろうか・・・、きっとローカルだから無いような・・・)

ちょっとべたな感じいっぱいだが、とりあえずこんな感じでいけそう。

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019

function Add-KnajiDate($date,$days)  
{ 
 
[char[]]$zen2han = "0","1","2","3","4","5","6","7","8","9"
  $targetDay = $date
  $targetDay =
 
   
-join ([char[]]$targetDay |
 
   
%{if($zen2han.IndexOf($_) -ge 0){$zen2han.IndexOf($_)}else{$_
}})

 
$culture =
 
   
New-Object System.Globalization.CultureInfo -argumentlist "ja-JP",$true
  $culture.DateTimeFormat.Calendar =
 
   
New-Object System.Globalization.JapaneseCalendar
  $parsedTargetDay =
 
   
[DateTime]::ParseExact($targetDay, "ggyy年M月d日",$culture
)
 
-join([string[]][char[]]$parsedTargetDay.AddDays($days).
ToString(
   
"gyy年M月d日",$culture) | %{if($_ -match '\d'){$zen2han[$_]}else{$_
}})
}


Add-KnajiDate "平成24年2月8日" 3

image

2013年2月6日水曜日

◆コンストラクタを表示する

TypeのGetConstructorsメソッドで確認できる。

image

2013年2月5日火曜日

◆ネットワークカードの速度を表示

001
002
003

[System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | 
 
ft Description,OperationalStatus,
    @{n="Speed(M)";e={($_.speed/1000000).tostring("0.0").padleft(8)}} -auto

image

2012年12月21日金曜日

◆IISのログを取得する2(結合、複合化、解凍)

PowerShell: ◆IISのログを取得する1(取得、圧縮、暗号化、分割)で作成したファイルをもとに戻すスクリプト。

ファイルのパターンは以下のように別れる。

  1. 圧縮ファイル(ログ.zip)
  2. 暗号化ファイル(ログ.dat)
  3. 非暗号化分割ファイル(ZIP.001~ZIP.nnn)
  4. 暗号化分割ファイル(DAT.001~DAT.nnn)

パラメータを指定せずにスクリプトを実行するとファイル選択ダイアログが表示されるので、対象のファイルを選択する。
(分割ファイルの場合はすべての分割ファイルを選択する。)

ファイル選択ダイアログはPowershellをSTAモードで実行する必要があるため「OutLogメイン.ps1」経由で「結合.ps1」を呼んでいる。
(V3からはSTAがデフォルトになったようだが。)

パラメータ指定で実行する時は、「InPath」に入力ファイル(分割ファイルの時はフォルダ指定)、「OutPath」に出力フォルダを指定する。

出力フォルダに「ログyyyyMMdd_HHmmss」の名前でフォルダを作り、その中にログを復号・解凍する。

image

<OutLogメイン.ps1>

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021

param(
 
[string]$InPath,
  [string]$OutPath="desktop"
)
#staで起動するために「OutLogメイン経由で結合.ps1を起動する。Ver3では不要」

$currntPath = Split-Path $myInvocation.MyCommand.path
Start-Transcript (Join-Path $currntPath "OutLog.log")

<# 分配演算子は使えない(バグ?)
$param = @{}
$param.OutPath = $OutPath
if($InPath){$param.InPath = $InPath}
#>

$scriptPath = Join-Path $currntPath "結合.ps1"
if($InPath
){
   
Powershell -sta $scriptPath $InPath $OutPath
}else
{
   
Powershell -sta $scriptPath -OutPath $OutPath
}
Stop-Transcript

<結合.ps1>

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

param(
 
$InPath,
  $OutPath="desktop"
)

function MakeDir($path
){
 
$f = mkdir $path
  Write-Host "mkdir $path" -ForegroundColor Cyan
}

$currntPath = Split-Path $myInvocation.MyCommand.path
$initFolder = [Environment]::GetFolderPath("desktop")

#入力パス取得&パターン判定
##ZIP:zipファイル、DAT:暗号化(DAT)ファイル、
##ZIPn:圧縮分割フォルダ、DATn:暗号化分割フォルダ

$inPtn = "";[String[]]$inPathFiles=""
if($InPath
){
 
if(Test-Path $InPath -PathType Leaf){  #ファイル指定--
  if((Split-Path $InPath -Leaf) -eq "ログ.zip"
){
   
$inPtn = "ZIP"
    $inPathFiles[0] = $InPath
  }else
{
   
if((Split-Path $InPath -Leaf) -eq "ログ.dat"
){
     
$inPtn = "DAT"
    $inPathFiles[0] = $InPath
    }else
{
     
Write-Error "◆入力指定誤り◆";return
    }
  }
  }
elseif(Test-Path $InPath -PathType Container){  #フォルダ指定--
    if(dir $InPath -Filter zip.*
){
   
$inPtn = "ZIPn"
    $inPathFiles = dir $InPath -Filter zip.* | select -ExpandProperty fullname
  }elseif(dir $InPath -Filter dat.*
){
   
$inPtn = "DATn"
    $inPathFiles = dir $InPath -Filter dat.* | select -ExpandProperty fullname
  }else
{
   
Write-Error "◆入力指定誤り◆";return
  }
  }
else
{
   
$InPath -eq ""
    $InPath
    if($InPath){"True"
}
   
Write-Error "◆入力指定誤り◆";return
  }
}
else
{
 
Add-Type -AssemblyName System.Windows.Forms
 
 
$dl = New-Object System.Windows.Forms.OpenFileDialog
 
 
$dl.Title = "ファイルの選択"
 
 
$dl.InitialDirectory = $initFolder
 
 
$dl.Multiselect = $true
  if($dl.ShowDialog() -eq "OK"
){ 
     
$inPathFiles = $dl.
FileNames
   
switch (Split-Path $inPathFiles[0] -Leaf
) {
     
"ログ.zip" {$inPtn = "ZIP";break
}
     
"ログ.dat" {$inPtn = "DAT";break
}
     
"dat.001" {$inPtn = "DATn";break
}
     
"zip.001" {$inPtn = "ZIPn";break
}
     
default
 {
       
Write-Error "◆入力指定誤り◆";return
      }
    }
  }
else{return
}
}


#出力先フォルダ作成
if((Test-Path $OutPath) -eq $false
){
 
$spcialFolder = [environment+specialfolder] |
 
   
Get-Member -Static -type property | select -expand name
  if($spcialFolder -contains $OutPath
){
   
$OutPath = [Environment]::GetFolderPath($OutPath
)
  }
else
{
   
Write-Error "◆出力パス誤り◆";return
  }
}

$outPathRoot =
 
 
Join-Path $OutPath ("ログ" + (Get-Date).ToString("yyyyMMdd_HHmmss"))
MakeDir $outPathRoot 


#◆◆◆ パターンに応じて「結合」「複合化」「解凍」実行をコントロール 
function Executer
{
 
 
switch ($inPtn
) {
   
"ZIP"
 {
     
$zipTargetFile = $inPathFiles[0]
      break
    }
   
"DAT"
 {
     
$decryptTargetFile = $inPathFiles[0]
      . F_Decrypt
      $zipTargetFile = $DecryptedFileName
      break
    }
   
"ZIPn"
 {
     
$joinTargetFiles = $inPathFiles
      . F_Join
      $zipTargetFile = $joinedFileName
      break
    }
   
"DATn"
 {
     
$joinTargetFiles = $inPathFiles
      . F_Join
      $decryptTargetFile = $joinedFileName
      . F_Decrypt
      $zipTargetFile = $DecryptedFileName
      break
    }
   
default
 {
     
break
    }
  }
 
. F_UnZip
  dir $outPathRoot | ?{$_.PSIsContainer -eq $false} | del
}

#◆結合
function F_Join
{
 
#$inpPath = "F:\Desktop\test"
  #$outPath = "F:\Desktop\Dec.txt"
  $joinedFileName = Join-Path $outPathRoot "結合ログ.tmp"
  $dest = New-Object System.IO.FileStream
(
   
$joinedFileName,[IO.FileMode]::Create,[IO.FileAccess]::
Write)
 
Get-Item $joinTargetFiles | sort name | %
{
     
$data = [System.IO.File]::ReadAllBytes($_.
FullName)
     
$dest.Write($data,0,$data.
Length)
  }
 
$dest.
Dispose()
 
Write-Host "結合しました" -ForegroundColor Cyan
}

#◆複合化
function F_Decrypt
{
 
$KEYFilePath = Join-Path $currntPath "KEY.dat"
  $IVFilePath = Join-Path $currntPath "IV.dat"
  if((Test-Path $KEYFilePath) -and (Test-Path $IVFilePath
)){
   
$desKey = [System.IO.File]::ReadAllBytes($KEYFilePath
)
   
$desIV = [System.IO.File]::ReadAllBytes($IVFilePath
)
  }
else
{
   
$desKey = [byte[]](1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1
)
   
$desIV = [byte[]](0,0,0,0,0,0,0,0
)
  }
 
$DecryptedFileName = Join-Path $outPathRoot "ログ.zip"
  $src = [System.IO.File]::ReadAllBytes($decryptTargetFile
)

 
$desProvider =
 
   
New-Object System.Security.Cryptography.TripleDESCryptoServiceProvider
  $decryptor = $desProvider.CreateDecryptor($desKey,$desIV
)
 
$ms = New-Object System.IO.MemoryStream
  $cs = New-Object System.Security.Cryptography.CryptoStream
(
   
$ms, $decryptor, [System.Security.Cryptography.CryptoStreamMode]::
Write)
 
$cs.Write($src,0,$src.
Length)
 
$cs.
Close()
 
[System.IO.File]::WriteAllBytes($DecryptedFileName,$ms.
ToArray())
 
Write-Host "複合しました" -ForegroundColor Cyan
}

#◆解凍
function F_UnZip
{
 
$dllPath = Join-Path $currntPath "ICSharpCode.SharpZipLib.dll"
  [Void][Reflection.Assembly]::LoadFile($dllPath
)
 
$zipFile =
 
     
New-Object ICSharpCode.SharpZipLib.Zip.FastZip
  $zipFile.RestoreAttributesOnExtract  = $true
  $zipFile.RestoreDateTimeOnExtract = $true
  $zipFile.CreateEmptyDirectories = $true
  #$zipFile.ExtractZip($DecryptedFileName,$outPathRoot,"")
  $zipFile.ExtractZip($zipTargetFile,$outPathRoot,""
)
 
Write-Host "解凍しました" -ForegroundColor Cyan
}

. Executer  #「結合」「複合化」「解凍」呼び出し
Write-Host "◆終了しました◆" -ForegroundColor Magenta