バージョン管理機能
バージョン管理機能をVisualStudioで使いたいと考えた。
導入が簡単で、条件によっては無料で使える、
http://www.visualsvn.com/
無料だが、導入はわずかに面倒な、
AnkhSVN
少し使ってみたが、長く使ってみないとその利点は判らないようだ。
PowerShellからWatiNを利用
ポイント
- WatiN.Core.dllは、Add-Type -Path で読み込む。
- WatiN.Core.Findクラスの利用は、
[Watin.Core.Find]::ByName("fmInput2") [Watin.Core.Find]::ByIndex(1)
のように行う。
PowerShell用コード
# Set WatiN.Core.dll Add-Type -Path "C:\Users\mikihiro\Documents\Visual Studio 2010\Projects\WatiNStudy\WatiNStudy\bin\Debug\WatiN.Core.dll" # new InternetExplorer $ie = New-Object WatiN.Core.IE $ie.GoTo("http://www.moderns.co.jp/trade/devtest/index.html") $elem = [Watin.Core.Find]::By("name","fmInput1") $ie.TextField($elem).value = "test1" $ie.TextField([Watin.Core.Find]::ByName("fmInput2")).value = "test2" $ie.CheckBox([Watin.Core.Find]::ByName("CB3")).Checked = $true # CheckBoxのValueが"C"なのは複数あるが、そのうち最初のCheckBoxがチェックされる。 $ie.CheckBox([Watin.Core.Find]::ByValue("C")).Checked = $true # Group3の2番目。.Andで繋げることができる。 $ie.RadioButton([Watin.Core.Find]::ByName("Group3").And([Watin.Core.Find]::ByIndex(1))).Checked = $true $sel = $ie.SelectList([Watin.Core.Find]::By("name","DropDown")) #$sel.Exists #$sel | Get-Member -Type Method #$sel.Option([Watin.Core.Find]::ByValue("2")).Select() $sel.Option([Watin.Core.Find]::ByText("選択肢2")).Select() # 「開発用フォーム入力画面」がInnerTextに含まれているので、Trueがコンソールに表示される。 $ie.ContainsText("開発用フォーム入力画面") # 最初の送信ボタンをクリック。 #$ie.Button([Watin.Core.Find]::ByValue("送信")).Click() # 2番目の送信ボタンをクリック。 #$buttons = $ie.Buttons.Filter([Watin.Core.Find]::ByValue("送信")) #$buttons.Item(1).Click()
環境
- Windows 7(64bit)
- PowerShell 2.0
WatiNを利用してIEを操作するPowerShell用スクリプトを、.Netのプログラム上で読み込んで実行する。
- System.Management.Automation.dll
- WatiN.Core.dll
を参照に追加する。
VB.Netのコード
Form1にButtonを配置しておく。
Imports System.Management.Automation Imports System.Management.Automation.Runspaces Public Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Dim runspaceConfiguration__1 As RunspaceConfiguration = RunspaceConfiguration.Create() Dim runspace As Runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration__1) runspace.ApartmentState = System.Threading.ApartmentState.STA runspace.ThreadOptions = PSThreadOptions.UseCurrentThread runspace.Open() Dim invoker As New RunspaceInvoke() invoker.Invoke("Set-ExecutionPolicy Unrestricted") Dim pipeline As Pipeline = runspace.CreatePipeline() Dim myCmd As New Command("C:\Users\mikihiro\Desktop\201205\Watin.ps1") 'Dim param As New CommandParameter("responseCollection", test) 'myCmd.Parameters.Add(param) pipeline.Commands.Add(myCmd) ' Execute PowerShell script Dim results As ObjectModel.Collection(Of PSObject) = pipeline.Invoke() End Sub End Class
Watin.ps1
[System.Reflection.Assembly]::LoadFile("C:\Users\mikihiro\Documents\Visual Studio 2010\Projects\WatiN-2.1.0.1196\source\src\WindowsApplication1\bin\Release\WatiN.Core.dll") $ie = New-Object WatiN.Core.IE $ie.GoTo("http://www.moderns.co.jp/trade/")
ファイルパスは設定し直して下さい。
環境
- Windows 7(64bit)
- PowerShell 2.0
- Visual Studio 2010 Professional
http://stackoverflow.com/questions/8336800/c-sharp-passing-an-array-to-a-powershell-script
バックテストでがっかり
2、3日かけてプログラムを作成して行ったバックテストの結果が(想定していたけど)あんまり良くなかったがっかり感。ひょっとしたら、結構良い成績になるんじゃないか、と思ったけど、やはり駄目だった。
まあ、これで一つ調べるべき事をつぶせたので、前進したと考えよう。
IE9をType.InvokeMemberで操作
IE9では、Type.InvokeMemberを利用して、IEを操作することになるのだけど、情報が少ない。
従って、実験を繰り返して調べることになる。
ここでは、その研究結果のコードを掲載しておきます。もっと洗練された方法があるはずだけれど、とりあえず動くものを作るのが必要なので、野暮ったいのは勘弁して下さい。
IE8までは、もっと簡単なコードで充分だったのに、IE9では厳密に指定しないと駄目。
Visual Studio 2010 / VB.net用
http://www.moderns.co.jp/files/UsingIE9Object.zip
Imports System.Reflection Public Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 'BindingFlags.GetProperty などを短く置き変えることが出来る。 'Dim getPr As BindingFlags = BindingFlags.GetProperty 'Dim setPr As BindingFlags = BindingFlags.SetProperty 'Dim invMe As BindingFlags = BindingFlags.InvokeMethod Dim ieObj As Object ieObj = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る If ieObj Is Nothing Then MsgBox("IE Nothing") End If ieObj.Visible = True '見えるようにする Dim uri As String = My.Computer.FileSystem.CombinePath(My.Application.Info.DirectoryPath, "IE9.html") 'uri = "http://www.moderns.co.jp/" Try ieObj.Navigate2(uri) Catch MsgBox("file not found:" & vbCrLf & uri) Exit Sub End Try Call ieWait(ieObj) Dim ieDoc As Object Dim typ As Type typ = Type.GetTypeFromProgID("mhtmlfile") 'あるいは、こちらでもOK。 'typ = Type.GetTypeFromCLSID(New System.Guid("{3050F4E7-98B5-11CF-BB82-00AA00BDCE0B}")) 'ieDoc = ieObj.Document 'IE8までは、こうした文法で良かった。IE9では、以下のようにするのが良い。 ieDoc = typ.InvokeMember("document", BindingFlags.GetProperty, Nothing, ieObj, Nothing) 'Title TextBox1.Text &= "title: " & typ.InvokeMember("title", BindingFlags.GetProperty, Nothing, ieDoc, Nothing) & vbCrLf 'URLは大文字 TextBox1.Text &= "URL: " & typ.InvokeMember("URL", BindingFlags.GetProperty, Nothing, ieDoc, Nothing) & vbCrLf 'Linkの数 TextBox1.Text &= "Link count : " & typ.InvokeMember("links", BindingFlags.GetProperty, Nothing, ieDoc, Nothing).length & vbCrLf 'TextBox1.Text &= "URL: " & GetP("URL", ieDoc) & vbCrLf 'TextBox1.Text &= "Link count : " & GetP("links", ieDoc).length & vbCrLf 'Typeを表示 mshtml.HTMLAnchorElementClass となる。 TextBox1.Text &= typ.InvokeMember("links", BindingFlags.GetProperty, Nothing, ieDoc, Nothing)(1).ToString & vbCrLf '2番目のリンクのInnerText TextBox1.Text &= "Second Link InnterText : " & typ.InvokeMember("innerText", BindingFlags.GetProperty, Nothing, typ.InvokeMember("links", BindingFlags.GetProperty, Nothing, ieDoc, Nothing)(1), Nothing) & vbCrLf '2番目のリンクをクリックする。 'Dim links As Object = typ.InvokeMember("links", BindingFlags.GetProperty, Nothing, ieDoc, Nothing) 'link 全部のObject 'typ.InvokeMember("click", BindingFlags.InvokeMethod, Nothing, links(1), Nothing) 'links(1)は、2番目のlinkを意味する。 'あるいは、こちらでも同じ。 'Dim link2 As Object = typ.InvokeMember("links", BindingFlags.GetProperty, Nothing, ieDoc, Nothing)(1) '2番目のlinkのObject (0)1番目 (1)2番目 (2)3番目 ・・・ 'typ.InvokeMember("click", BindingFlags.InvokeMethod, Nothing, link2, Nothing) 'Call ieWait(ieObj) TextBox1.Text &= vbCrLf 'Body Elementを確定する2種類の方法 '1 how to get the body object Dim htmlBody As Object htmlBody = typ.InvokeMember("body", BindingFlags.GetProperty, Nothing, ieDoc, Nothing) 'htmlBody = GetP("body", ieDoc) TextBox1.Text &= "body innerHTML : " & typ.InvokeMember("innerHTML", BindingFlags.GetProperty, Nothing, htmlBody, Nothing) & vbCrLf & vbCrLf '2 how to get the body object Dim htmlBody2 As Object htmlBody2 = typ.InvokeMember("getElementsByTagName", BindingFlags.InvokeMethod, Nothing, ieDoc, {"body"})(0) 'htmlBody2 = InvokeM("getElementsByTagName", ieDoc, {"body"})(0) TextBox1.Text &= "body innerHTML : " & typ.InvokeMember("innerHTML", BindingFlags.GetProperty, Nothing, htmlBody2, Nothing) & vbCrLf & vbCrLf 'Form Element Dim formElm As Object = typ.InvokeMember("getElementsByName", BindingFlags.InvokeMethod, Nothing, ieDoc, {"formName1"}) Dim inputElm As Object = typ.InvokeMember("getElementsByTagName", BindingFlags.InvokeMethod, Nothing, formElm(0), {"input"}) 'InputBox inputElmを利用 For i As Integer = 0 To inputElm.length - 1 TextBox1.Text &= typ.InvokeMember("name", BindingFlags.GetProperty, Nothing, inputElm(i), Nothing) & vbCrLf If typ.InvokeMember("name", BindingFlags.GetProperty, Nothing, inputElm(i), Nothing) = "siteurl" Then typ.InvokeMember("value", BindingFlags.SetProperty, Nothing, inputElm(i), {"input value"}) End If Next 'CheckBox inputElmを利用 For i As Integer = 0 To inputElm.length - 1 TextBox1.Text &= typ.InvokeMember("name", BindingFlags.GetProperty, Nothing, inputElm(i), Nothing) & vbCrLf If typ.InvokeMember("name", BindingFlags.GetProperty, Nothing, inputElm(i), Nothing) = "c1" Then typ.InvokeMember("checked", BindingFlags.SetProperty, Nothing, inputElm(i), {"True"}) End If Next 'RadioButton inputElmを利用 For i As Integer = 0 To inputElm.length - 1 TextBox1.Text &= typ.InvokeMember("name", BindingFlags.GetProperty, Nothing, inputElm(i), Nothing) & vbCrLf If typ.InvokeMember("name", BindingFlags.GetProperty, Nothing, inputElm(i), Nothing) = "r1" Then typ.InvokeMember("checked", BindingFlags.SetProperty, Nothing, inputElm(i), {"True"}) End If Next 'Select and Option Dim selectElm As Object = typ.InvokeMember("getElementsByName", BindingFlags.InvokeMethod, Nothing, ieDoc, {"sele1"})(0) Dim optionsElm As Object = typ.InvokeMember("getElementsByTagName", BindingFlags.InvokeMethod, Nothing, selectElm, {"option"}) For i As Integer = 0 To optionsElm.length - 1 TextBox1.Text &= typ.InvokeMember("innerText", BindingFlags.GetProperty, Nothing, optionsElm(i), Nothing) & vbCrLf If typ.InvokeMember("innerText", BindingFlags.GetProperty, Nothing, optionsElm(i), Nothing) = "def" Then typ.InvokeMember("selected", BindingFlags.SetProperty, Nothing, optionsElm(i), {"True"}) End If Next 'TextArea Dim textAElem As Object textAElem = typ.InvokeMember("getElementsByName", BindingFlags.InvokeMethod, Nothing, ieDoc, {"te1"}) 'textAElem = InvokeM("getElementsByName", ieDoc, {"te1"}) typ.InvokeMember("value", BindingFlags.SetProperty, Nothing, textAElem(0), {"textarea value"}) 'Call SetP("value", textAElem(0), {"textarea value"}) 'Form InnerHTML TextBox1.Text &= vbCrLf & "Form innerHTML : " & GetP("innerHTML", InvokeM("getElementsByName", ieDoc, {"formName1"})(0)) & vbCrLf End Sub ''' <summary> ''' IEの表示が完了するまで待つ ''' </summary> ''' <param name="ieObj"></param> ''' <remarks></remarks> Sub ieWait(ByRef ieObj As Object) Try Dim sw As New Stopwatch sw.Start() Do While (ieObj.Busy OrElse ieObj.ReadyState <> SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE) _ AndAlso sw.Elapsed <= New TimeSpan(0, 0, 0, 20) '読み込み中でも、CheckWatingSecond(20秒)を超えたら抜ける Application.DoEvents() '読み込み中なら待つ Loop sw = Stopwatch.StartNew() Do While sw.Elapsed <= New TimeSpan(0, 0, 0, 0, 1000) '念のため読み込みが終わってもさらに1秒待つ Application.DoEvents() Loop sw.Reset() Catch ex As Exception 'IEが閉じられていた場合などエラーになるので、それをキャッチする。 MsgBox("Error") End Try End Sub ''' <summary> ''' InvokeMemberの、GetPropertyを実行 ''' </summary> ''' <param name="name1"></param> ''' <param name="target1"></param> ''' <param name="args1"></param> ''' <returns></returns> ''' <remarks></remarks> Function GetP(ByVal name1 As String, ByVal target1 As Object, Optional ByVal args1 As Object = Nothing) Dim typ As Type = Type.GetTypeFromProgID("mhtmlfile") Return typ.InvokeMember(name1, BindingFlags.GetProperty, Nothing, target1, args1) End Function ''' <summary> ''' InvokeMemberの、SetPropertyを実行 ''' </summary> ''' <param name="name1"></param> ''' <param name="target1"></param> ''' <param name="args1"></param> ''' <returns></returns> ''' <remarks></remarks> Function SetP(ByVal name1 As String, ByVal target1 As Object, Optional ByVal args1 As Object = Nothing) Dim typ As Type = Type.GetTypeFromProgID("mhtmlfile") Return typ.InvokeMember(name1, BindingFlags.SetProperty, Nothing, target1, args1) End Function ''' <summary> ''' InvokeMemberの、InvokeMethodを実行 ''' </summary> ''' <param name="name1"></param> ''' <param name="target1"></param> ''' <param name="args1"></param> ''' <returns></returns> ''' <remarks></remarks> Function InvokeM(ByVal name1 As String, ByVal target1 As Object, Optional ByVal args1 As Object = Nothing) Dim typ As Type = Type.GetTypeFromProgID("mhtmlfile") Return typ.InvokeMember(name1, BindingFlags.InvokeMethod, Nothing, target1, args1) End Function End Class
対象のHTML IE9.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <title>IE9 Object</title> </head> <body> <p><a href="http://www.moderns.co.jp/">modern design laboratory</a></p> <p><a href="http://www.msignal.info/">M.Signal</a></p> <p><a href="http://www.linkget.info/">LinkGet</a></p> <form action="form1.html" name ="formName1" method="get"> <input type="text" name="siteurl" size="20" /> <input type="checkbox" name="c1" value=""> <input type="checkbox" name="c2" value=""> <input type="radio" name="r1" value="b1"> <input type="radio" name="r1" value="b2"> <input type="radio" name="r1" value="b3"> <select name="sele1" size="1" tabindex="0"> <option value="">abc</option> <option value="">def</option> <option value="">ghi</option> </select> <textarea name="te1" rows="2" cols="20" tabindex="0"></textarea> </form> </body> </html>