2009/06/08

むたぐちです。いろいろあってご無沙汰になっていますが、ぼちぼち復活中です。

1年間更新が途絶えていたWSH連載(@IT)が再開になりました。遅くなってすみませんです。

チェック式 WSH入門
第18回 FileSystemObjectオブジェクトを利用する(3)
http://www.atmarkit.co.jp/fwin2k/tutor/cformwsh18/cformwsh18_01.html

懲りずにネタを仕込んでますが気づいた方はしれっと流してくださいw

この連載記事も次回で最終回です。 @ITのWindows Server Insiderフォーラムではいつも上位PVをキープしているようでありがとうございます。

http://www.atmarkit.co.jp/fwin2k/

また、Windows 7とWindows Server 2008 R2の標準機能(コマンドプロンプトと同様に削除もできない)となるPowerShell ver2についていち早く紹介するセッションを7/4(土)わんくま大阪勉強会でやります。ぜひご参加ください!

http://www.wankuma.com/seminar/20090704osaka30/Default.aspx

おそらく、7を入れてみて多くの人が思うことは、まずタスクバーが分からないってのと、スタートメニューのアクセサリにあるPowerShellってなんぞ?ってなると思うんですよね。タスクバーはタスクバーのプロパティを適当に設定すればVistaライクになりますが、PowerShellはいきなり見てもなんだか分からないと思いますので、基礎をざっとやって、あとはver1からの変更点をお話します。

あと6/13わんくま大阪もスタッフとして参加しますのでよろしくですv

元記事:http://blogs.wankuma.com/mutaguchi/archive/2009/06/08/174534.aspx

2008/12/07

レガシASPでサイトを作ってると、Shift-JISなサイトを作るのが基本になると思います。なんでかというと、FileSystemObjectが基本的にShift-JISの読み書きにしか対応しておらず(UTF-16もいけますが)、いまどきのUTF-8を使うのはちょっと面倒です(FSOの代わりにADODB.Streamを使えば行けますけどどうでしょうねー?私はあんまり好きじゃないです)。

ただ、UTF-8な他のWebサイト/サービスと連携する場合はどうしても避けて通れません。そこでレガシASPでShift-JISなページを作る際、UTF-8文字列を扱う上で知っておくべきこと。

1. escape関数を使うとShift-JISでURLエンコードがされる

ASPはだいたいVBScriptで書くと思うんですが、隠し関数であるescape関数を使うとURLエンコードができます。ですが、escape関数は呼び出し元のページコードの文字コードでエンコードします。なのでShift-JISなページで呼び出すとShift-JISのエンコードURLを出力します。(ちなみにWSHで使うとUTF-16のものになる)

JScriptのencodeURIComponent関数はどんな場合でもUTF-8文字列を出力するので、これを使うといいでしょう。使い方はこうです。

Set sc = CreateObject("ScriptControl")
sc.Language = "JScript"
Set js = sc.CodeObject
Response.Write js.encodeURIComponent("文字列") 

逆にShift-JISなページでShift-JISなエンコードURL文字列を取得したい場合は単にescape関数を呼び出せばいいです。
さらに別なケースですがUTF-8なページでShift-JISなエンコードURLを取得したい場合は、こんな関数を使うといいんじゃないでしょうか

2. XMLHTTPでPostメソッドでSendする際は必ずUTF-8でURLエンコードがされる

Set xh = CreateObject("MSXML2.XMLHTTP")
xh.Open "POST", "http://hogehoge/hoge.aspx", False
xh.Send "文字列"

このように何も考えずに書いても、勝手にUTF-8でURLエンコードされてPostされるので大丈夫です。

3. UTF-8なページのHTMLを読み込む際

標準機能だけでやろうと思うとADODB.Streamを使うしかないと思います。
ちなみに読み込むページの文字コードが不明の場合は判定した上で変換する必要がありますが、これはかなり面倒なので、BASP21を使うといいんじゃないでしょうか。

Function GetPageString(strUrl)
 Set bobj = CreateObject("basp21")
 Set oHTTP = CreateObject("Msxml2.XMLHTTP")
 oHTTP.Open "GET", strUrl, False
 oHTTP.Send
 GetPageString = bobj.Kconv (oHTTP.responseBody,4)
End Function

これは引数にURLを与えるとそのHTMLを文字列として取得します。対象の文字コードが何であってもOKなのがミソ。

4. UTF-8のURLエンコードされたクエリ、あるいはPOSTされたデータを受ける際

これのやり方が分からない!具体的にはトラックバックpingなんかを受け取る際に困ります(さすがにShift-JISでトラックバックpingを送れ!というのはゴーマンだと思います)。私はここだけASP.NETを使って逃げました。どなたかやり方わかります?

追記。Request.BinaryReadしたやつをADODB.Streamにかけたあと&でsplitして=でsplitしてDictionaryに入れてdecodeURIComponentすればいけるかな?

ただし、ここだけASP.NETを使う際にも注意が必要です。まずweb.configの<system.web>セクションに

<globalization
requestEncoding="Shift-JIS" responseEncoding="Shift-JIS" fileEncoding="Shift-JIS"/>

というのを埋め込んで、まずレスポンスエンコーディングをShift-JISにしておきます。IISの設定でもいいですが。

続いてコーディング。Request.QueryStringやRequest.Formは使えないので、Request.InputStreamを使ってごりごり読まないと駄目じゃないかな・・・。なぜかVB.NETですがUTF-8なトラックバックpingをShift-JISなページで受けるサンプルコードを。

Dim str As System.IO.Stream
Dim counter, strLen, strRead As Integer
str = Request.InputStream
strLen = CInt(str.Length)
Dim strArr(strLen) As Byte
strRead = str.Read(strArr, 0, strLen)

Dim Forms As New Dictionary(Of String, String)

For Each item As String In Split(Encoding.UTF8.GetString(strArr),"&")
	If InStr(item, "=") Then
		Dim s As String() = Split(item, "=")
		If s.Length = 2 And Not Forms.ContainsKey(s(0)) Then
			Forms.Add(s(0), HttpUtility.HtmlEncode(HttpUtility.UrlDecode(s(1), Encoding.UTF8)).Trim().Replace(vbNullChar, ""))
		End If
	End If
Next

↑自分でも謎なコードを書いてたのでちょっとマシなのに修正。コンパイル通るかどうかわかりませんが・・・さらにゴミコードが残ってたのでバッサリ切りました。

ただし!これの問題は改行コードが消えることなんです。対処法は見つけていません(勘違いでした)。もっといい方法があったら教えてください。そもそもInputStreamを使わないでRequest.Formとか使いたいんですが、Shift-JISのところにUTF-8が来るとうまくいかないですねぇー。

というわけで長々と書きましたが、Shift-JISにこだわらなければこんなに苦労することはないです。FileSystemObjectがUTF-8を読み書きできないので私はSJISにこだわってるだけです。FSOはWSHからも使いますので・・・

元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/12/07/162931.aspx

2008/08/12

Const olFolderContacts = 10
Set Outlook = CreateObject("Outlook.Application")
Set Fs = CreateObject("Scripting.FileSystemObject")
Set ts = Fs.CreateTextFile("Address.lst")
For Each oItem In Outlook.GetNamespace("MAPI").GetDefaultFolder(olFolderContacts).Items
	If oItem.Email1Address<>"" Then
		ts.WriteLine oItem.Email1Address & vbTab & oItem.FullName
	End If
	If oItem.Email2Address<>"" Then
		ts.WriteLine oItem.Email2Address & vbTab & oItem.FullName
	End If
	If oItem.Email3Address<>"" Then
		ts.WriteLine oItem.Email3Address & vbTab & oItem.FullName
	End If
Next
ts.Close

さくっと。他のメーラーにも無論カスタマイズして使ってください。npopqのアドレス帳ほどシンプルなのはたぶんないと思いますがw(メールアドレス<タブ>名前)

元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/08/12/152820.aspx

2008/05/15

FileSystemObjectオブジェクトを利用する(2) − @IT http://www.atmarkit.co.jp/fwin2k/tutor/cformwsh17/cformwsh17_01.html 元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/05/15/137888.aspx

2008/04/20

FileSystemObjectオブジェクトを利用する(1) − @IT
http://www.atmarkit.co.jp/fwin2k/tutor/cformwsh16/cformwsh16_01.html

FSOですー

私流の切り口で説明しています
この説明展開どこかで見かけた方と思った方、するどいです
やはり私がFSOやると説明は同じになるんですね
私はこれが一番いい分類だと思っています

FSOは3回くらいに分けて解説します。

これが終わったら本連載は終了予定です。

次はー

未定w

元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/04/20/133980.aspx

2008/03/20

Vistaガジェットに「付箋」というのがありますが、その内容をテキストに書き出すスクリプトをWSHで書いてみました。(22:55 WshNetworkを使ってAddDataパスを取得していたのをShell.Application経由で取得に変更)

'sTextFolderにVistaガジェット付箋をページごとに0.txt, 1.txt...のように保存していく
sTextFolder = "D:\document\Advanced_es の文書\" 'テキストファイル保存フォルダ
Set Fs = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Shell.Application")
Const CSIDL_LOCAL_APPDATA  = &H1C
Set tsIni = Fs.OpenTextFile(Fs.BuildPath(objShell.NameSpace(CSIDL_LOCAL_APPDATA).Self.Path, _
            "\Microsoft\Windows Sidebar\Settings.ini"),,,True)
Set regEx = New RegExp
regEx.Global = True
bCNotesSection = False
Do Until tsIni.AtEndOfStream
    sLine = tsIni.ReadLine()
    If InStr(sLine,"CNotes.Gadget") Then
        bCNotesSection = True
    End If
    If bCNotesSection And InStr(sLine,"[") Then
        bCNotesSection = False
    End If
    If bCNotesSection Then
        regEx.Pattern = "(\d+)\=""(.+)"""
        If regEx.Test(sLine) Then
            For Each oMatch In regEx.Execute(sLine)
                Set oSubs = oMatch.SubMatches
                Fs.CreateTextFile(sTextFolder & oSubs(0) & ".txt").Write unescape(oSubs(1))
            Next
        End If
    End If
Loop
tsIni.Close

私はこのスクリプトをタスクスケジューラで5分間隔で動かしています。Advanced esというスマートフォンを使ってますが、これにViewTextというTodayプラグインを使うとテキストファイルがTodayに表示できるので、同期センターを使うと付箋の内容を同期できるわけです。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/03/20/128772.aspx

2008/02/21

本業もやってます。

WshNetworkオブジェクトを利用する − @IT
http://www.atmarkit.co.jp/fwin2k/tutor/cformwsh15/cformwsh15_01.html

あまり目立たないオブジェクトですのでひっそりと一回分で書き上げました。

WSH Remoteについては初心者向けの範囲を逸脱すると編集さんと私の意見が一致したので省略することになりました。なんせ動作させるのにレジストリ操作やコマンドライン操作やDCOMの設定やWindows ファイアウォールの設定などが必要になってくるので動かすまでがたいへん。うちのWikiなどをどうぞ参考になさってください。

なので、次はFileSystemObjectです。WMIやADSIは今回やらないのでいよいよ佳境ですね。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/02/21/124306.aspx

2007/11/08

.NETアプリをFramework付属のコンパイラを使ってコンパイルし、できあがった実行ファイルexeを実行するというものです。これがまた便利でw *.vbか*.csか*.jsファイルを開いた状態で、コメント行に記述したコンパイラに渡すオプション(VB.NETなら'/r:System.Windows.Forms.Dll /t:winexeという行の/r:System.Windows.Forms.Dll /t:winexeという部分)を選択すると、そのコンパイラオプションをつけてコンパイルします。デフォルトだと/t:exeが渡されます。

'*.cs, *.vb, *.jsをコンパイルして実行
Set regEX = New RegExp
regEx.Global = True
regEX.IgnoreCase = True
Set Fs = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("WScript.Shell")

sCompilerDir = "C:\windows\Microsoft.NET\Framework\v2.0.50727\"
sDefaultArguments = "/t:exe" 'winexe
sSourcePath = Document.FullName
sEXEPath = Fs.BuildPath(Fs.GetParentFolderName(sSourcePath),Fs.GetBaseName(sSourcePath) & ".exe") 
sExt = LCase(Fs.GetExtensionName(sSourcePath))

Document.Save sSourcePath 'ソース保存

Select Case sExt
	Case "vb" : sCompilerPath = sCompilerDir & "vbc.exe"
	Case "cs" : sCompilerPath = sCompilerDir & "csc.exe"
	Case "js" : sCompilerPath = sCompilerDir & "jsc.exe"
	Case Else : sCompilerPath = ""
End Select

Set sel = Document.Selection

If sel.IsEmpty Then
	sArguments = sDefaultArguments
Else
	regEx.Pattern = "\s?(\/[^\:]+\:\S+)\s?"
	If regEx.Test(sel.Text) Then
		For Each oMatch In regEx.Execute(sel.Text)
			sArguments = sArguments & oMatch.SubMatches(0) & " "
		Next
	Else
		sArguments = ""
	End If
End If

If sCompilerPath="" Then
	Alert sExt & "ファイルに対応するコンパイラがありません。"
Else
	sCommandLine = "cmd.exe /k " & sCompilerPath & " " & _
	"/out:" & """" & sEXEPath & """" & " " & sArguments & " " & _
	"""" & sSourcePath & """"
	WshShell.Run sCommandLine ,,True 'コンパイル実行
	If Fs.FileExists(sEXEPath) Then
		WshShell.Run sEXEPath,,True 'コンパイルしたファイルを実行
	Else
		Alert "コンパイルに失敗したようです。"
	End If
End If
元記事:http://blogs.wankuma.com/mutaguchi/archive/2007/11/08/106978.aspx

2007/08/20

HTA(HTML Application)とは、拡張子htaで中身はHTMLなんですけど、VBScriptとかでFileSystemObjectなどのIEなどでは動かないオブジェクトも呼べて便利なものです。見た目、Windows Formのアプリケーションのようなものが作れちゃいます。Windows標準ツールとしては「アプリケーションの追加と削除」や「サーバーの役割管理」などが実はHTAでできています。

ewさて、Web標準ページ作成エディタであるところのMicrosoft Expression Webを何気に触っているのですが、これで実はHTAの開発ができます。しかも、インテリセンスが効きます。しかも、CreateObjectしたオブジェクト変数にもインテリセンスが効くんですよー。すばらしいですねー。HTAの開発がぐっと効率的に、お安くできますよー。

Expression Webの操作方法などについては、MSMVPのwanichanのサイトが参考になると思います。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2007/08/20/91018.aspx

2007/05/24

open_shortcut_folder.vbsはショートカットをドロップするとそのショートカットがあるフォルダを開きます。
sendtoにショートカットを登録して使います。

ちなみにsendtoは「ファイル名を指定して実行」で「shell:sendto」ですぐに開けます。

Set WshShell = CreateObject("WScript.Shell")
Set Fs = CreateObject("Scripting.FileSystemObject")
For Each sArgument In WScript.Arguments
    If Fs.FileExists(sArgument) And _
    LCase(Fs.GetExtensionName(sArgument)) = "lnk" Then
        Set oShortcut=WshShell.CreateShortcut(sArgument)
        WshShell.Run "explorer.exe /select," & oShortcut.TargetPath 
    End If
Next

こういうスクリプトはPowerShellじゃ組めないですよねー。機能的にはできても、まずドロップができない、コンソールは出るし…

元記事:http://blogs.wankuma.com/mutaguchi/archive/2007/05/24/78147.aspx

古い記事のページへ |


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

Books

Twitter