清泛IT社区

搜索
App Inventor 2 中文社区 轻松创建Apps

扫码访问移动社区 移动社区,您的掌上技术专家

关注我,精彩不错过! 关注我,精彩不错过!

扫码安装最新版AI伴侣 最新版AI伴侣v2.69

Aia Store .aia 源码一站式解决方案 发布日志AI2连接测试ai2Starter模拟器

开通VIP送小红花App Inventor 2 拓展有奖征文 VIP会员享专有教程,免费赠送基础版*技术支持服务! AI2入门必读中文文档中文教程IoT专题

查看: 603|回复: 0
打印 上一主题 下一主题

C++代码执行安装包静默安装

  • TA的每日心情
    开心
    2024-03-14 20:36
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    70

    主题

    117

    帖子

    1365

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1365
    跳转到指定楼层
    楼主
    发表于 2015-01-07 15:22:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    本帖最后由 zqp2013 于 2015-1-8 10:19 编辑

    需求:安装包下载完成后,创建一个子进程自动安装。

    1.-----------------------CreateProcess----------------------
            PROCESS_INFORMATION pi;
            STARTUPINFO si;
            memset( &si, 0, sizeof( si ) );
            si.cb = sizeof( si );
            si.wShowWindow = SW_SHOW;
            si.dwFlags = STARTF_USESHOWWINDOW;

    //nsis安装包(http://bbs.tsingfun.com/forum-55-1.html)
            szCmdline = _T("/NCRC /S /D=\"");
            szCmdline.Append( DEFAULT_INSTALL_PATH );
            szCmdline.Append( _T("\"") );

    CreateProcess( szSetupPath, szCmdline.GetBuffer(), NULL, FALSE, NULL, NULL, NULL, szWorking, &si, &pi );
    WaitForSingleObject( m_hCreatePackage, INFINITE ); // 这种方式不太好,因为会卡前台UI线程。
    启动一秒探测的Timer,WaitForSingleObject( m_hCreatePackage, 0 ); 每次查状态,如果是WAIT_OBJECT_0,就说明完成了,然后KillTimer。
    这种方式,当权限不足时(Win7以上非管理员运行),会无限等待....
    2.---------------------CreateProcessAsUser-------------------
    HANDLE hPtoken = NULL ;
    INTER_GetExplorerToken( &hPtoken );
    CreateProcessAsUser(hPtoken, szPath, szCmdline.GetBuffer(), NULL, FALSE, NULL, NULL, NULL, szWorking, &si, &pi );
    这种方式貌似还是不能解决问题,具体原因没有深入详查,最终采用了方案3,完美解决。

    //在系统进程中查找explorer.exe,并获取其访问令牌
    DWORD WINAPI INTER_GetExplorerToken( OUT PHANDLE  phExplorerToken )
    {   
        DWORD       dwStatus = ERROR_FILE_NOT_FOUND ;
        BOOL        bRet = FALSE ;
        HANDLE      hProcess = NULL ;
        HANDLE      hProcessSnap = NULL ;
        TCHAR       szExplorerPath[MAX_PATH] = { 0 } ;
        TCHAR       FileName[MAX_PATH] = { 0 } ;
        PROCESSENTRY32 pe32 = { 0 } ;
        __try   
        {   
            GetWindowsDirectory( szExplorerPath , MAX_PATH ) ;
                    _tcscat_s( szExplorerPath , _T("\\explorer.exe") ) ;
            hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS , 0 ) ;
            if( hProcessSnap == INVALID_HANDLE_VALUE )     
            {   
                dwStatus = GetLastError() ;
                __leave ;
            }   
            pe32.dwSize = sizeof( PROCESSENTRY32 ) ;
            if( !Process32First( hProcessSnap, &pe32 ))
            {      
                dwStatus = GetLastError() ;
                __leave ;
            }

                    // 遍历系统进程,查找explorer.exe
            do {
                hProcess = OpenProcess( PROCESS_ALL_ACCESS , FALSE , pe32.th32ProcessID ) ;
                if( hProcess )           
                {
                                    DWORD size = MAX_PATH;
                                    if ( QueryFullProcessImageName(hProcess, 0, FileName, &size) )   
                    {
                        if( !_tcsicmp( FileName , szExplorerPath ))
                                            {                     
                      HANDLE  hToken ;
                            if( OpenProcessToken( hProcess, TOKEN_ALL_ACCESS, &hToken ))   
                            {                                 
                                * phExplorerToken = hToken ;
                                dwStatus = 0 ;
                            }
                            break ;
                        }
                    }

                    CloseHandle ( hProcess ) ;
                    hProcess = NULL ;
                }   

            } while( Process32Next( hProcessSnap, &pe32 )) ;
        }   
        __finally   
        {   
           if( NULL != hProcess )   
            {
              CloseHandle( hProcess ) ;
            }   
            if( NULL != hProcessSnap )   
            {   
               CloseHandle ( hProcessSnap ) ;
            }   
        }

        return dwStatus ;
    }


    3.----------------------ShellExecuteEx--------------------------

            // ------提升权限------
            // Initialize the structure.
            SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
    sei.fMask = SEE_MASK_NOCLOSEPROCESS; //不可少,否则不会等待安装结束
    (详见SHELLEXECUTEINFO定义:   HANDLE hProcess;            // out, valid when SEE_MASK_NOCLOSEPROCESS specified)
            // Ask for privileges elevation.
            sei.lpVerb = TEXT("runas");

            // Create a Command Prompt from which you will be able to start
            // other elevated applications.
            sei.lpFile = szFile;
            sei.lpParameters = szCmdline;
            sei.lpDirectory = szWorking;

            // Don't forget this parameter; otherwise, the window will be hidden.
            sei.nShow = SW_SHOWNORMAL;

            if (!ShellExecuteEx(&sei)) {
                    DWORD dwStatus = GetLastError();

                    if (dwStatus == ERROR_CANCELLED) {
                            // The user refused to allow privileges elevation.
                            UpdateMessage(_T("用户拒绝安装,安装失败。"));
                    }
                    else if (dwStatus == ERROR_FILE_NOT_FOUND) {
                            // The file defined by lpFile was not found and
                            // an error message popped up.
                            UpdateMessage(_T("安装包不存在,请检查!"));
                    }

                    CString strMsg;
                    ::GetLastErrorString(strMsg);
                    LOG_ERROR(_T("启动安装程序失败:%s"), strMsg);

                    return -1;
            }
            ...
            WaitForSingleObject( sei.hProcess, 0 );





    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    © 2024 tsingfun.com, Inc.  沪ICP备2020034476号-1  沪公网安备31011702000040号

    GMT+8, 2024-05-19 16:48 , Processed in 0.015633 second(s), 28 queries .