全110件 (110件中 1-50件目)
windows11のコンテキストメニューがうっとおしい。レジストリをいじれば、Win10以前のメニューに戻すことができるらしいので、スクリプト化してみました。function ConvertTO-OldMenu{ New-Item "hklm:\system\CurrentControlSet\Control\FeatureManagement\Overrides\4\586118283" -Force|Out-Null $entries =@{ EnabledState = 1; EnabledStateOptions = 1; Variant = 0; VariantPayload = 0; VariantPayloadKind = 0 } $entries.GetEnumerator()|%{ Set-ItemProperty -Path hklm:\system\CurrentControlSet\Control\FeatureManagement\Overrides\4\586118283 -Name $_.Key -Value $_.Value -Type DWord } New-Item "HKCU:\software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" -Force Set-ItemProperty -Path "HKCU:\software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" -Name "(default)" -Value $null}ConvertTO-OldMenu
2022.01.19
コメント(0)
前回の続きファイルをエディタで開かずにファイルの中身だけ見たいことありますよね。うっかりエディタで開くと中身をいじってしまうかもしれないので、チラ見だけしたいってとき。で、これも「送る」にショートカットを作ることで解決できました。前回同様のフォルダで、ショートカットを作成。「項目の場所」に次の文字列を入れればOK。C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -w h "add-type -a system.windows.forms;function s($s){$d=[windows.forms.form]::new();new-object windows.forms.label -p @{parent=$d;text=gc -ra $s;autosize=1};$d.autoscroll=1;$d.showdialog()};s入る文字数が厳しいので パラメータ指定など切り詰めています。
2021.12.21
コメント(0)
powershellのスコープがいまいち理解できず、「関数を定義する関数」ってのが作れないでいました。スコープについて説明してるのって、大概が変数についての説明で、関数のスコープを指定するやり方が分からなかったのです。長い間悩んでいたのですが、先日、いいサイトを見つけました。function Global:関数名(パラメタ){関数実体}とやればいいだけなんですね。簡単じゃん。ちなみに、日本語でスコープを詳しく解説しているのも見つけたので、書いておきます。function Build-Function( [string]$name, [scriptblock]$definition ){ Invoke-Expression "function Global:$name{${definition}}"}Build-Function -name foo -definition { param( $p1, $p2 ) "bar`t$p1`t$p2"}foo a b
2021.12.20
コメント(0)
ファイルをエディタで開いて全選択→コピー→エディタ終了って面倒くさいよね。で、ファイルをテキスト読み出しして、クリップボードに送るメニューが作れないか考えてみました。できました。エクスプローラーのアドレスバーに%Appdata%\microsoft\Windows\SendToを打ち込み、開いたフォルダ内でショートカットの新規作成を行います。「項目の場所」に次の文字列を打ち込み、適当な名前(「テキストコピー」とか)で保存します。powershell -executionpolicy bypass -command "$OutputEncoding = [Console]::OutputEncoding;function c($f){gc $f|clip};c"これで、任意のファイルを右クリックし、「送る」の中から「テキストコピー」を選べばファイルの中身(テキストファイルであれば)をクリップボードに送れます。ちょっくら技術解説最初は単純にgc $args|clipみたいな形でやろうとしたけどうまくいきませんでした。ショートカットに与えられるパラメータは、「項目の場所」の文字列の最後に追加されるみたい。(訂正2021年12月20日)SendToに送られるファイルのパスは、ショートカットの「項目の場所」の文字列の最後に追加されるみたい。そこで、SendToに送られるファイルパスを受け取るためには、事前に関数化しておかないとならないってわけ。あと、日本語ファイルを素のままclip.exeに送ると文字化けします。そこで、おまじないとして、$OutputEncoding = [Console]::OutputEncodingの1行が必要になります。
2021.12.13
コメント(0)
今回はPDFの分割。元のPDFファイル名に枝番を付して、指定フォルダ(無指定:デスクトップ)に生成する。使用している関数 set-PdfSharpAssembly は前回のやつ。split-pdffunction split-pdf{ param( [parameter(mandatory)][string]$pdfpath, [parameter(mandatory=$false)][string]$outfolder="$env:userprofile\desktop" ) if ( !( Test-Path $pdfpath ) ){ throw "pdfのパスが見つかりません:$pdfpath" } set-PdfSharpAssembly $inputpdf = [PdfSharp.Pdf.IO.PdfReader]::Open( $pdfpath, [PdfSharp.Pdf.IO.PdfDocumentOpenMode]::Import ) $totalpages = $inputpdf.pagecount $NombreWidth = [math]::Floor([math]::Log10( $totalpages )) + 1 $NameStem = [io.path]::GetFileNameWithoutExtension( $pdfpath ) for ( $Nombre = 0; $Nombre -lt $totalpages; $Nombre++ ){ $outname = "${NameStem}_" + ([string]$Nombre).PadLeft( $NombreWidth, "0" ) + ".pdf" $outpath = Join-Path $outfolder $outname $pdfdoc = New-Object PdfSharp.Pdf.PdfDocument $pdfdoc.AddPage( $inputpdf.pages[ $Nombre ] )|Out-Null $pdfdoc.Save( $outpath ) }}
2021.10.29
コメント(0)
powershellでpdfを操作するっていうと、定番はitextsharpでした。今でも、フリーのPDFツールにdllが同梱されていたりしますね。 でも、いつの間にかライセンスがややこしく、自由に(無料で)使おうとすると苦労するようになったみたいです。これ、元のitextのライセンスが変更されたからで、古いバージョンを使えば今でも利用は可能なようですが、メンテされていないライブラリをいつまでも使うってのはどうもね。 何か手はないかと探したら、いいのを見つけました。名前は「pdfsharp」。ウェブサイトはこちら。同サイトの更新状況は2015年が最新ですが、nuget galleryのlast updateは2019年なので、そこそこ新しいようです。 なんといっても、「PDFsharp and MigraDoc Foundation is Open Source and free to use even in commercial applications. See Licensing.」というのがうれしい。おっと、こんなことも書いてあった。「PDFsharp and MigraDoc Foundation will remain Open Source and free to use even in the far future」。even in the far futureですよ。 これは使わない手はない。ちょこちょこっと触ってみよう。インストールしたくないので、強引なことをやってます。これで、カレントフォルダに「Hello World」と印刷された pdfが生成されます。function set-PdfSharpAssembly{ #Prepare pdfsharp.dll $tmpdll = "$Env:Temp\pdfsharp.dll" $tmpzip = "$Env:Temp\pdfsharp.zip" $tmpfolder = join-path "$Env:temp" ([io.path]::GetFileNameWithoutExtension( $tmpzip )) if (!( test-path $tmpdll )){ #dllがない if ( !( test-path $tmpzip ) ){ #zipもない $nugetURL = "https://www.nuget.org/packages/PdfSharp" $response -or ( $response = Invoke-WebRequest -Uri $nugetURL )|out-null $nupkgURL = ($response.Links|?{$_.innerText -match "Download package"})[0].href Invoke-WebRequest -Uri $nupkgURL -OutFile $tmpzip #"Has Got Zip" } #zipを解凍 Expand-Archive -Force -Path $tmpzip -DestinationPath $tmpfolder $dllToCopy = Get-ChildItem -Include "pdfsharp.dll" -Recurse "$tmpfolder\*" $dllToCopy.CopyTo( $tmpdll )|Out-Null #"Has Got DLL" }else{ #"Has DLL" } Add-Type -Path $tmpdll}<#確認 set-PdfSharpAssembly[appdomain]::CurrentDomain.GetAssemblies()|?{$_.location -like "*pdfsharp*"}|%{$_.exportedtypes}|%{$_.fullname}#>#PDFsharp - Getting Started http://www.pdfsharp.net/wiki/PDFsharpFirstSteps.ashxset-PdfSharpAssembly$Document = new-object PdfSharp.Pdf.PdfDocument$page = $Document.AddPage()$gfx = [PdfSharp.Drawing.XGraphics]::FromPdfPage( $page )$font = New-Object PdfSharp.Drawing.XFont("Verdana", 20, [PdfSharp.Drawing.XFontStyle]::Bold)$gfx.DrawString( "Hello World!", $font,[PdfSharp.Drawing.XBrushes]::Black, ( New-Object PdfSharp.Drawing.XRect( 0, 0, $page.Width, $page.Height ) ), [PdfSharp.Drawing.XStringFormat]::Center)$Document.Save( "./pdfsharp.pdf" )
2021.10.22
コメント(0)
文字列をワイルドカードで判定するときハマったのでメモ。正規表現の特殊文字エスケープなどは情報がたくさんあるのですぐ見つかりますが、ワイルドカードの場合どうなるのか見つからず試行錯誤してみました。MSのサイトにもないしね。まず、"abc[]"にマッチするワイルドカード(abcは任意)を思いつくまま動かしてみると"abc[]" -like "*[]""abc[]" -like "*\[\]""abc[]" -like "*`[`]"1と3はエラー、2はFalseを返します。正解は"abc[]" -like "*``[``]"で、バッククオートで二回エスケープするってやつでした。試したのは"[]"だけだけど、たぶん、*?も同様かと思います。なんと、?や*は振る舞いが違う。もう少し研究が必要…。
2021.06.30
コメント(0)
nugetのサイトなんかにある、.netライブラリ。便利そうだけど、powershellでの使い方がいまいちわからないってことが結構あります。つまり…add-type -path "foobar.dll"とやって.netライブラリを読み込んだ後、さて、何が使えるのでしょう。こんなときは、[appdomain]::CurrentDomain.GetAssemblies()|?{$_.location -like "*foobar.dll*"}|%{ $_.definedtypes|?{$_.IsPublic}|%{$_.name}}とやれば読み込まれた型がリストアップされます。(修正2021年10月22日:日本人だな、複数のSを忘れてる)もっと簡単に[appdomain]::CurrentDomain.GetAssemblies()|?{$_.location -like "*foobar.dll*"}|%{$_.exportedtypes}でもいけそう。見付かった型をnew-objectするなり、[型]するなりして、get-memberでプロパティやメソッドを調べればいいね。
2021.06.24
コメント(0)
いや、switchってたって、せっかく買ったのにお蔵入りして3DSばっかやってるあの機械のことじゃありません。powershellのswitch文のすごいところは、「switch」に続くカッコ内(「制御式」というらしい)に、単一の値だけじゃなくて、配列だのコレクションだのをじゃんじゃか書けること。例えばswitch ( gci . ){ {$_.lastwritetime -gt [datetime]::now.AddYears(-1)}{$_.fullname}}でカレントディレクトリにある1年以内のファイルをリストアップできちゃたりする。これ便利だけど、その分、ロジックとか追いにくくて難しいんだよね。そして、もう一つ。制御式とCase句の判定にワールドカードや正規表現などさまざまなオプションが使えること。それだけじゃない。Case句には文字列や数値だけでなく、ブレース({})でくくった任意の式も書けるので、ほとんどどんなことでも判定できちゃう。さて、前置きはこれくらいで、テストパターン。switch -Regex ("a b c d" -split " ") { "a|b"{ "$_`ta_b match" } "a|c"{ "$_`ta_c match" } default{ "$_`tdefault" }}これで、次の結果が出力される。a a_b matcha a_c matchb a_b matchc a_c matchd default
2021.06.09
コメント(0)
powershellの利点のなかに、ディスク以外のシステムもドライブ名+パスでアクセスできることがあります。慣れてくると、これ結構便利だったりしますよね。その一つがレジストリ参照・操作。この前の電源オプションの話でもやったHKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorerなんてのもそう。サクッとワンライナーで書けたのは、powershellがレジストリをドライブ+パス名で扱えるからでした。ところが…どういうわけか、MSが用意してくれたのは、HKCU(HKEY_CURRENT_USER)とHKLM(HKEY_LOCAL_MACHINE)しかありません。要らないと判断した理由は何でしょう。どなたかご存じなら教えてほしいものです。それはともかく、残り3つのハイブもドライブ名にしちゃえというわけで。set-RegDriveを実行しておけばHKCR:HKU:HKCC:のドライブ名がスクリプト中で使えるようになります。Set-RegDrive.ps1function set-RegDrive{ $RegNames=@" CLASSES_ROOT CURRENT_USER LOCAL_MACHINE USERS CURRENT_CONFIG"@ -split "`r`n"|%{$_ -replace "\s","" } $AlreadyDefined = get-psdrive|?{$_.Provider.name -eq "registry"}|%{ ($_.Root -replace "HKEY_","").trim() } $RegNames|%{ $Abbrev = $_ -replace "^(.).*_(.).*",'$1$2' if ( $Abbrev -eq "USERS" ){ $Abbrev = "U" } if ( $AlreadyDefined -contains $_ ){ return } $DriveName = "HK$Abbrev" New-PSDrive -name "$DriveName" -PSProvider "Registry" -root "HKEY_$_" -Scope Script }}
2021.06.08
コメント(0)
常時起動のマシンをシャットダウンされてしまって、困ったことがあったので対策。あれこれ調べたんですが、一番ラクそうなのを見つけました。 レジストリのHKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer の「HidePowerOptions」エントリ(DWord値)を作り、値に「1」を入れてやると、スタートボタンの電源ボタンを押しても、シャットダウン・再起動・スリープなどが表示されなくなるそうです。 元に戻すときは、値に0を入れればOK。 で、この程度ならpowershellワンライナーにして、ショートカットにしてしまえば、スクリプトすら要らないじゃん。ってわけで表示無効の例powershell Set-ItemProperty -Path HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name "HidePowerOptions" -Type DWord -Value "1"
2021.03.16
コメント(0)
qiitaに面白いのがあったんで、powershellでもやってみました。向こうは色なしだったけどこっちは色付き。fakehacker.ps1function invoke-fakehacker( [int]$count ){ if ( !$count ){ $count=5 } $sharp="#" Get-Date 1..$count|%{ $color=[console]::ForegroundColor 1..50|%{ [console]::write( $sharp ) Start-Sleep -Milliseconds ( ( Get-Random 5 ) * 10 + ( Get-Random 2 ) * 50 ) if( ( Get-Random 5 ) -eq 4 ){ Start-Sleep -Milliseconds 60 } } [console]::ForegroundColor="yellow" [console]::writeline( "`tdone!" ) [console]::ForegroundColor=$color }}
2021.03.06
コメント(0)
*nixのxevみたいなのをpowershell+windows.formsでできないかな、と思ってやってみたら結構できた。というわけでget-WinformEvent.ps1Add-type -AssemblyName system.windows.forms$Handler ={ ($sender, $e) = $this, $_ # sender($this) Write-Host '■イベントソース' Write-Host $sender.GetType().FullName # 型を表示 # event($_) Write-Host '■イベントデータ' Write-Host $e.GetType().FullName # 型を表示 Write-Host $($e | Format-List * | Out-String) # 全てのプロパティを表示}$form=new-object system.windows.forms.form$textbox=new-object system.windows.forms.textbox -Property @{ parent=$form; dock="fill"; multiline=$true}$textbox.add_KeyDown($Handler)$textbox.add_MouseDown($Handler)$textbox.add_MouseMove($Handler)$textbox.add_MouseWheel($Handler)$form.ShowDialog()こんなんで、結構それっぽいことができます。ただ、キーコードの取得で、prtscrキーの捕捉ができません。ググってみたところ、KeyDownじゃなくKeyUpで取れるのだそうです。ほかに、使えそうなマウス&キーイベントはこんな感じMouseCaptureChangedMouseClickMouseDoubleClickMouseDownMouseEnterMouseHoverMouseLeaveMouseMoveMouseUpMouseWheelKeyDownKeyPressKeyUp
2021.02.20
コメント(0)
UWSCスクリプトを作るとき、最初にpublic DEBUG=trueなんておまじないを付けているのは私だけではないはず。でも、これってtrue/falseを設定し忘れたりすると、結構めんどいことになることもあります。ECサイトで思いがけずポチっちゃったりして。で、自動でデバッグ中かどうかを返す関数を作ってみました。デバッグ中かどうか、なんてどうしてわかるの? という方はスクリプトを読んでください。IsInDebug.uwsif Get_Uwsc_Name="IsInDebug.uws" msgbox( IsInDebug() )endiffunction isInDebug() with createoleobj("WbemScripting.SWbemLocator") getOleItem(.ConnectServer.ExecQuery( "SELECT * FROM Win32_Process" )) endwith ParentPid="" ParentName="" for process in All_Ole_Item if process.processid=status(getid(GET_THISUWSC_WIN), ST_PROCESS) ParentPid=process.ParentProcessId break endif next for process in All_Ole_Item if process.processid=ParentPid ParentName=process.Name ParentName=copy( ParentName, 1, length(ParentName)-4 ) endif next result=!(!pos( ParentName, MyEditors ))textblock MyEditorssakura mery code atomendtextblockfendスクリプトの冒頭でコールしておけば、必要な時if IsInDebug()とかで制御できます。デバッグ中かどうかの判定は、エディタから起動したかどうか。ただそれだけ。テキストブロックに使いそうなエディタを書いておけば大抵用は足りると…。
2020.12.19
コメント(0)
powershellでタプルが使えることに気づいたので、思いついた。$n=72$x=$y=1;1..$n|%{$x,$y=$y,($x+$y)};$x #fib(72)を求める#806515533049393 を出力
2020.12.10
コメント(0)
文字コード表上で次の文字を取得したいことってありますね。何かテキスト処理をするとき、そのファイルにない文字を区切り文字に使ったり。textencodingほにゃららgetbyteとかなんとか結構めんどかったんだけど、試行錯誤でできました。powershell内部ではUnicodeで処理しているとかで、文字コード表はUnicodeのものになります。get-NextCodeCharfunction get-NextCodeChar( $c,[switch]$Decrease ){ if ( !$c ){ $c=$input } if ( !$c ){ return } if ( $Decrease ){ $inc=-1 }else{ $inc=1 } $result="" $c -split ""|%{ try{ $result+=[string]([char]([int]([convert]::ToChar($_))+$inc)) }catch{} } return $result}パイプや引数で文字を渡すとコード表で次の文字を返します。2文字以上の文字列なら、それぞれを一つずらしたものをくっつけて取得できます。-Decrease をつけて呼び出すと、「次」でなく一つ手前の文字になります。
2020.12.02
コメント(0)
inputにタイトルを表示するの新バージョン。前回はinputボックスだけを考えてみたけど、ほかのダイヤログも変えられないかなあと思って。そこで、考えたのは一時UWSCファイルを作って呼び出してみてはどうか。CallSub関数を作ってみたら、結構うまくいきました。第二引数をtrueにすると、サブ側でstdout(出力文字列)を実行することで、呼び出し元に値(文字列オンリー)を返せます。inputの使用例はこんな感じres=CallSub(sample,true)msgbox( res )textblock sample //サブプログラムoption DLGTITLE="入力してください" //ダイヤログタイトルの変更stdout(input( "サブプログラムからの入力プロンプト","既定値",,60,60 ))endtextblockCallSubUwsc.uwsfunction CallSub( AllText, isFunction=false ) fso=CreateOleObj("Scripting.FileSystemObject") repeat tmp=fso.GetTempName tempuws=Copy(tmp, 1, length(tmp)-4)+".uws" tempuws=fso.GetSpecialFolder(2) + "\" + tempuws until !fopen(tempuws, f_exists) if isFunction UWSText=AllText + "<#CR>" + stdout_uws else UWSText=AllText endif fd=fopen( tempuws, f_write16 ) fput( fd, UWSText, f_alltext ) fclose( fd ) UWSCEXE=GET_UWSC_DIR+"\uwsc.exe" if isFunction result=doscmd( UWSCEXE + " " + tempuws +"|more" )//このmoreを外すとなぜかエラーになります。ご注意を。 else exec( UWSCEXE + " " + tempuws ) endif deletefile(tempuws)textblock stdout_uws procedure StdOut(text) with CreateOleObj("Scripting.FileSystemObject") .GetStandardStream( 2 ).WriteLine( text ) endwith fendendtextblockfend
2020.11.25
コメント(0)
世界の感染状況を一覧するデスクトップアプリをつくってみました。NHKのサイトからデータを取ってくるんで、もし怒られたら削除します。powershellで作っていますが、起動の簡便のため、バッチ化しています。バッチでpowershellを書く時の参考になればいいな。感染者、死者、回復者の各欄をクリックするとそれぞれの項目にしたがって並び替えます。covid19.cmd@SET self=%0@SET args=%* &powershell -command "$lines=gc %Self%;$lines[2..($lines.length-1)],'',''" |powershell -windowstyle hidden -executionpolicy bypass -sta -command -& goto:EOF########################################################################################################引数処理#バッチの引数がpowershellの$arguments配列に入る。#二重引用符中の空白を除き、連続空白を1個のセパレータとして引数配列に分割する。#######################################################################################################$argstr =$env:args$arguments =@()$space ="<space>"while( $argstr -match $space ){ $space +="_"}$spacers =@()$regex =[regex]"`"[^`"]+`""#"エディタの文字列色別表示を満足させるための引用符。外してOK$matches =$regex.Matches( $argstr )$matches|%{ $from =$_.value $to =$from -replace " ", $space $spacers +=,@{ from =$from to =$to }}$spacers|%{ if (!$_){return} $argstr =$argstr.replace( $_.from, $_.to )}$argstr -replace " +", " " -split " "|%{ if ( !$_ ){return} $arg =$_ $spacers|%{ $arg =$arg.replace( $_.to, $_.from ) } $arguments +=,$arg}##############################################################################################################以下、powershellスクリプト領域#############################################################################################################add-type -assembly system.windows.formsadd-type -assembly system.drawingfunction new-winform( $name, $parent=$null, $attribute=$null ){ $res = iex "new-object System.Windows.Forms.$name" if ( $attribute ){ $attribute.Keys|%{ $res.$_=$attribute.$_ } } if ( $parent ){ $res.parent=$parent } return $res}$resp=(Invoke-WebRequest "https://www3.nhk.or.jp/n-data/dn/covid19-world-data.json").content$Json=ConvertFrom-Json ([System.Text.Encoding]::UTF8.GetString( [System.Text.Encoding]::GetEncoding("ISO-8859-1").GetBytes($resp) ))$WorldList=$Json.WorldList$jresp=(Invoke-WebRequest "https://www3.nhk.or.jp/news/special/coronavirus/data/summary.json").content$jjson=ConvertFrom-Json ([System.Text.Encoding]::UTF8.GetString( [System.Text.Encoding]::GetEncoding("ISO-8859-1").GetBytes($jresp) ))$Csv=@()$Json.worldList|%{ $name=$_.name $infected=[int]$_.confirmed $deaths=[int]$_.deaths try{ $recovered=[int]$_.recovered }catch{ $recovered=$null } $line=new-object PsObject foreach( $key in ("name,infected,deaths,recovered"-split",")){ $line|Add-Member -MemberType NoteProperty -Name $key -Value ( iex ("$"+$key ) ) } $Csv+=,$line}$line=new-object PsObject$line|Add-Member -MemberType NoteProperty -Name name -Value "日本"$line|Add-Member -MemberType NoteProperty -Name infected -Value ([int]($jjson.infection[0]))$line|Add-Member -MemberType NoteProperty -Name deaths -Value ([int]($jjson.death[0]))$line|Add-Member -MemberType NoteProperty -Name recovered -Value ([int]($jjson.recovered[0]))$Csv+=,$line$Csv=$Csv|Sort-Object -Property "infected" -Descending$UpdateDate=$jjson.date$dlg = new-winform form -attrib @{ text="新型コロナ 世界の感染者 ${UpdateDate}現在"; width=800; height=800}$gv = new-winform datagridview -parent $dlg -attrib @{ columnCount=4; RowCount=$WorldList.length + 2 dock="fill"; AutoSizeColumnsMode="fill";}$headers="国名、確認感染者、死者、回復者(ゼロは未公表含む)"-split"、"for( $i=0; $i -lt $headers.length; $i++ ){ $gv.columns[$i].name=$headers[$i]}$gv.Rows[0].Cells[0].Value="総数"$gv.Rows[0].Cells[1].Value=[int]$Json.total.confirmed$gv.Rows[0].Cells[2].Value=[int]$Json.total.deaths$gv.Rows[0].Cells[3].Value=[int]$Json.total.recovered$gv.Rows[0].Frozen=$truefor( $i=0; $i -lt $Csv.length; $i++ ){ $country=$Csv[$i].name $infected=$Csv[$i].infected $deaths=$Csv[$i].deaths $recovered=$Csv[$i].recovered $gv.Rows[$i+1].Cells[0].Value="$country" $gv.Rows[$i+1].Cells[1].Value=[int]$infected $gv.Rows[$i+1].Cells[2].Value=[int]$deaths try{ $gv.Rows[$i+1].Cells[3].Value=[int]$recovered }catch{} if ( $country -eq "日本" ){ 0..3|%{$gv.Rows[$i+1].Cells[$_].Style.BackColor="yellow"} }}1..3|%{ $gv.Columns[$_].DefaultCellStyle.alignment="middleright" $gv.Columns[$_].DefaultCellStyle.format="#,0"}$gv.add_RowPostPaint({ #$_.Rowindex|write-host $rectangle=New-Object System.Drawing.Rectangle( $_.RowBounds.Location.X, $_.RowBounds.Location.Y, ($gv.RowHeadersWidth - 4), $_.RowBounds.Height ) [windows.forms.TextRenderer]::DrawText( $_.Graphics, ($_.RowIndex).ToString(), $gv.RowHeadersDefaultCellStyle.Font, $rectangle, $gv.RowHeadersDefaultCellStyle.ForeColor, ([Windows.Forms.TextFormatFlags]::VerticalCenter -bor [Windows.Forms.TextFormatFlags]::Right) )})$dlg.showdialog()
2020.10.16
コメント(0)
UWSCのFukidasi(Balloon)って結構便利だったりするんで、powershellでもつかえないかな。使い方表示する $fuki=show-balloon "文字列"文言を変更 $fuki.setText("別の文字列")フォントを変更 $fuki.setFont((new-object system.drawing.font("MS明朝",9))フォントサイズだけ変更 $fuki.resizeFont(12)UWSCだと同一スレッドに1つしかfukidasiを持てないけれど、これはいくつでもOKその代わり、終了するときは明示的に $fuki.Close() が必要中身show-balloonの戻り値はただのwindowsforms.formにいくつかメソッドを追加したもの。なので、移動するなら $fuki.location=@{x=200;y=500} みたいにすればいい。balloon.ps1function show-balloon( $text ){ function new-winform( $name, $attribute=$null ){ $res = iex "new-object System.Windows.Forms.$name" if ( $attribute ){ $attribute.Keys|%{ $res.$_=$attribute.$_ } } return $res } function asyncshow( $winform ){ $rs =[Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() $rs.Open() $rs.SessionStateProxy.SetVariable("form",$winform) $p =$rs.CreatePipeline({[void]$form.ShowDialog()}) $p.Input.Close() $p.InvokeAsync() } $form=new-winform form -attrib @{ backcolor="yellow"; formborderstyle="none"; opacity=0.7; topmost=$true } $label=new-winform label -attrib @{ text=$text; textalign="MiddleCenter"; parent=$form; dock="fill" } $form|add-member -MemberType ScriptMethod -Name setText -Value { param($text) $label = $this.Controls[0] $label.text=$text } $form|add-member -MemberType ScriptMethod -Name setComplimentaryColor -Value { $bcol=$this.backcolor $max=$bcol.r if ( $bcol.g -gt $max ){ $max=$bcol.g } if ( $bcol.b -gt $max ){ $max=$bcol.b } $min=$bcol.r if ( $bcol.g -lt $min ){ $min=$bcol.g } if ( $bcol.b -lt $min ){ $min=$bcol.b } $fcol=[drawing.color]::FromArgb( $max + $min - $bcol.r, $max + $min - $bcol.g, $max + $min - $bcol.b ) $this.ForeColor=$fcol } $form|add-member -MemberType ScriptMethod -Name setFont -Value { param($font) $label = $this.Controls[0] if ( $font ){ $label.font=$font } else { $label.font } } $form|add-member -MemberType ScriptMethod -Name resizeFont -Value { param($size) $label = $this.Controls[0] $font=$label.font $label.font=new-object drawing.font( $font.name, $size ) } $label|add-member -MemberType NoteProperty -Name FormMinHeight -Value 40 $redraw={ $this.parent.width=$this.preferredSize.width + 10 $height=$this.preferredSize.height + 10 if ( $height -le $this.FormMinHeight ){ $height = $this.FormMinHeight } $this.parent.height=$height } $label.add_textchanged($redraw) $label.add_fontchanged($redraw) $form.width=$label.preferredSize.width + 10 $form.height=40 asyncshow $form $form}
2020.10.09
コメント(0)
powershellで別プログラムを動かしたいとき、単に記述するstart-processを使う方法があります。その別プログラムの出力結果をpowershellで利用したいとき、1.なら$Dir=cmd /c dirみたいに変数に入れればいいのですが、2.はちょっとやっかい。どうすればいいかググってみたので、powershellに移し替えてみました。$p=new-object system.diagnostics.process$pi=$p.startinfo$pi.FileName ="c:\windows\system32\ipconfig.exe"$pi.UseShellExecute = $false$pi.RedirectStandardOutput = $true$pi.CreateNoWindow = $true$p.start()$ipconfig=$p.StandardOutput.ReadToEnd()これで変数$ipconfigにipconfigの結果が入ります。どう考えても、$ipconfig=ipconfigのが早いんだけど、これはこれで使い道があるはず。あ、プログラムに引数を入れる場合は$pi.arguments="/?"#ヘルプ表示の場合みたいな感じ。
2020.09.26
コメント(0)
大抵のプログラミング言語だと、二つの変数を交換するとき一時的に使用する変数が必要になります。Cなどint a=3;int b=5;int temp;temp=a;a=b;b=temp;みたいな感じ。powershellはこれが1行でできちゃう。powershell$a,$b=$b,$a簡単! 交換だけでなく、たくさん動かすなら$a=1;$b=2;$c=3;$d=4$b,$c,$d,$a=$a,$b,$c,$d"$a,$b,$c,$d" #2,3,4,1みたいにすればOK。お、配列もいける。$list = 0, 1, 2, 3, 4$list[0], $list[3] = $list[3], $list[0]$list -join "," #3,1,2,0,4これ、pythonもおなじことができるようです。あ、rubyもできた!スクリプト言語はこうじゃなきゃ。気になってもうちょっとググってみた。あれ、C#もいけるじゃん。いまどきは、こういうの常識なのかな。ええい、ひとまとめでこれでどうだ。
2020.09.23
コメント(0)
ブラウザの自動操縦といえばselenium(WebDriver)みたいだけど新顔(ヘッドレス)が登場したらしい。決定版になるか?
2020.09.15
コメント(0)
powershellの関数(未確認だけどクラスも)は先に定義しておかなければ呼び出すことができません。これは「仕様」です。でも、プログラムするとき、最初に全体の構造を書いてあとから細かな関数なんかを書くほうが見通しが良くなります。逆に、長大な関数定義の後でメインルーチンがあると可読性もよくありません。最後まで読まないとなんのスクリプトかわからないからです。多くのプログラム言語は関数をどこに書いてもOKですが、powershellがそうでないのはなぜなのでしょう。powershellスクリプトが本格的なプログラム(C++とかC#とか)を書く前段のプロトタイプ言語プロトタイピング言語(2002/12/08修正)としても使われることを考えると、この「仕様」は更になぞです。シェル言語だからそんなもんだという話もあろうかと思うのですが、バッチやunix系シェルとの互換性が決して良いとは言えないpowershellがこんな制限を引きずっていることは甚だ不満です。例えば、コマンドインタプリタとしてbasicを利用していた8ビット時代のパソコンですら、関数を後ろに書くことができました。OS/2で第二シェルとして使われたREXXなんかはもっと本格的なプログラム言語でした。文句ばかり言っていてもきりがないので、対策。$SKIP=$true;iex ((gc $MyInvocation.InvocationName|%{ if ($SKIP -and ($_ -notmatch "^####FuncDef\s*$")){return} $SKIP=$false $_})-join "`r`n")$a=foobar|Write-Host #エラーになるfunction foobar{ "foobar"}$b=hogefuga|Write-Host #正常動作####FuncDeffunction hogefuga{ "hogefuga"}####FuncDef以降の行に書いた関数を先に読み込むというものです。$aへの代入ではfoobarが定義されていないのでエラーになりますが、$bに代入されるhogefugaは####FuncDef以降に定義されているので、ちゃんと機能します。
2020.09.13
コメント(0)
軽くて旧FireFoxコンパチのブラウザ「Pale Moon」を使っています。このブラウザ、メニュー周りの日本語対応は公式ではサポートしていません。しかし、Githubのプロジェクトからja.xpiを読み込めば簡単にインストールできます。ところが、palemoonのバージョンが28.10.0に上がったにもかかわらず、language packのバージョンは28.9.0のまま。ブラウザの更新後、日本語メニューが使えなくなってしまいました。強引に手作業でxpiファイルを更新することで、どうにか日本語メニューが使えるようになったので、ここに手順を記しておきます。xpiファイルをダウンロード前記Githubのページでなるべく最新のja.xpiを探し、「リンク先を保存」でデスクトップにダウンロード。xpiの中身のひとつ「install.rdf」ファイルを読み込む落としたja.xpiをja.xpi.zipにリネームし圧縮フォルダを表示。「install.rdf」をデスクトップにコピーし、テキストエディタで開く。ファイルを改造<em:maxVersion>28.9.*</em:maxVersion>の行を探し、「28.9.*」を「28.10.*」に変更、ファイルを上書き保存。このファイルを圧縮フォルダに投入、上書きする。圧縮フォルダをリネームし、元の「ja.xpi」にするpale moonでこのxpiを読み込みインストール成功
2020.06.06
コメント(3)
こんな感じの文字列$filters="HTML ファイル|*.html;*.htm,テキストファイル|*.txt,全てのファイル|*.*"を配列に分解しようとしてハマりました。コンマで分けた後、「|」で説明とワイルドカードに区切ろうとして「?」な現象が。$filter=($filters -split ",")[0]これで$filter="HTML ファイル|*.html;*.htm"となるとこまでは無事だったんですが、次に$filterを「HTML ファイル」と「*.html;*.htm」に分けようとして失敗。端末で $filter -split "|" と打ち込むとHTML ファ以下略と1文字ごとバラバラになってしまいました。どうやら、-split演算子で指定する区切り文字はただの文字として処理するのでなく正規表現を期待している模様。「-split "|"」は正規表現としてみると「-split ""」と同じなので結局全部を分化してしまったのでした。ここらへん、-replace演算子に触れた正規表現じゃない直接文字置換と同じようにやれば解決します。$filter -split [regex]::escape("|")ほかには、文字列のsplitメソッドを使って$filter.split("|")とやってもOK。powershellの文字列演算子は正規表現を期待していること、覚えておこう。
2020.05.29
コメント(0)
powershellの関数やスクリプトで可変個の引数を利用する場合、組み込み変数$ARGSでパラメーターにアクセスできます。大抵はそれでいいんだけど、困ったことが起きました。一部の引数のみ必須にして、残りは可変個というのがどうもうまくできないんです。function foo{ param( [parameter(mandatory=$true)]$MustArg ) "Mandatory Argument=$MustArg" "Other Arguments=$ARGS"}foo abc def ghiとやると、「引数 'def' を受け入れる位置指定パラメーターが見つかりません。」のエラーが。mandatoryとか関係なく、[parameter()]を付けると、その関数(スクリプト)に余計な引数を与えるとエラーになるようです。あちこちググって、参考サイトを見つけました。function hoge{ param( [parameter(mandatory=$true)][string]$FirstArg, [parameter(ValueFromRemainingArguments=$true)]$others ) $others}[parameter(ValueFromRemainingArguments=$true)]$othersというのが肝。残りの引数が、$others[]配列に入ってくれます。一方、$ARGSは空っぽのままのようです。
2020.03.12
コメント(0)
powershellでテキストファイルのエンコーディングを知るには(new-object io.streamreader("テキストファイルのパス")).CurrentEncodingってやるそうなのですが、これでSJISのファイルを判別しようとすると、SJISでなくUTF8が返ってきてしまいます。参考:PowerShellで、テキストファイルの文字コードを判定したい。。。古くはnkfなんかを使ったりしたものですが、Windows用のnkfを探すのも面倒だし、そもそもメンテされているのか怪しい。そこで、探してみたところ、いいのを見つけました。リンク先フォルダにあるcs4ファイルを拝借。こんな感じで、powershellの関数化できました。get-Encoding.ps1function get-Encoding( $filepath ){ try{ [void][Hnx8.ReadJEnc.ReadJEnc] #"AlreadyAdded" }catch{ #https://github.com/hnx8/ReadJEnc/tree/master/Source/Hnx8.ReadJEncから丸パクリ cd "4ファイルの格納フォルダ" add-type .\ReadJEnc.cs,.\FileType.cs,.\FileReader.cs,CharCode.cs #[Hnx8.ReadJEnc.ReadJEnc] } $file=Get-Item $filepath $reader=new-object Hnx8.ReadJEnc.FileReader( $file ) $reader.Read($file)}<#実例get-Encoding "sjisファイル"get-Encoding "utf8ファイル"get-Encoding "utf16leファイル"以下出力Name CodePage---- --------ShiftJIS 932UTF-8N 0UTF-16 0#>
2020.02.28
コメント(0)
仮掲示板での質問「配列を組み合わせて集計したい」。さすがstuncloudさんがさくっと回答しておられました。質問は件数を数えるだけだったので、複数の属性をそのまま文字列としてくっつけ連想配列で処理するというものでした。とはいえ、複数の属性にまたがったしぼ売込み絞り込み条件で検索・列挙・集計したいとなると単純な配列や連想配列では荷が重すぎます。こういうのは普通、データベースを構築してSQL文でクエリーを行うのでしょうけど、DBの構築だけでも結構な作業。UWSC一本でシンプルにできないかと考え、XMLの要素を探索するxpath式でクエリーを発行することを考えました。お題は質問と同じ果物でやってみました。どうせなら本格的なものを、と、農水省謹製のCSVを(ここらへんからリンクをたどって)拾って解析しています。なんちゃってDB.uws//青果市況をXMLに読み込みSQL文//IEがいると邪魔なので殺すpowershell("ps iexplore|kill")//XMLの準備xml=createoleobj( "Msxml2.DOMDocument.6.0" )xml.loadxml("<?xml version='1.0' encoding='utf-16'?><fruits/>")rootnode=xml.selectSingleNode("//fruits")//msgbox(xml.xml)//WebからCSVを落としてきて、XMLに読み込むCsvString=getFruitsMarketData()CsvTexts=split(CsvString,"<#CR>")sendstr(0,CsvTexts[0])titles=split(CsvTexts[0],",")for i=1 to length(CsvTexts)-1 terms=split(CsvTexts[i], ",") node=xml.createElement( "fruit"+i ) for j=0 to length( titles )-1 subnode=xml.createElement( titles[j] ) subnode.text=terms[j] node.appendChild(subnode) next rootnode.appendChild(node)next//べつにセーブする必要はないけれど書き出しておくほうが便利saveXmlWithIndent( xml, "C:\Users\satocha\Desktop\fruits.xml" )////////////////ここからDB(実はただのXML)へのクエリーをやってみる//温州みかんの産地を調べるfukidasi("温州みかんの産地を調べる")hashtbl ProducingAreafor node in getoleitem(xml.selectNodes("//品目名[contains(text(),'温州')]")) area=node.parentNode.selectSingleNode("産地名").text if area <> "" ProducingArea[ area ]="dmy" endifnextfor i=0 to length(ProducingArea)-1 msgbox( ProducingArea[i,hash_key] )next//愛媛産の果物をリストアップするfukidasi("愛媛産の果物をリストアップする")hashtbl FruitsOfEhimefor node in getoleitem(xml.selectNodes("//産地名[text()='愛 媛']")) fruit=node.parentNode.selectSingleNode("品目名").text if area <> "" FruitsOfEhime[ fruit ]="dmy" endifnextfor i=0 to length(FruitsOfEhime)-1 msgbox( FruitsOfEhime[i,hash_key] )next//////////////////////////////関数定義//セーブ用関数 いらないんだけどどうせならきれいにインデントしてセーブfunction saveXmlWithIndent( xml, path ) writer =createoleobj( "MSXML2.MXXMLWriter" ) reader =createoleobj("MSXML2.SAXXMLReader") fso =createoleobj("Scripting.FileSystemObject") textStream = fso.CreateTextFile( path, 1, -1 ) writer.indent = true writer.omitXMLDeclaration = true reader.contentHandler = writer reader.parse( xml ) textStream.Write(writer.output) textStream.Close() result=fopen( path, f_exists )fend//農水省の青果市況情報をCSVに落とす関数。//今回の主眼はスクレイピングじゃないのでやっつけ仕事。//IEの設定によっては手直しが必要function getFruitsMarketData( market="豊洲" ) BaseUrl="https://www.seisen.maff.go.jp/seisen/bs04b040md001/BS04B040UC010SC999-Evt001.do" Ie=CreateOleObj( "InternetExplorer.Application" ) Ie.Navigate( BaseUrl ) repeat fukidasi("waiting") try if !Pos( "青果物市況情報画面", Ie.document.title ) continue endif except continue endtry fukidasi("") break until false DateStr="" hashtbl ATagList for ATag in getoleitem( Ie.Document.GetElementsByTagName("A") ) text=trim(ATag.innerText) if Copy( text, 5, 1 )<>"年" then continue DateStr=DateStr+" "+text ATagList[ text ]=ATag.href next DateArray=split( trim(DateStr), " " ) qsort(DateArray,QSRT_NATURALD) Newest=DateArray[0] Ie.Navigate( ATagList[Newest] ) repeat fukidasi("waiting") try if !Pos( "東京都中央卸売市場豊洲市場", Ie.document.body.innerText ) continue endif except continue endtry fukidasi("") break until false hashtbl TdTagList for TdTag in getoleitem( Ie.Document.GetElementsByTagName("TD") ) text=trim(TdTag.innerText) if Pos( market, text ) if !pos( "<td>", TdTag.innerHTML ) break endif endif TdTag=null next if TdTag<>null getOleItem( TdTag.NextSibling.NextSibling.NextSibling.NextSibling.GetElementsByTagName("A") ) Ie.Visible=true all_ole_item[1].click() clkitem( getid( Ie.Document.title ) ,"保存",CLK_ACC) Ie.Visible=false else msgbox( "市場:" + market + "が見つかりません" ) exit endif Ie.Quit() //ダウンロードフォルダに落ちてくると決め打ち。ダウンロード失敗も考慮していない。 DLFolder=replace(Get_Appdata_Dir,"Appdata\roaming","Downloads" ) n=GetDir( DLFolder, "*.csv", true, 2 ) if n > 0 csv=DLFolder + "\" + getdir_files[n-1] fd=fopen( csv, f_read ) result=fget(fd,f_alltext) fclose(fd) deletefile( csv ) endiffend
2019.12.23
コメント(0)
以前書いたものがなんとなく動作が怪しかったのでリファイン。$linesに空文字を2つ追加しているのは無意味ではありません。これを付けておかないとソースの末尾に改行を付加しないと動きません。PsOnBatTmplate.cmd@SET self=%0@SET args=%* &powershell -command "$lines=gc %Self%;$lines[2..($lines.length-1)],'',''" |powershell -windowstyle hidden -executionpolicy bypass -sta -command -& goto:EOF########################################################################################################引数処理#バッチの引数がpowershellの$arguments配列に入る。#二重引用符中の空白を除き、連続空白を1個のセパレータとして引数配列に分割する。#######################################################################################################$argstr =$env:args$arguments =@()$space ="<space>"while( $argstr -match $space ){ $space +="_"}$spacers =@()$regex =[regex]"`"[^`"]+`""#"エディタの文字列色別表示を満足させるための引用符。外してOK$matches =$regex.Matches( $argstr )$matches|%{ $from =$_.value $to =$from -replace " ", $space $spacers +=,@{ from =$from to =$to }}$spacers|%{ if (!$_){return} $argstr =$argstr.replace( $_.from, $_.to )}$argstr -replace " +", " " -split " "|%{ if ( !$_ ){return} $arg =$_ $spacers|%{ $arg =$arg.replace( $_.to, $_.from ) } $arguments +=,$arg}##############################################################################################################以下、powershellスクリプト領域#############################################################################################################<# 動作テスト コメントを外してメッセージボックスが表示されたら正常動作add-type -assembly system.windows.forms[system.windows.forms.messagebox]::show("$Env:Self " + ($arguments -join ","))#>
2019.11.20
コメント(0)
powershellの関数やコマンドレットには命名規則が定められています。英語動詞-なんとかかんとかって形。例えばget-contentとか。 別に従わなくてもいいけど、ルールどおりやっておいたほうが何かとご利益があるのでは? と思い、どんな動詞が使えるのか調べてみました。MS公式いちいちネットで確認しなくてもいいようにpowershell自身に出力させてみます。("Common,Communications,Data,Diagnostic,LifeCycle,Security" -split","|%{(iex "[system.management.automation.Verbs$_]").getMembers()|?{$_.MemberType -eq "Field"}|%{$_.name}}) -join " "このワンライナーで次のリストが得られました。Add Clear Close Copy Enter Exit Find Format Get Hide Lock Move New Open Push Pop Remove Rename Reset Set Search Show Skip Step Join Redo Split Switch Select Undo Unlock Watch Send Receive Connect Disconnect Write Read Backup Checkpoint Compare Compress Convert ConvertFrom ConvertTo Edit Expand Export Group Import Initialize Limit Merge Publish Restore Save Sync Unpublish Update Mount Dismount Out Debug Measure Ping Repair Resolve Test Trace Approve Assert Complete Confirm Deny Disable Enable Install Invoke Register Request Restart Resume Start Stop Submit Suspend Uninstall Unregister Wait Grant Revoke Protect Unprotect Block Unblockこれ以外に汎用動詞 use- があるようです。もっと調べてから書けばよかった。get-verbこれ一発。Verb Group ---- ----- Add Common Clear Common Close Common Copy Common Enter Common Exit Common Find Common Format Common Get Common Hide Common Join Common Lock Common Move Common New Common Open Common Pop Common Push Common Redo Common Remove Common Rename Common Reset Common Search Common Select Common Set Common Show Common Skip Common Split Common Step Common Switch Common Undo Common Unlock Common Watch Common Backup Data Checkpoint Data Compare Data Compress Data Convert Data ConvertFrom Data ConvertTo Data Dismount Data Edit Data Expand Data Export Data Group Data Import Data Initialize Data Limit Data Merge Data Mount Data Out Data Publish Data Restore Data Save Data Sync Data Unpublish Data Update Data Approve Lifecycle Assert Lifecycle Complete Lifecycle Confirm Lifecycle Deny Lifecycle Disable Lifecycle Enable Lifecycle Install Lifecycle Invoke Lifecycle Register Lifecycle Request Lifecycle Restart Lifecycle Resume Lifecycle Start Lifecycle Stop Lifecycle Submit Lifecycle Suspend Lifecycle Uninstall Lifecycle Unregister Lifecycle Wait Lifecycle Debug Diagnostic Measure Diagnostic Ping Diagnostic Repair Diagnostic Resolve Diagnostic Test Diagnostic Trace Diagnostic Connect Communications Disconnect Communications Read Communications Receive Communications Send Communications Write Communications Block Security Grant Security Protect Security Revoke Security Unblock Security Unprotect Security Use Other 2021年12月21日追記powershell 6.0で追加された動詞が2つありました。build と deploy です。参照
2019.11.11
コメント(0)
uwscのpowershell関数にあれこれ悩んでいます。まず、起動が遅い。起動するためのオーバーヘッドは半端ないんだろうな。しかも、起動したpowershellのインスタンスを再利用できません。前回の結果を次のセッションで利用することができず、いつも単発の呼び出しだけ。じゃ、uwscからpowershellを呼ぶんじゃなくて、powershellからuwscを呼べばいいんじゃない? あるんですよ。stuncloud さんのPoshUwscとかしゅんさんのpowershell_uwsc_bridgeとか。でも、uwscメーンで、powershellのインタンスを1回起動したら、そのあとそのインスタンスとやり取りしたいってのもあってもいいんじゃない。つまり、powershellを起動しっぱなしにする。powershell側に目に見えないGUIを持たせてUWSCから操縦するってのを作ってみました。uwscユーザーですので、ソケットとかHTTPサーバとかじゃなく、ひたすらgetid sendstr clkitem getstrでいきます。※debugをtrueにすればGUIが見えます。※以前やったUWSCのpowershell関数をスピードアップの改訂版です。呼び出し例StayOnPs.debug=falsesop=StayOnPs.new()msgbox(StayOnPs.execute("ls"))msgbox(StayOnPs.execute("ls .."))stayOnPS.uwsmodule StayOnPs dim instancemax=10 hashtbl instance public DEBUG=true function new() if length(instance)>instancemax msgbox("powershellの実行数が上限を超えました") exit endif uwsPid=status(getid(get_thisuwsc_win),st_process) result=uwsPid + "_" + gettime() result=result + "_" + g_time_zz2 src=replace(psdlg_src,"<TITLE>",result) src=replace(src,"<UWSPID>", uwsPid) if DEBUG src=replace(src,"<DEBUG>", "$true") else src=replace(src,"<DEBUG>", "$false") endif powershell(src,true,false) id=getid(result,,5) if status(id, st_isid) ctrlwin(id,show) instance[result]=1 else msgbox("powershellの実行に失敗") exit endif textblock psdlg_srcadd-type -assembly system.windows.forms$title="<TITLE>"$uwsPid="<UWSPID>"$doNotShow=!<DEBUG>$prompt="sop>"$timer=new-object windows.forms.timer -property @{interval=55}$form=new-object windows.forms.form -property @{text=$title}$timer.add_tick({ if(ps -id $uwsPid){ }else{ ps -id $pid|kill }})$form.add_shown({$timer.start()})$base=new-object windows.forms.flowlayoutpanel -property @{dock="fill";parent=$form}$inBox=new-object windows.forms.textbox -property @{ parent=$base; multiline=$true; text=$prompt}$outLabel=new-object windows.forms.label -property @{ parent=$base; text=$prompt}$clr=new-object windows.forms.button -property @{ parent=$base; text="reset"}$exe=new-object windows.forms.button -property @{ parent=$base; text="exec"}$quit=new-object windows.forms.button -property @{ parent=$base; text="quit"; dialogresult="ok"}$clr.add_click({ $outLabel.text=$prompt $inBox.text=$prompt})$exe.add_click({ try{ $res=iex $inBox.text }catch{ $res=$error[0] } $outLabel.text=$res $inBox.text=$prompt})if ($doNotShow){ $form.opacity=0.01 $form.formborderstyle="none"}$form.showdialog() endtextblock fend function quit(title="newest") if title="newest" title=instance[length(instance)-1,hash_key] endif result=clkitem( getid(title), "quit" ) if result endif fend procedure quitAll() for i =0 to length(instance)-1 this.quit( instance[i, hash_key ]) next fend function execute(str,title="newest") if title="newest" title=instance[length(instance)-1,hash_key] endif id=getid(title) clkitem(id,"reset") sendstr(id,str,1,true) clkitem(id,"exec") repeat result=getstr(id,0,str_acc_static) until result<>"sop>" fend endmodule
2019.10.05
コメント(0)
仮掲示板で質問があったんで思わずググってしまいました。W10だとなんかやたらいろんな通知が画面の端から上がってくるんですが、あれのことらしいです。で、その機能はWindows8以降限定とのことで、7ユーザーとしては邪魔者でも「できない」といわれるのはシャクで。でタスクトレイからのバルーンチップを上げることで、似た感じになるのではと。trayBalloon.uwsif Get_Uwsc_Name="trayBalloon.uws" trayBalloon()endiffunction trayBalloon( title="uwscからの通知",message="uwscからの通知本文", toolTipIcon = "Info" ) textblock trayBalloon_ps powershell -sta -command @' add-type -assemblyname System.Windows.Forms add-type -assemblyname System.Drawing [string]$tilte = '<TITLE>' [string]$message = '<MESSAGE>' [string]$toolTipIcon = '<toolTipIcon>' $exepath='UWSCEXE' $notifyIcon = New-Object System.Windows.Forms.NotifyIcon try{ $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($exepath) }catch{ $newpath=join-path $Env:Temp (split-path -leaf $exepath ) cp $exepath $newpath $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($newpath) } $notifyIcon.Icon = $icon $notifyIcon.Visible = $true $notifyIcon.ShowBalloonTip( 500, $tilte, $message, $toolTipIcon) '@ endtextblock select toolTipIcon case "None","Info","Warning","Error" //do nothing default toolTipIcon="Info" selend src=replace( trayBalloon_ps, "UWSCEXE", GET_UWSC_DIR + "\uwsc.exe" ) src=replace( src, "<TITLE>", title ) src=replace( src, "<MESSAGE>", message ) src=replace( src, "<toolTipIcon>", toolTipIcon ) result=powershell( src )fend
2019.09.27
コメント(0)
powerhell_iseの画面で編集メニューの「切り取り」が効きません。キーボードショートカットがバッティングしてるのかと思ったので、「編集」メニューから操作してみてもダメ。何がダメかというと、コピーバッファには送られるんだけど、切り取りができないという症状。つまり、コピーと同じってわけ。「powershell _ise edit menu cut」で検索するとありました。technetのやりとりが。ピント外れの回答に若干キレぎみなやりとりがあったりして、挙句、出てきた答えがこれ。Are you running in a VM by any chance?(もしか、仮想環境で動かしたりして?)そうです。私の場合もそうでした。アドバイスに従って、「クリップボードの共有」をオフにすると正常動作しました。でも、コピペの共有を切ると不便なんだよな。これ、Virtualboxの不具合ってことになるのかな。
2019.09.14
コメント(0)
いろいろ謎の多いpowershellの$null。<謎1>よくやりがち(私だけですが)なのが、$nullって型は何だっけと思い$null.gettype().nameとタイプしてシステムに怒られるやつです。$nullの型ってどうやって調べるのでしょう。<謎2>そうだ。数値と$nullを比べてみよう。 $null -eq 0 #falseゼロではないらしい。じゃ、 $null -gt 0 #falseなら、 $null -lt 0 #trueどうやらマイナスの数のよう。じゃ、 [math]::sign($null) 0ううん。なんだかわからん。今のところ、「0 より小さいが符号はゼロである何か」ってところ。<謎3>$nullを要素に含む配列を$nullと比較してはいけないらしい。だめだと言われればやってみたくなるのは、ただの天邪鬼だ。で、 if(@(1,$null,3) -eq $null){"NULL"}else{"Not A Null"} Not A Nullなるほど。んじゃ、 if(@(1,$null,2,$null,4) -eq $null){"NULL"}else{"Not A Null"} NULLううん、$nullが複数だとnull判定されるのか。 if(@(1,$null,,$null,4) -eq $null){"NULL"}else{"Not A Null"} Not A Nullえ?じゃ $a=@($null,$null);$b=@($null,,,$null) $a.length;b.length 2 2$aと$bはどちらも、2つの$nullを要素とする配列だな。null判定すれば同じ結果になるはず。 $a,$b|%{if ( $_ -eq $null){"Null"}else{"Not A Null"}} Null Not A Nullもう、ここらへんでギブアップ。だれか教えて!
2019.09.08
コメント(0)
何かと便利なHTA。HTAファイルを作らなくても、GUI画面を簡単に出せます。とはいえ、実際にやってみると、1行の長さに対するOS(あるいはコマンドシェル)の制限により、それほど長いHTMLを読ませることは難しいです。日付を入力させる程度なら簡単ですけど。そこでどうしてもHTAファイルを作らなくちゃいけない、と思いきやFSO(Scripting.FileSystemObject)の力を借りて長いHTMLを読み込むことが可能なことが分かりました。こんな具合。$HugeHtml=@"長いHTML長いHTML長いHTML"@$HugeHtml|mshta "about:<script>document.write((new ActiveXObject('Scripting.FIleSystemObject')).GetStandardStream(0).ReadAll())</script>"バッチだと環境変数に格納できる文字数に制限があるので、powershellでやっています。
2019.09.03
コメント(0)
よくあるやつ。GUIで設定するなら、例えばこれ。コマンドレベルでやろうとすると、レジストリ操作が伴います。面倒なんで、powershellの関数にしてみました。使い方は、. DefaultButton.ps1set-MouseJumpModeToDefaultButton #引数なし:現在の設定の問い合わせ 1 なら設定済みset-MouseJumpModeToDefaultButton 1 #1を与えると設定。set-MouseJumpModeToDefaultButton 0 #0を与えると解除。DefaultButton.ps1function set-MouseJumpModeToDefaultButton( $argv1="q" ){ if ( !( test-path hku:) ){ New-PSDrive -name HKU -PsProvider Registry -Root HKEY_USERS|out-null } foreach( $x in (ls 'HKLM:\software\Microsoft\windows NT\CurrentVersion\ProfileList') ){ if ( (gp ("$x" -replace "^HKEY_LOCAL_MACHINE","HKLM:")).ProfileImagePath -eq $env:USERPROFILE ){ $sid=split-path -leaf "$x" break } } $mouse="hku:$sid\Control` Panel\mouse" switch($argv1){ "q"{(gp $mouse).SnapToDefaultButton} $null{remove-itemproperty $mouse SnapToDefaultButton} "1"{set-itemproperty $mouse SnapToDefaultButton 1} "0"{set-itemproperty $mouse SnapToDefaultButton 0} default{<# nothing #>} }}
2019.08.31
コメント(0)
よくあるやつ。GUIで設定するなら、例えばこれ。コマンドレベルでやろうとすると、レジストリ操作が伴います。面倒なんで、powershellの関数にしてみました。使い方は、. DefaultButton.ps1set-MouseJumpModeToDefaultButton #引数なし:現在の設定の問い合わせ 1 なら設定済みset-MouseJumpModeToDefaultButton 1 #1を与えると設定。set-MouseJumpModeToDefaultButton 0 #0を与えると解除。DefaultButton.ps1function set-MouseJumpModeToDefaultButton( $argv1="q" ){ if ( !( test-path hku:) ){ New-PSDrive -name HKU -PsProvider Registry -Root HKEY_USERS|out-null } foreach( $x in (ls 'HKLM:\software\Microsoft\windows NT\CurrentVersion\ProfileList') ){ if ( (gp ("$x" -replace "^HKEY_LOCAL_MACHINE","HKLM:")).ProfileImagePath -eq $env:USERPROFILE ){ $sid=split-path -leaf "$x" break } } $mouse="hku:$sid\Control` Panel\mouse" switch($argv1){ "q"{(gp $mouse).SnapToDefaultButton} $null{remove-itemproperty $mouse SnapToDefaultButton} "1"{set-itemproperty $mouse SnapToDefaultButton 1} "0"{set-itemproperty $mouse SnapToDefaultButton 0} default{<# nothing #>} }}
2019.08.31
コメント(0)
拡張子から既定のアプリケーションを探す。 簡単そうに見えて意外に難しいんです。 レジストリ、みれば簡単じゃん、って思ったあなた、甘い、甘い。 そもそも、拡張子とアプリケーションの関連付けはWindowsのバージョンアップに伴って、いろいろ変わってきています。 特に、最近は、セキュリティ上の理由から、ユーザーがGUIで設定しないといけないようになっていて、一筋縄ではいきません。 じゃ、どうするか。 その拡張子のダミーファイルを作って、起動しちゃえばいいじゃん。 なので、作ってみました。get-DefaultApplication.ps1function get-DefaultApplication{ param( [parameter(mandatory=$true)] [string]$extension ) if( $extension[0] -ne '.' ){ $extension=".$extension" } $Dummy=join-path $env:TEMP "dummy$extension" $BeforeStart=[datetime]::Now "">$Dummy try{ start-process $Dummy }catch{ if( $error -match "この操作に対して指定されたファイルには、アプリケーションが関連付けられていません" ){ rm $Dummy return "NotAssociated" } } $newerProcesses=gwmi win32_process|?{ $_.ConvertToDatetime($_.CreationDate) -gt $BeforeStart } if( $pr=($newerProcesses|?{ $_.name -eq "openwith.exe" }) ){ $pr|%{$_.terminate()}|out-null rm $Dummy return "NotAssociated" } if ( $newerProcesses.gettype().name -match "\[\]$" ){ $oldest=$null $newerProcesses|%{ if (!$oldest){ $oldest=$_ return } if( $_.ConvertToDatetime($_.CreationDate) -lt $oldest.ConvertToDatetime($oldest.CreationDate) ){ $oldest=$_ return } } $newerProcesses=$oldest } $newerProcesses.terminate()|out-null rm $Dummy $newerProcesses}<# 拡張子HTMを調べてみる。get-DefaultApplication htm#>
2019.07.22
コメント(0)
HTAだとセキュリティに引っかかるとのことなので、powershell経由でwindows.formsのwebbrowserコントロールで書いてみました。これなら、HTMLの知識で書けます。textblock formsource<h1>お料理申し込み</h1>メニュー<select id="sel_menu" name="sel_menu"> <option selected>和食</option> <option>中華</option> <option>洋食</option></select><br/>お一人さまご予算<select id="sel_price" name="sel_price"> <option selected>1500円未満</option> <option >1500円~4999円</option> <option >5000円以上</option><select/><br/>人数<input type="text" id="howmany" name="howmany" value="1" style="width:80px"/><br/>コース<input type="radio" name="courese" value="lunch" checked>ランチ <input type="radio" name="courese" value="dinner">ディナー<br/>特記事項<input type="checkbox" name="special" value="nosmoking">禁煙 <input type="checkbox" name="special" value="child">お子様連れendtextblockres=getFormResult( formsource )msgbox(res)function getFormResult( HTML ) result =powershell( replace(pssrc,"dummy",HTML ) )fendtextblock pssrc$PSSRC=@'add-type -assembly system.windows.formsfunction mkWFItem( $itemname, $parent, $atrb ){ $item=iex "new-object system.windows.forms.$itemname" if( $parent ){ $item.parent=$parent } if(( $atrb ) -and ( $atrb.gettype().name -eq "Hashtable" )){ $atrb.keys|%{ if ( $_ -like "add_*" ){ iex "`$item.$_( `$atrb.`$_ )" } else { $item.$_=$atrb.$_ } } } return $item}$base=mkWFItem form -a @{ text="UwscFormDialog"}$br=mkWFItem webbrowser -p $base @{ anchor=[System.Windows.Forms.AnchorStyles]"top" -bor [System.Windows.Forms.AnchorStyles]"right" ` -bor [System.Windows.Forms.AnchorStyles]"left" -bor [System.Windows.Forms.AnchorStyles]"bottom" width=$base.clientsize.width; height=$base.clientsize.height - 50; }$btn=mkWFItem button -p $base -a @{ text="ok"; top=$base.clientsize.height - 30 left=$base.clientsize.width - 120 anchor=[System.Windows.Forms.AnchorStyles]"bottom" -bor [System.Windows.Forms.AnchorStyles]"right"; add_click={ $br.document.invokescript("setReusult",$null) $br.document.getElementById("resdiv").innerText|write-host $base.close() }}$base.add_shown({ $br.navigate("about:blamk") while ($br.ReadyState -ne "complete"){ [System.Windows.Forms.Application]::DoEvents() } $HTML=@"<body><form name='uwscform' id='uwscform'>dummy</form><script>function setReusult(){ var uform=document.getElementById('uwscform') var resdiv=document.getElementById('resdiv') if( !resdiv ){ resdiv=document.createElement('div') resdiv.id='resdiv' resdiv.style='display:none' resdiv.appendChild(document.createTextNode("dmy")) document.body.appendChild(resdiv) } resdiv.innerHTML='' var selects=uform.getElementsByTagName( 'select' ) for( var i=0,len=selects.length; i< len;i++ ){ var select=selects[i] resdiv.innerHTML+=select.name + '=' + select.options[select.selectedIndex].outerHTML+'<br/>' } var inputs=uform.getElementsByTagName( 'input' ) for( var i=0,len=inputs.length; i< len;i++ ){ var input=inputs[i] if ( !input.type ||( input.type.match(/^text$/i) )){ resdiv.innerHTML+=input.name + '=' + input.value+'<br/>' continue; } if ( input.type.match(/^(radio)|(checkbox)$/i) && input.checked ){ resdiv.innerHTML+=input.name + '=' + input.value+'<br/>' continue; } } var textareas=uform.getElementsByTagName( 'textarea' ) for( var i=0,len=textareas.length; i< len;i++ ){ var textarea=textareas[i] resdiv.innerHTML+=textarea.name + '=' + textarea.value+'<br/>' }}</script></body>"@ $br.document.write($HTML)})[void]$base.showdialog()'@$encoded=[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes( $PSSRC )) -replace "[\r\n]",''powershell -sta -encodedcommand $encodedendtextblock
2019.05.12
コメント(1)
appフォルダのファイル名に日本語を使うとよくないことが起こる。
2019.04.08
コメント(0)
UWSCのビルトイン関数「powershell」は、端末デフォルトのpowershellを起動しているみたいです。 なので、Win7マシンでexecutionpolicyをいじっていない場合、外部スクリプトの実行不可でスレッドアパートンメントはMTAの状態でpowershellを動かします。 windows.formsでGUI画面を出力したり、自作ライブラリを読み込んだりといった使い方ができないので、対策。使い方はこんな感じ。call OptionedPowershell.uwsdim options[]="-sta","-executionplicy bypass"textblock src[threading.thread]::CurrentThread.GetApartmentState()get-ExecutionPolicyendtextblockmsgbox( OptionedPowershell( src, options ) ) OptionedPowershell.uwsfunction OptionedPowershell( src, options[] ) encodedSource =powershell( "[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes( '" + src + "' ))" ) encodedSource =replace( encodedSource, "<#CR>", "" ) result =powershell( "powershell " + join( options, " " ) + " -EncodedCommand " + encodedSource )fend
2019.03.25
コメント(0)
フォルダ選択ダイヤログを開くスクリプトを書いたんだけど、肝心のダイヤログが他のウインドウの陰に隠れて気付かれない、という問題が起きました。対策を調べてみたら、こんな感じで書けばいいのではと。$folderbrowser=new-object system.windows.forms.folderBrowserDialog$dmy=new-object system.windows.forms.form$dmy.topmost=$true$folderbrowser.showdialog($dmy)ファイル選択ダイヤログだと、$filedialog=new-object system.windows.forms.openFileDialog$filedialog.showhelp=$true$dmy=new-object system.windows.forms.form$dmy.topmost=$true$filedialog.showdialog($dmy)
2019.03.01
コメント(0)
powershell3.0以降はget-content -tailがあるので問題ないのですが、windows7で巨大ログを見たいときなど、get-content -path ファイルパス |select -last 行数なんてやると、ファイルを全部読み込んじゃうまで待たされてキツイわけです。で、function tail( $path, [int]$num=40 ){ if ( $num -lt 0 ){ [io.file]::readAllLines($path)[$num..-1] } else { [io.file]::readAllLines($path)[(-1*$num)..-1] }}これも、全部読み込んではいるんだけど、行レベルで読んでいるので十数倍は軽減できそう。これ以上速度を上げるなら、行単位ではできないけどバイト単位でfunction tail( $logpath, $bytes=1024 ){ $fs =[System.IO.File]::OpenRead($logpath) $fs.Position =$fs.Length - $Bytes $enc =[System.Text.Encoding]::unicode $sr =New-Object System.IO.StreamReader( $fs, $enc ) $text =$sr.ReadToEnd() $sr.Close() $fs.Close() return $text}これなら、一瞬で終わるんだけど行ベースでないところがなんだかなあ。書いた後、ちょっとぐぐってみたら、PSCXを入れればget-FileTailコマンドレットが使えるそうな。ソースを見るとsjis未対応ではあるようですが。
2019.02.05
コメント(0)
uwscの組み込みインプットボックス関数「input」は機能豊富ですが、入力ダイヤログのタイトルは自由に設定できません。 Option DlgTitleで値を設定すればその文字列、無指定なら "UWSC - "+Get_Uwsc_Nameがタイトルに表示されます。Option DlgTitleはinputのみならずmsgboxなどほかのUWSC組み込みダイヤログのタイトルと共用なので、使い勝手はよくありません。確か、途中で値を変更することもできません。検証スクリプト //option dlgtitleは何回も書けるが効果があるのは最後の1回だけ。//下のmsgboxは3回ともt「itle 2」msgbox("aaa")option dlgtitle="title 1"msgbox("aaa")option dlgtitle="title 2"msgbox("aaa") そこで、タイトル付きインプットボックス関数「inputbox」を作ってみました。<ポイント>VB.NETのinputboxはタイトルを付けられるので、powershell経由で呼びます。ただし、UWSCのpowershell関数からwindows.forms出力しても(VB.NETのinputboxもwindows.formらしい)、出力が隠されてしまいます。powershell関数の第三引数をtrueにすると表示できるがpowershellの出力を受け取れなくなってしまいます。そのため、inputboxを実行したらそのウインドウをctrlwin(id,show)してやります。同時並行処理となるのでスレッド展開します。ウインドウIDはinputboxのタイトル名とウインドウクラス名(先述の通り「WindowsFormsほにゃらら」)で指定します。念のため実行ファイルがpowershell.exeであることも確認しています。inputbox.uwsif GET_UWSC_NAME = "inputbox.uws" a=inputbox( "入力してください", "input_テスト中" ) msgbox(a)endiffunction inputbox( msg="", title=GET_UWSC_NAME ) src ="[void][Reflection.Assembly]::LoadWithPartialName(<#DBL>Microsoft.VisualBasic<#DBL>);" src =src+"[Microsoft.VisualBasic.Interaction]::InputBox(<#DBL>@@@msg@@@<#DBL>,<#DBL>@@@ittle@@@<#DBL>);" thread inputbox_sub( title ) result=powershell( replace( replace( src, "@@@msg@@@", msg ), "@@@ittle@@@", title ) )fendprocedure inputbox_sub(title) while true for id in getallwin() if status( id, st_title ) <> title then continue if pos( "WindowsForms", status( id, st_class ) )<> 1 then continue if pos( "powershell.exe", status( id, st_path ) ) = 0 then continue break 2 next wend ctrlwin( id, show ) ctrlwin( id, activate ) ctrlwin( id, normal )fend20190320追記えらく手間をかけていますが、uwscからSTAモードでpowershellを起動すれば、別スレッドで表示させなくてもウインドウが出てくれます。そこで関数をこうすれば簡単。function inputbox( msg="", title=GET_UWSC_NAME ) src="powershell -sta -command <#dbl>" src =src + "[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic');" src =src + "[Microsoft.VisualBasic.Interaction]::InputBox('@@@msg@@@','@@@ittle@@@');<#dbl>" result=powershell( replace( replace( src, "@@@msg@@@", msg ), "@@@ittle@@@", title ) )fend
2019.01.10
コメント(0)
user32.dllの「GetKeyboardState」APIを使って複数キー読み込みをしてみました。同じことは組み込み関数のGetKeyStateでできるんですが、読み込みが1回でできます。仮想キーコードはここがよくまとまっているみたい。※12・26追記ソースのコメントをもう少し丁寧に書けば良かった。getPushedKeys()は押された複数のキーのキーコードを要素として持つ配列を返す関数です。各配列の値はキーコードです。例えば、得られた配列(値の昇順で入るみたい)の中に、65と66があれば、「A」と「B」が同時に押されたということが分かる仕掛けです。getPushedKeys.uwsif get_uwsc_name="getPushedKeys.uws" while 1 pushed =getPushedKeys() keys ="キーを押すと、下にキーコードが表示されます。alt+f2で終了<#CR>" for key in pushed keys =keys + key + "," next fukidasi( keys ) wendendiffunction getPushedKeys( skipToggles=true ) def_dll GetKeyboardState( var byte[] ):bool:user32.dll result ="" if skipToggles //トグル系のキーは何もしなくても押されたことになるのでデフォルトで排除 last =239 else last =255 endif buff =safearray( 0,last ) GetKeyboardState( buff ) for i =0 to last PushedKey =buff[ i ] if PushedKey > 127 result =result + i + "," endif next //余分なコンマを外す result =copy(result, 1, length( result )-1) result =split( result, "," )fend
2018.12.25
コメント(2)
えらく遠回りでしか取得できません。2019/01/27追記バカバカバカ!status(getid(get_thisuwsc_win),st_process)で簡単ジャン。以下は恥ずかしいけど、自分の無知をさらしておきます。(1)自身のウインドウID→自身のウインドウハンドル→自身のプロセスID手間がかかっているようですが、(2)より速い。pid=-9999def_dll GetWindowThreadProcessId( dword, var dword ):dword:user32.dllGetWindowThreadProcessId( idtohnd(getid( get_thisUWSC_Win )), pid )msgbox(pid)(2)powershell起動→$pidでpowershell自身のプロセスID取得→プロセス取得→親プロセス(つまりUWSC)のプロセスID取得遅いのはpowershell起動のオーバーヘッドのせいでしょうか。msgbox(trim( powershell( "(gwmi Win32_Process -filter ProcessId=$pid).ParentProcessId" ) ))
2018.12.19
コメント(0)
しろまささんブログに触発され、N進変換を書いてみました。siromasa進数には未対応。ChangeRadix.uwsif Get_UWSC_Name="ChangeRadix.uws" //1121を36進法で表示→v5 msgbox( NumbertoRadix( 1121, 36 ) ) //36進数「v5」の10進表示→1121 msgbox( RadixToNumber( "v5", 36 ) ) //36進を超えるとエラー→空文字 msgbox( NumbertoRadix( 1121, 38 ) )endiffunction NumbertoRadix( n, r ) com_err_ign with createoleobj( "ScriptControl" ) .language="JScript" .addCode( "function f(x,y){ return x.toString(y)}" ) result=.CodeObject.f(n,r) endwith com_err_ret if com_err_flg result="" endiffendfunction RadixToNumber( str, r ) com_err_ign with createoleobj( "ScriptControl" ) .language="JScript" .addCode( "function f(x,y){ return parseInt( x, y )}" ) result=.CodeObject.f(str,r) endwith com_err_ret if com_err_flg result="" endiffend
2018.12.19
コメント(0)
以前、マイクロソフトの穂スティングサイトCodePlexから配布ファイルを取得する方法について書いたんですが、結構面倒くさい手順だったので、powershellスクリプトを作りました。巨大アーカイブをダウンロードし、zipを展開してできたフォルダ直下に次のスクリプトを書いて実行すれば、自動で必要なzipが生成されます。吸い出し.ps1#Json読み出し関数 ネタ元はhttps://stackoverflow.com/questions/28077854/powershell-2-0-convertfrom-json-and-convertto-json-implementation<#function ConvertTo-Json20([object] $item){ add-type -assembly system.web.extensions $ps_js=new-object system.web.script.serialization.javascriptSerializer return $ps_js.Serialize($item)}#>function ConvertFrom-Json20([object] $item){ add-type -assembly system.web.extensions $ps_js=new-object system.web.script.serialization.javascriptSerializer #The comma operator is the array construction operator in PowerShell return ,$ps_js.DeserializeObject($item)}$Global:PsScriptRoot=split-path -parent $MyInvocation.MyCommand.Definition$Latest =@{ModifiedDate=[datetime]"0001/01/01"}$JsonFile ="$Global:PsScriptRoot\releases\releaseList.json"(ConvertFrom-Json20 ( gc $JsonFile ))|%{ $date =[datetime]$_.ModifiedDate if ( !$_.Files ){ return } if ( $date -gt $Latest.ModifiedDate ){ $Latest =$_ }}if (!$Latest.Files){ throw "不明なエラー"}$Latest.Files|%{ $FileName =$_.FileName $Url =$_.Url $Path =join-path "$PsScriptRoot\releases" $Url $newPath ="$PsScriptRoot\$FileName" cp $Path $newPath}
2018.11.25
コメント(0)
しろまささん開設の掲示板に投稿したものと同じです。if get_UWSC_Name="deleteHistory.uws" ie =createoleobj( "internetexplorer.application" ) ie.navigate("https://www.yahoo.co.jp") ie.visible =true msgbox( "ヤフーのページが表示されたらOKを押してください" ) msgbox( "履歴を開いて「今日」のヤフーを確認してください" ) msgbox( "ヤフーの履歴をUWSCで消します" ) deleteHistorySite( "yahoo","今日" ) msgbox( "履歴を開いて「今日」の履歴にないことを確認してください" ) msgbox( "「今日」の履歴を丸ごとUWSCで消します" ) deleteHistoryDate( "今日" ) msgbox( "履歴を開いて「今日」の履歴が空(もしくは新規タブページのみ)になっていることを確認してください" )endiffunction deleteHistoryDate( DateString ) thread pressYes() with createoleobj( "shell.application" ) historyRoot=.namespace(34).items found =false for DatedHistory in historyRoot if DatedHistory.isfolder and (DatedHistory.name = DateString) found =true break endif next if !found result="" exit endif DatedHistory.invokeverb( "delete" ) endwith //dialogid =getid()fendfunction deleteHistorySite( SiteString,DateString="今日" ) thread pressYes() with createoleobj( "shell.application" ) historyRoot=.namespace(34).items found =false for DatedHistory in historyRoot if DatedHistory.isfolder and (DatedHistory.name = DateString) found =true break endif next if !found result="" exit endif websites =DatedHistory.GetFolder.Items() found =false for website in websites if pos( SiteString, website.name ) website.invokeverb( "delete" ) endif next endwith //dialogid =getid()fendprocedure pressYes() while 1 found =false for id in getallwin() if status( id, st_title )="警告" and _ status( id, st_class )="#32770" text =getstr(id,0,STR_ACC_STATIC) // = "次の履歴の項目を削除しますか? 今日" if pos( "次の履歴の項目を削除しますか?", text ) found =true break endif endif next sleep(0.05) if found clkitem(id,"はい",CLK_BTN) exit endif wendfend
2018.10.28
コメント(0)
公式掲示板が書き込めなくなってどうなるかと心配していましたが、しろまささんが掲示板を用意してくれました。http://www3.rocketbbs.com/601/siromasa.html
2018.09.24
コメント(0)
全110件 (110件中 1-50件目)