经过试验,qt启动一个新的进程时,这个进程的工作目录是继承父进程的,无论是通过start还是startDetached来启动。

其实对于linux系统,qt底层应该也是调用fork、exec之类的函数,对于fork,参看apue中文版第三版,有以下解析:

在f o r k之后处理文件描述符有两种常见的情况:
(1) 父进程等待子进程完成。在这种情况下,父进程无需对其描述符做任何处理。当子进
程终止后,它曾进行过读、写操作的任一共享描述符的文件位移量已做了相应更新。
(2) 父、子进程各自执行不同的程序段。在这种情况下,在 f o r k之后,父、子进程各自关闭
它们不需使用的文件描述符,并且不干扰对方使用的文件描述符。这种方法是网络服务进程中
经常使用的。
除了打开文件之外,很多父进程的其他性质也由子进程继承:
• 实际用户I D、实际组I D、有效用户I D、有效组I D。
• 添加组I D。
• 进程组I D。
• 对话期I D。
• 控制终端。
• 设置-用户- I D标志和设置-组- I D标志。
• 当前工作目录。
• 根目录。
• 文件方式创建屏蔽字。
• 信号屏蔽和排列。
• 对任一打开文件描述符的在执行时关闭标志。
• 环境。
• 连接的共享存储段。
• 资源限制。
父、子进程之间的区别是:
• fork的返回值。
• 进程I D。
• 不同的父进程I D。
• 子进程的t m s _ u t i m e , t m s _ s t i m e , t m s _ c u t i m e以及t m s _ u s t i m e设置为0。
• 父进程设置的锁,子进程不继承。
• 子进程的未决告警被清除。
• 子进程的未决信号集设置为空集。

由以上分析知,工作目录确实是被子进程继承的。个人理解qt的setWorkingDirectory相当于:fork后的chdir,而qt新进程的start或者startDetached相当于exec族的某一个。

再来谈回qt,在没有设置子进程的工作目录的情况下,假如新的进程代码里面使用了相对路径,那么这个相对路径相对的是父进程的工作目录,而不是传递给start还是startDetached的第一个参数里面的路径。那么问题来了,如果新的进程是要使用相对路径来读写配置文件的情况下,这个配置文件的读写将会在父进程的工作目录进行,这无疑是会有很大问题的。

针对以上问题,个人进行了以下试验并总结。

//两种办法都可以获取当前进程的路径
    QString path = QApplication::applicationFilePath();
    int index = path.lastIndexOf("/");
    path = path.mid(0, index);
    qDebug() << "applicationFilePath" << path;
    QDir dir;
    path=dir.currentPath();
    //qDebug() << "current path" << path;

//构造新进程
    QProcess *updateProcess = new QProcess(this);

//指定工作目录
    QString workingDir = "/home/mohanhui/work/tmp/test/qt5.3.2-64/softwareCenter/"
            "build-softwareCenter-Desktop_Qt_5_3_GCC_64bit-Debug" ;

//指定可执行程序的路径
    QString program = workingDir +"/softwareCenterTest";

/*1.setCurrent
     * 由子进程继承
     * 现象:由子进程继承了这个工作目录,子进程使用“./”即相当于这个setCurrent指定的目录,
     * 子进程读写文件使用"./"时,都在这个setCurrent指定的目录里面生效。
     * 但是子进程打印workingDirectory结果却是“”空的,不知道会不会有其他问题。
     */
#if 0
    //更改父进程的工作目录
    QDir::setCurrent(workingDir);
    //启动新进程
    updateProcess->startDetached(program);
    qDebug() <<"新的工作目录" << updateProcess->workingDirectory();
    return;
#endif
    
    /* 2.什么都不干
     * 现象:子进程打印workingDirectory是“”空的。子进程继承了父进程的工作目录,
     * 子进程使用“./”即相当于这个在父进程指定的目录,
     * 子进程读写文件使用"./"读写配置文件时,都在父进程的目录里面生效,所以子进程是不能正常工作的。
     */
#if 0
    //启动新进程
    updateProcess->startDetached(program);
    qDebug() <<"新的工作目录" << updateProcess->workingDirectory();
    return;
#endif
    
     /* 3.子进程启动前调用setWorkingDirectory
     * 现象:貌似用到相对路径的时候,程序会自己退出,原因不详。(可能和我的系统有关,
     * 没有在其他系统尝试)
     */
#if 0
    //设置子进程工作目录
    updateProcess->setWorkingDirectory(workingDir);
    //启动新进程
    updateProcess->startDetached(program);
    qDebug() <<"新的工作目录" << updateProcess->workingDirectory();
    return;
#endif
    
     /* 4.子进程创建时就指定工作目录,如newProcess->startDetached(program,QStringList(), workingDir);
     * 现象:很好,父进程与子进程的工作目录分开,互不影响。父进程使用相对目录
     * 时是相对父进程的工作目录,子进程使用相对路径时是相对子进程的工作目录。
     * */
#if 0
    //启动新进程
    updateProcess->startDetached(program,QStringList(), workingDir);
    qDebug() <<"新的工作目录" << updateProcess->workingDirectory();
    return;
#endif

http://blog.csdn.net/u013281495/article/details/51086943

qt新进程工作目录的设置(工作目录确实是被子进程继承的,但也可以设置)的更多相关文章

  1. 设置vim的默认工作路径同时与自动设当前编辑的文件所在目录为当前工作路径不冲突

    问题: 想让vim自动设当前编辑的文件所在目录为当前工作路径不冲突,但是当vim新建文件的时候,工作路径会又自动切换缓存path下. 如何使当使用vim打开文件时,vim的工作路径是当前文件所在的路径 ...

  2. 把Excel工作簿的每个工作表提取出来保存为新工作簿

    平台:MS office 2010 任务:有个excel工作簿,其中有上百个工作表,要求把每一个工作表全部保存为新工作簿,如果一个一个复制出来太傻了,可以用excel自带的VB解决. 方法:打开工作簿 ...

  3. LinuxMint(同Ubuntu)下安装配置NFS设置共享目录

    假设有两台机器, 机器A:10.68.93.2 机器B:10.68.93.3 现在需要将机器A上的/opt/nfsshare共享出去,然后挂载到机器B的/nfsshare目录下. 1. 在机器A上: ...

  4. 周鸿祎——不要抱着打工心态去工作,而是把工作当创业(附读书笔记) good

    360周鸿祎反而最为开明,他说“不要抱着打工心态去工作,而是把工作当创业”,就像是,鼓励你拿着公司的工资,锻炼自己的能力,为自己以后创业积累资源和人脉(读书笔记:真是天底下最好的机会,天底下没有比工作 ...

  5. VMware 设置共享目录

    VMware 共享目录设置 1,选择"虚拟机"->"重新安装VMware Tools"2,挂载cdrom3,拷贝VMware-tool.tar.gz 到L ...

  6. jsp文件调用本地文件的方法(Tomcat server.xml 设置虚拟目录)

    JSP文件: <video id="my-video" class="video-js" controls preload="auto" ...

  7. Ubuntu16.04系统下 解决“无法获得锁 /var/lib/dpkg/lock -open (11:资源暂时不可用)、无法锁定管理目录(/var/lib/dpkg/),是否有其他进程正占用它?”的方法

    在Ubuntu16.04下安装软件,例如:sudo apt-get install lrzsz时提示: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) 无法 ...

  8. du 使用详解 linux查看目录大小 linux统计目录大小并排序 查看目录下所有一级子目录文件夹大小 du -h --max-depth=1 |grep [

    常用命令 du -h --max-depth=1 |grep [TG] |sort   #查找上G和T的目录并排序 du -sh    #统计当前目录的大小,以直观方式展现 du -h --max-d ...

  9. C++遍历目录,并把目录里超过7天的文件删除(跨平台windows&amp;linux)

    C++遍历目录,并把目录里超过7天的文件删除,适用于项目里删除过期的日志,或者视频文件. 在windows和linux下测试通过. windows测试结果: linux测试结果: 源码: #inclu ...

随机推荐

  1. ABP文档 - SignalR 集成

    文档目录 本节内容: 简介 安装 服务端 客户端 连接确立 内置功能 通知 在线客户端 帕斯卡 vs 骆峰式 你的SignalR代码 简介 使用Abp.Web.SignalR nuget包,使基于应用 ...

  2. iOS coredata 数据库的加密(待研究)

    https://github.com/project-imas/encrypted-core-data 使用起来很方便,底层还是使用了SQLCipher,有时间要研究一下! 数据库的密码不能用固定字符 ...

  3. Spring配置文件详解 - applicationContext.xml文件路径

    spring的配置文件applicationContext.xml的默认地址在WEB-INF下,只要在web.xml中加入代码 org.springframework.web.context.Cont ...

  4. Swift开发第二篇——extension及fatalError

    本篇分两部分: 一.extension在 Swift 中的使用 二.Swift 中的 fatalError 一.extension在 Swift 中的使用 在 swift 中我们可以通过 extens ...

  5. String详解, String和CharSequence区别, StringBuilder和StringBuffer的区别 (String系列之1)

    本章主要介绍String和CharSequence的区别,以及它们的API详细使用方法. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/string01. ...

  6. 在Android设备上判断设备是否支持摄像头

    private boolean hasCamera(){ boolean hasCamera=false; PackageManager pm=getActivity().getPackageMana ...

  7. iOS之UI--转场动画

    1.什么是转场动画?    就是从一个场景转换到另一个场景,像导航控制器的push效果,就是一个转场.    2.如何创建转场动画    创建转场动画    CATransition *anim = ...

  8. Asp.net 服务器Application,Session,Cookie,ViewState和Cache区别

    2.8 Context 的使用Context 对象包含与当前页面相关的信息,提供对整个上下文的访问,包括请求.响应.以及上文中的Session 和Application 等信息.可以使用此对象在网页之 ...

  9. 【LeetCode 235】Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  10. 使用C# 生成word记录

    private void button1_Click(object sender, System.EventArgs e) { object oMissing = System.Reflection. ...