2009/12/03

以前、[Twitter][WSH]Twitterにポストするという記事を書いたんですが、もっと簡単にできましたので修正版。


sUser = "userid" 'ユーザーID
sPassword = "password" 'パスワード
sURL = "http://twitter.com/statuses/update.json"

Set oHTTP = WScript.CreateObject("Msxml2.XMLHTTP")
Set wshShell=CreateObject("WScript.Shell")

oHTTP.Open "POST", sURL, False, sUser, sPassword
oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oHTTP.setRequestHeader "X-Twitter-Client", "twitterPost.vbs"
oHTTP.setRequestHeader "X-Twitter-Client-Version", "1.0"
oHTTP.send "status=" & "テストです"

ポイントは、URLエンコードが実は必要なかったというところです。XMLHTTPは呼び出し元の文字コードに関わらず必ず文字列をUTF-8でURLエンコードしてポストするのでした。というわけでこれを使ってください。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2009/12/03/183500.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/07/02

Twitterに発言する最も簡単なスクリプトです。twitterPost.vbsと名前を付けて保存してください。

sUser = "*****" 'ユーザーID
sPassword = "*****" 'パスワード
sURL = "http://twitter.com/statuses/update.json"

Set oHTTP = WScript.CreateObject("Msxml2.XMLHTTP")
Set sc = CreateObject("ScriptControl")
sc.Language = "JScript"
Set js = sc.CodeObject

oHTTP.Open "POST", sURL, False, sUser, sPassword
oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oHTTP.setRequestHeader "X-Twitter-Client", "twitterPost.vbs"
oHTTP.setRequestHeader "X-Twitter-Client-Version", "1.0"
oHTTP.send "status=" & js.encodeURIComponent(WScript.Arguments(0))

使い方

twitterPost.vbs "テスト投稿"
元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/07/02/146863.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

2007/11/27

True

どっちか要らない子なんじゃ・・・違いがわからないよー

これだけではなんなのでミクシィから適当にコピペ

----------------------------------------------------------------------------------------------------
 
[powershell]new-service何のために
2007年11月26日19:04

あるのかよくわからんー
新しくサービスを登録するっていうんだけど、そういうのってインストーラーの仕事じゃ・・・
おまけにRemove-Serviceコマンドレットがないから作っても削除できないw
sc.exe delete hoge
としないといけない。
sc delete hogeだとSet-Contentのエイリアスが動いちゃうw
なんかすげー危ないコマンドレットな気がするよ。

----------------------------------------------------------------------------------------------------

VistaにはWin32_LogicalMemoryConfigurationないんだ

http://msdn2.microsoft.com/en-us/library/aa394181.aspx
Windows XP and Windows Server 2003: This class is no longer supported. Use the Win32_OperatingSystem class instead.

ほう

 

----------------------------------------------------------------------------------------------------

http://www.anchorsystems.co.jp/anchor/ashp/netmon/faq.html
ファイヤウォールが WMI 呼び出しをブロックしてしまうためです。 Windows 2003 SP1 と Windows XP では、デフォルトでファイヤウォールが ON になっています。ファイヤウォールに WMI 呼び出しを通過させるようにするには、以下のスクリプトを実行してください。
Set objFirewall = CreateObject("HNetCfg.FwMgr")
Set objPolicy = objFirewall.LocalPolicy.CurrentProfile
Set objAdminSettings = objPolicy.RemoteAdminSettings
objAdminSettings.Enabled = TRUE
これで WMI 呼び出しが許可されます。

ファイアウォール嫌いー

リモートでGet-WMIObjectするときにひつよう

----------------------------------------------------------------------------------------------------

[PowerShell]Get-Serviceしょぼすぎ
2007年11月26日00:55

Get-Serviceの戻り値が.NETのSystem.ServiceProcess.ServiceControllerなんすけど、Descriptionプロパティとかないねんな。
でもSet-ServiceでDescriptionを設定できたりする。どうやってちゃんと設定できたかを確認するかはget-wmiobject win32_serviceで調べるらしいwなんだこの中途半端な実装は。
ServiceControllerオブジェクトに対しps1xmlファイルでDescriptionやStartModeをScriptPropertyにして実装しとけよーと思った。せっかく拡張できるんだからさ。

----------------------------------------------------------------------------------------------------
Select-String使えん・・・
2007年11月25日00:10

PS C:\script> select-string "aa" *.ps1
attrib.ps1:7: # Get-Item?R?}???h???b?g??p???AAttributes?v???p?e?B??B
文字化けしとるがな
Shift-JISのファイルも検索・表示できないとはかなり終わってますね
せめて文字コードを指定できるようにしてくれー

UTF8はいけます
 
.NET Frameworkには文字コード判別のクラスとかないのかな・・・
前探してなかった気もする
文字コードを判別する: .NET Tips: C#, VB.NET, Visual Studio
http://dobon.net/vb/dotnet/string/detectcode.html
こういうごり押しが必要なのねー

----------------------------------------------------------------------------------------------------

あと&{スクリプトブロック} は、C#の{}空ブロックと同じことができるらしいー

要するに変数がその中でのみ使われてスコープ抜けたら破棄されるという

これを応用すればtrap文でtry catchみたいなこともできるらしいー

詳しくはPowerShellインアクションを買おう!w

元記事:http://blogs.wankuma.com/mutaguchi/archive/2007/11/27/110583.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

2007/01/15

スクリプト センターの新着記事にこんなのが。

VBScript からも .NET Framework のクラスを利用できる?!
NET Framework のクラスは VBScript からアクセスできないと皆さん思っていませんか? 後悔する前にこの記事を読みましょう!

System.Collections.ArrayListなんかを普通にCreateObjectして使えるんですねー。

しらんかったー!すげー!

たしかにProgIDがレジストリに登録されてるから、使えるような気はしてましたが、まさか本当に使えるとは。

これってどういう仕組みなんだろう?どのクラスが使えてどのクラスがだめかは筆者も調査中とのことですが、相当いろんなことができるんじゃないでしょうか。

少なくともCOMコンポーネントにはコンストラクタがない(ですよね?)のでコンストラクタが必須のクラスは駄目でしょうね。

まだまだWSHいけるんじゃないですか?PowerShellもいいですけどWSHも使いましょう。

元記事:http://blogs.wankuma.com/mutaguchi/archive/2007/01/15/56349.aspx

古い記事のページへ |


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

Twitter

Books