使用Visual Basic SSIS脚本任务和UIAutomation

时间:2018-04-13 15:27:13

标签: vb.net visual-studio-2012 ssis ui-automation ie-automation

我在Visual Studio的SSIS中使用Visual Basic脚本任务来自动从https://www.fincen.gov/msb-registrant-search下载excel文件。

导航到网站并点击蓝色的“查看/下载”链接时,我没有任何问题。

我遇到的问题是黄色的“框架通知栏”出现时我需要以编程方式点击“保存”。 (我不想使用SendKeys方法。)

我正在使用UIAutomation参考来完成此任务。

除了使用UIAutomation关于如何下载此文件之外,我还对其他建议持开放态度 - 该解决方案必须能够用作SSIS包的一部分。

我已经在Excel VBA中编写了这段代码并且运行正常,但是我在将代码转换为VB时遇到了问题。

成功点击下载链接后,以下是我运行以执行以下操作的代码:

  1. 找到通知栏hWnd
  2. 阅读通知栏中的文字 确定确切的文件名,因为它每次都会改变(我会工作 下载后的文件)
  3. 点击保存按钮
  4. 检查通知栏中的文本以确定何时 下载已经完成。
  5. *我可以提供有效的Excel VBA代码。

    #Region "Imports"
    Imports System.Threading.Thread
    Imports UIAutomationClient
    Imports UIAutomationClient.UIA_PropertyIds
    Imports UIAutomationClient.UIA_PatternIds
    #End Region
    
    
    <Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute()> _
    <System.CLSCompliantAttribute(False)> _
    Partial Public Class ScriptMain
    Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    
    Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr
    
    Public CUIAuto As IUIAutomation
    Public WindowHandleElement As IUIAutomationElement
    Public windowHandle As Long
    Public tCnd As IUIAutomationCondition
    Public bCnd As IUIAutomationCondition
    Public tCtl As IUIAutomationElement
    Public bCtl As IUIAutomationElement
    Public dlStatus As String
    Public InvokePattern As IUIAutomationInvokePattern
    
    Public Sub Main()
    
    getReport()
    
    
    GC.Collect()
    GC.WaitForPendingFinalizers()
    Dts.TaskResult = ScriptResults.Success
    End Sub
    
    
    
    Public Sub getReport()
    Dim IE As InternetExplorerMedium
    Dim iePage As mshtml.HTMLDocument
    Dim msbExport As IHTMLElement
    
    
    IE = New InternetExplorerMedium
    
    IE.Visible = True
    IE.Navigate("https://www.fincen.gov/fcn/financial_institutions/msb/msbstateselector.html#")
    
    Do : Sleep(1000) : Loop Until IE.ReadyState = tagREADYSTATE.READYSTATE_COMPLETE And IE.Busy = False
    
    
    iePage = CType(IE.Document, mshtml.HTMLDocument)
    msbExport = iePage.getElementById("ExportExcelLink")
    msbExport.click()
    
    Do
    
    windowHandle = IE.HWND
    windowHandle = CLng(FindWindowEx(windowHandle, 0, "Frame Notification Bar", vbNullString))
    Sleep(1000)
    Loop Until windowHandle > 0
    
    
    
    CUIAuto = New CUIAutomation
    WindowHandleElement = CUIAuto.ElementFromHandle(CType(windowHandle, IntPtr))
    
    tCnd = CUIAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_ControlTypeIds.UIA_TextControlTypeId)
    tCtl = WindowHandleElement.FindFirst(TreeScope.TreeScope_Subtree, tCnd)
    dlStatus = CType(tCtl.GetCurrentPropertyValue(UIA_ValueValuePropertyId), String) 'get download status
    
    bCnd = CUIAuto.CreatePropertyCondition(UIA_NamePropertyId, "Save")
    bCtl = WindowHandleElement.FindFirst(TreeScope.TreeScope_Subtree, bCnd) ' The error seems to be happening here, there is no object after running this line
    InvokePattern = CType(bCtl.GetCurrentPattern(UIA_InvokePatternId), IUIAutomationInvokePattern)
    InvokePattern.Invoke()
    
    
    End Sub
    
    
    
    #Region "ScriptResults declaration"
    'This enum provides a convenient shorthand within the scope of this class for setting the
    'result of the script.
    
    'This code was generated automatically.
    Enum ScriptResults
    Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
    Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
    End Enum
    
    #End Region
    
    End Class
    

    参考文献:

    enter image description here

1 个答案:

答案 0 :(得分:0)

我能够弄清楚这一点。这是整个工作代码。

#Region "Imports"
Imports System.Threading.Thread
Imports UIAutomationClient
Imports UIAutomationClient.UIA_PropertyIds
Imports UIAutomationClient.UIA_PatternIds
'Imports UIAutomationClient.IUIAutomationElement
#End Region


<Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute()> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
    Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase

Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr

Public CUIAuto As IUIAutomation
Public WindowHandleElement As IUIAutomationElement
Public windowHandle As Long
Public tCnd As IUIAutomationCondition
Public bCnd As IUIAutomationCondition
Public tCtl As IUIAutomationElement
Public bCtl As IUIAutomationElement
Public dlStatus As String
Public fileName As String
Public InvokePattern As IUIAutomationInvokePattern

Public Sub Main()


    getReport()
    'deleteRows()


    GC.Collect()
    GC.WaitForPendingFinalizers()
    Dts.TaskResult = ScriptResults.Success
End Sub

Sub deleteExistingExtract()
    On Error Resume Next
    Dim StrFile As String
    Dim fPath As String

    fPath = "C:\Users\" & Environ("username") & "\downloads\152*"

    StrFile = Dir(fPath)
    Do While Len(StrFile) > 0

        Kill(fPath)
        StrFile = Dir()
    Loop

End Sub

Public Sub getReport()
    Dim IE As InternetExplorerMedium
    Dim iePage As mshtml.HTMLDocument
    Dim msbExport As IHTMLElement


    IE = New InternetExplorerMedium

    IE.Visible = True
    IE.Navigate("https://www.fincen.gov/fcn/financial_institutions/msb/msbstateselector.html#")
    'On Error Resume Next
    Do : Sleep(1000) : Loop Until IE.ReadyState = tagREADYSTATE.READYSTATE_COMPLETE And IE.Busy = False


    iePage = CType(IE.Document, mshtml.HTMLDocument)
    msbExport = iePage.getElementById("ExportExcelLink")
    msbExport.click()

    Do
        'On Error Resume Next
        windowHandle = IE.HWND
        windowHandle = CLng(FindWindowEx(windowHandle, 0, "Frame Notification Bar", vbNullString))
        Sleep(1000)
    Loop Until windowHandle > 0



    CUIAuto = New CUIAutomation
    WindowHandleElement = CUIAuto.ElementFromHandle(CType(windowHandle, IntPtr))

    tCnd = CUIAuto.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_ControlTypeIds.UIA_TextControlTypeId)
    tCtl = WindowHandleElement.FindFirst(TreeScope.TreeScope_Subtree, tCnd)
    dlStatus = CType(tCtl.GetCurrentPropertyValue(UIA_ValueValuePropertyId), String)
    fileName = Mid(dlStatus, InStr(dlStatus, "1"), 14)
    bCnd = CUIAuto.CreatePropertyCondition(UIA_NamePropertyId, "Save")
    bCtl = WindowHandleElement.FindFirst(TreeScope.TreeScope_Subtree, bCnd)
    InvokePattern = CType(bCtl.GetCurrentPattern(UIA_InvokePatternId), IUIAutomationInvokePattern)
    InvokePattern.Invoke()


    Do
        dlStatus = CType(tCtl.GetCurrentPropertyValue(UIA_ValueValuePropertyId), String)
        Sleep(1000)
    Loop Until Right(Trim(dlStatus), 10) = "completed."

    IE.Quit()

End Sub

#Region "ScriptResults declaration"
    'This enum provides a convenient shorthand within the scope of this class for setting the
    'result of the script.

    'This code was generated automatically.
    Enum ScriptResults
        Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
        Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
    End Enum

#End Region

End Class