控制安装向导程序的自动安装

来源:互联网 发布:淘宝网梳妆台 编辑:程序博客网 时间:2024/05/19 03:46


      怎样实现通过一个程序来控制其它程序,比如控制安装向导程序自动完成程序的安装过程而不用手动干预。我们知道对于windows图形界面程序只要获取窗体的句柄就可以向窗体发送消息,或者是获取窗体的子窗体和控件,也就获得了去整个窗体的控制权。在windows api函数中FindWindow用于获取窗体句柄,函数原型声明如下:
HWND FindWindow(
  LPCTSTR lpClassName,  // pointer to class name
  LPCTSTR lpWindowName  // pointer to window name
);
参数
lpClassName:窗体类名字符串指针。
lpWindowName:窗体的标题字符串指针。
返回值: 如果调用成功返回相应窗体的句柄,如果失败返回NULL。

同时基于MFC的应用程序对上面的函数进行了封装,作为CWnd类的一个静态函数,为了使用方便本例以基于MFC的应用为例,函数声明如下:
static CWnd* PASCAL FindWindow( LPCTSTR lpszClassName, LPCTSTR lpszWindowName );
参数含义和上面的API函数相同,此处就不在傲述。
应用程序窗体的类名以及窗体标题可以借助VC++自带的Spy++进行分析获取(使用VC的不会对此工具陌生,功能非常强大),本例以完成  jdk1.4.2.exe程序的安装为例。首先启动jdk1.4.2.exe出现安装界面的第一步,然后打开Spy++工具,会自动捕捉到正在运行的程序一切进程信息,从中找到jdk1.4.2.exe安装程序对应的项目,即可获取 Windows Caption和Class Name ,然后进一步获取子控件(比如 下一步)的指针,向子控件发送单击消息即模拟手工单击按钮的操作。具体实现代码如下:

int InstallJ2sdk()
{
   /***************************************************
        * version:
        * last modify time:
        * author:
        * 功能:安装JDK
        * 参数:无
        * 返回值:成功返回 0 ,否则返回 -1
        ***************************************************/
        int nRet = -1 ;
        int nCount = 0 ;
        CString strProsname = _T("J2SDK1.4.2.exe") ;
        CString strClassName = _T( "MsiDialogCloseClass" ) ;
        CString strWidLicense = _T("Java 2 SDK, SE v1.4.2 - License") ;
        CString strWidCustom = _T("Java 2 SDK, SE v1.4.2 - Custom Setup") ;
        CString strWidReg = _T("Java 2 SDK, SE v1.4.2 - Browser Registration") ;
        CString strWidComplete = _T("Java 2 SDK, SE v1.4.2 - Complete") ;
    CWnd   *pWndLicense , *pWndCustom , *pWndReg , *pWndComplete ;
        CButton  *pBut ;
        //!QueryProcessByName为自定义函数,用于判断指定的进程是否存在
        while( !QueryProcessByName( strProsname ) && nCount < 20  )
        {
                Sleep(1000) ;
        nCount = nCount + 1 ;
        }
        //安装向导第1步,认证许可界面
        nCount = 0 ;
        //获取认证许可界面的窗体
        pWndLicense = ( CWnd *) CWnd::FindWindow( strClassName , strWidLicense );       
        while( QueryProcessByName( strProsname ) == true  &&
                   pWndLicense == NULL &&
                   nCount < 60 )
        {
                nCount = nCount + 1 ;
                pWndLicense = ( CWnd *)CWnd::FindWindow( strClassName , strWidLicense );
                Sleep( 1000 ) ;

        }
        if( pWndLicense != NULL )
        {       //获取“同意”按钮控件的指针,可以通过Spy++工具来获取“同意”按钮的Control ID
                pBut = (CButton *)pWndLicense->GetDlgItem( 0x10d9);
                if( pBut != NULL )
                {
                    CButton  *pButAcept = (CButton *) pBut ->GetDlgItem( 0x565); //同意 按钮对应Control ID
                    pButAcept->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000) ;
                        pButAcept->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000) ;
                        pButAcept->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000) ;
                    CButton  *pButNext = (CButton *) pWndLicense->GetDlgItem( 0x5c9); //next 按钮对应Control ID         //向控件发送单击消息,为了保证成功连续发送多次。
                    pButNext->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000) ;
                        pButNext->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000) ;
                        pButNext->SendMessage(BM_CLICK, 0, 0);
                }
            else
                {
            nRet = -1 ;
                }
        }
        //安装向导第2步,安装路径设置界面
        Sleep(2000) ;
        if( !QueryProcessByName( strProsname ) )
        nRet = -1 ;
        nCount = 0 ;
        pBut = NULL ;
    pWndCustom = ( CWnd *)CWnd::FindWindow( strClassName, strWidCustom );
        while( QueryProcessByName( strProsname ) == true  &&
                   pWndCustom == NULL &&
                   nCount < 10 )
        {
        Sleep( 1000 ) ;
                nCount = nCount + 1 ;
        pWndCustom = ( CWnd *)CWnd::FindWindow( strClassName, strWidCustom );
        }
        if( pWndCustom != NULL )
        {
        CButton *pBut2 = (CButton *)pWndCustom->GetDlgItem( 0x5c9); //next 按钮对应Control ID
            if( pBut2 != NULL )
                {  
            pBut2->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000);
                        pBut2->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000);
                        pBut2->SendMessage(BM_CLICK, 0, 0);
                }
            else
                {
            nRet = -1 ;
                }
        }

    Sleep(2000) ;
        if( !QueryProcessByName( strProsname ) )
        nRet = -1 ;
        nCount = 0 ;
        pBut = NULL ;
        //安装向导第3步,注册界面
        pWndReg= ( CWnd *)CWnd::FindWindow( strClassName, strWidReg );
        while( QueryProcessByName( strProsname ) == true  &&
                   pWndReg == NULL &&
                   nCount < 10 )
        {
        Sleep( 1000 ) ;
                nCount = nCount + 1 ;
        pWndReg= ( CWnd *)CWnd::FindWindow( strClassName, strWidReg );
        }
        if( pWndReg != NULL )
        {
        pBut = (CButton *)pWndReg->GetDlgItem( 0x5c9); //next 按钮对应Control ID
                if( pBut != NULL )
                {
            pBut->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000);
                        pBut->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000);
                        pBut->SendMessage(BM_CLICK, 0, 0);
                }
            else
                {
            nRet = -1 ;
                }
        }

        Sleep(2000) ;
        if( !QueryProcessByName( strProsname ) )
        nRet = -1 ;
        nCount = 0 ;
        pBut = NULL ;
  //安装向导第4步,完成界面
    pWndComplete = ( CWnd *)CWnd::FindWindow( strClassName, strWidComplete );
        while( QueryProcessByName( strProsname ) == true  &&
                   pWndComplete == NULL &&
                   nCount < 500 )
        {
                nCount = nCount + 1 ;
        pWndComplete = ( CWnd *)CWnd::FindWindow( strClassName, strWidComplete );
        Sleep( 1000 ) ;
        }
    if( pWndComplete != NULL )
        {
                Sleep(2000) ;
        pBut = (CButton *)pWndComplete->GetDlgItem( 0x5dd); //finish 按钮对应Control ID
                if( pBut != NULL )
                {
            pBut->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000);
                        pBut->SendMessage(BM_CLICK, 0, 0);
                        Sleep(1000);
                        pBut->SendMessage(BM_CLICK, 0, 0);
                        return 0 ;
                }
            else
                {
            nRet = -1 ;
                }
        }
    return nRet ;
}

bool QueryProcessByName( CString strProsName )
{
   /***************************************************
        * version:
        * last modify time:
        * author:
        * 功能:查看strProsName指定的进程是否存在
        * 参数:strProsName 要关闭进程名子
        * 返回值:关闭成功返回 true ,否则返回 false
        ***************************************************/
        bool nRet = false ;
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hSnapshot, &pe)) {
                //显示错误信息
            LPVOID lpMsgBuf;
                FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                                                FORMAT_MESSAGE_FROM_SYSTEM |
                                                FORMAT_MESSAGE_IGNORE_INSERTS,
                                                NULL,
                                                GetLastError(),
                                                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                                                (LPTSTR) &lpMsgBuf,
                                                0,
                                                NULL );
                //AfxMessageBox( (LPCTSTR)lpMsgBuf);
                LocalFree( lpMsgBuf );
        return nRet;
    }
    while (Process32Next(hSnapshot, &pe)) {
        if ( strcmp( strProsName , pe.szExeFile) == 0  ){
            return true ;
                }
    }
        return nRet ;
}

通过类似的方法也可以对其它的程序进行控制,完成安装。

原创粉丝点击