zoukankan      html  css  js  c++  java
  • FileZilla命令行实现文件上传以及CreateProcess实现静默调用

    应用需求:

            用户在选择渲染作业时面临两种情况:一是选择用户远程存储上的文件;二是选择本地文件系统中的文件进行渲染。由于渲染任务是在远程主机上进行的,实际进行渲染时源文件也是在ftp目录中获取的,因此当用户选择本地文件系统中的文件时,文件必须上传到ftp上的指定目录中,远程主机才能正确获取到文件的路径,下载后进行文件渲染,然后将渲染结果保存在ftp的指定路径下。因此,需求就是当用户选择本地文件系统中的文件时,文件要自动上传到ftp的目录中,供渲染程序调用执行。

    解决方案分析:

            原有Qftp的操作中存在文件上传的操作,但是利用qftp中的方式,上传文件不稳定,而且如果文件较大,很容易发生错误,因此才想着使用外部的Ftp工具实现文件的上传。

            到这里我们已经明确,要实现上述目标需要解决以下两个问题:1)FileZilla上传文件的命令行形式。2)如何实现FileZilla静默上传,即不弹出窗口。

            1)FileZilla上传文件的命令行形式。在解决这个问题的时候,费了一点时间。Google之后的确有使用命令行上传文件的相关信息,但是我在cmd下调用FileZilla.exe查看相关帮助,一直说命令不存在。经过一番周折看到一篇帖子,说命令的支持与FileZilla的版本有关,较高版本的FileZilla不支持文件上传的命令行形式。因此,又下载了较低版本的FileZilla,这里我使用的是2.2.17版本。使用方式如下:

            OK,第一个问题解决,但它还不太完美,因为到调用的时候总是弹出窗口,虽然在上述命令的最后加上"-close",在文件上传结束后,窗口会自动关闭,但这会严重影响用户的使用体验,那么就集中解决这个问题吧。

            2)如何实现FileZilla静默上传,即不弹出窗口

            刚开始解决这个问题时,一直在找它的命令行中是否相关参数能够实现静默上传,但是很遗憾,没有找到。甚至还想到了修改FileZilla的源码,反正它也是开源的。但是后来一想,调用它要采用CreateProcess创建一个新的进程的方式,以前有些印象通过CreateProcess设置某些参数可以不显示子进程的窗口。通过查阅相关资料,bingo,方案可行。相关代码如下:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void LHGoldenfarmClientPrivate::StartProcessDownloadFiles(const QStringList downloadFiles)  
    2. {  
    3.     int file_count = downloadFiles.size();  
    4.     HANDLE *file_handles = (HANDLE *)malloc(file_count*sizeof(HANDLE)) ;  
    5.     for(int i = 0 ; i < downloadFiles.size() ; i++)  
    6.     {  
    7.         QFileInfo files(downloadFiles.at(i));  
    8.   
    9.         if(files.exists()){  
    10.   
    11.             STARTUPINFO si = {sizeof(si)};  
    12.             PROCESS_INFORMATION pi ;  
    13.   
    14.             si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;  
    15.             si.wShowWindow = SW_HIDE;  
    16.   
    17.             QString ftpHost ;  
    18.             QString ftpUser ;  
    19.             QString ftpPass ;  
    20.             LHGoldenfarmClientPrivate::Mgr->GetFtpCredentials(ftpHost , ftpUser , ftpPass);  
    21.             QString filepath = files.absoluteFilePath().replace("/","\");  
    22.             QString filename = files.fileName();  
    23.             QString filesuffix = files.suffix();  
    24.             QString destdir = QString("scene_Files") ;  
    25.   
    26.             QString s_cmdline = QString("FileZilla//filezilla.exe -r -u %1 ftp://%2:%3@%4/%5 -t %6 -close").arg(filepath.toLatin1().data()  
    27.           ).arg(ftpUser.toLatin1().data()).arg(ftpPass.toLatin1().data()).arg(ftpHost.toLatin1().data()).arg(  
    28.                                             destdir.toLatin1().data()).arg(filename.toLatin1().data());  
    29.               
    30.             qDebug() << s_cmdline.toLatin1().data();  
    31.   
    32.             //! 完成多字节到宽字节的转换  
    33.             WCHAR *w_cmdline = ConvertFromCharToWchar(s_cmdline.toLatin1().data());  
    34.   
    35.             BOOL bRet = ::CreateProcess(  
    36.                           NULL ,  
    37.                           w_cmdline ,  
    38.                           NULL,  
    39.                           NULL,  
    40.                           FALSE,  
    41.                           CREATE_NO_WINDOW,  
    42.                           NULL,  
    43.                           NULL,  
    44.                           &si,  
    45.                           &pi  
    46.                         );  
    47.   
    48.             if(bRet){  
    49.                 file_handles[i] = pi.hThread;  
    50.             }  
    51.   
    52.         }  
    53.     }  
    54.   
    55.     WaitForMultipleObjects(file_count , file_handles , TRUE , 3 * 60 *1000);  
    56.   
    57.   
    58. }  
             这里主要要同时设置:si.wShowWindow = SW_HIDE以及CreateProcess中的CRATE_NO_WINDOW参数才可以。好了,运行一下,嗯,不过,文件正确上传;再运行一下,怎么会弹出窗口?原来是文件已经存在了,在这种情况下,会弹出窗口询问你如何操作,这里采用-r的命令行可以设置默认直接覆盖,话说这个参数还是自己猜出来的,我是有多么伟大。

    总结:

             这篇文章大部分为技术性的,而非思路上的拓展。但是这里要提的一点是,在解决第二个问题的时候,花的时间不太久,但是已近超过了我的预期。而且想起这个方法来,也是不经意间就想起来了。因为以前用过这种方式,不知道为嘛第一时间没有想起这个方法来,看来还是知识掌握的不够牢固,缺乏灵活运用。不过倒也符合我现在看书对自己的要求,不要试图记一些东西,只要能在脑子里留一点点印象就足够了,将来碰到问题的时候,能有印象知道应该向哪个方向查找,或许这就是我说的思路。

            珍惜时间。时间这么紧张,真心不想大把大把的把时间浪费在无用的事情上,因为------我是有野心的。

  • 相关阅读:
    CPP--关于long的争议和思考
    CPP--借助神器VS理解内存存储(含大小端对齐)
    1.QT开发第一个程序
    POJ-1456 Supermarket 贪心问题 有时间限制的最小化惩罚问题
    HDU-4310 Hero 贪心问题
    HDU-1789 Doing Homework again 贪心问题 有时间限制的最小化惩罚问题
    HDU-2303 The Embarrassed Cryptographer 高精度算法(大数取模)
    【错题本】刷算法题中出现的一些错误和小技巧
    HDU-2050 折线分割平面 找规律&递推
    记intel杯比赛中各种bug与debug【其五】:朴素贝叶斯分类器的实现和针对性的优化
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/4061650.html
Copyright © 2011-2022 走看看