ShellExecuteA加载exe文件指定工作目录找不到文件的问题

使用ShellExecuteA调用exe文件时,指定工作目录需要注意

函数原型为:

HINSTANCE ShellExecuteA(
HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTSTR lpParameters, LPCTSTR lpDirectory, INT nShowCmd );

MSDN中对lpDirectory是这样说明的:

[in] A pointer to a null-terminated string that specifies the default (working) directory for the action. If this value is NULL, the current working directory is used. If a relative path is provided at lpFile, do not use a relative path for lpDirectory.

注意最后一句:如果lpFile提供的是相对路径,则lpDirectory不能使用相对路径。

咋看这句还以为是:如果lpFile提供了相对路径,lpDirectory可以使用绝对路径,可是实验却不是如此。

下面用程序举列:目录为C:\\temp

a文件夹里放置被调程序a.exe,a.exe运行会显示所在的目录路径,如:

下面用四种情况验证:

1、test1.exe

使用相对路径加载a\\a.exe,并指定了a.exe的工作目录

使用的代码:

char* workDir = "C:\\temp\\a\\";
	HINSTANCE ret;

	//使用相对路径,指定工作目录:文件找不到
	ret = ShellExecuteA(NULL, "open", "a\\a.exe", NULL, workDir, SW_SHOWNORMAL);
	if ((int)ret == ERROR_FILE_NOT_FOUND)
	{
		std::cout << "使用相对路径,指定工作目录:文件找不到" << std::endl;
	}

如果是:提示文件找不到。

2、test2.exe

使用相对路径加载a\\a.exe,不指定a.exe的工作目录

使用的代码:

char* workDir = "C:\\temp\\a\\";
	HINSTANCE ret;

	//使用相对路径,未指定工作目录:文件加载正常
	//a.exe的工作目录为 "C:\\temp\\"
    ret = ShellExecuteA(NULL, "open", "a\\a.exe", NULL, NULL, SW_SHOWNORMAL);

结果,a.exe可以正常加载,但a.exe显示的工作目录为 C:\\temp

3、test3.exe

使用相对路径加载a\\a.exe,不指定a.exe的工作目录

使用的代码:

	char* workDir = "C:\\temp\\a\\";
	HINSTANCE ret;
 	//使用绝对路径,未指定工作目录:文件加载正常
	//a.exe的工作目录为 "C:\\temp\\"
	ret = ShellExecuteA(NULL, "open", "C:\\temp\\a\\a.exe", NULL, NULL, SW_SHOWNORMAL);

结果,a.exe可以正常加载,但a.exe显示的工作目录为 C:\\temp ,与第二种情况一样

4、test4.exe

使用绝对路径加载 a\\a.exe,同时指定a.exe的工作目录

使用的代码:

char* workDir = "C:\\temp\\a\\";
	HINSTANCE ret;
// 	//使用绝对路径,指定工作目录:文件加载正常
// 	//a.exe的工作目录为 "C:\\temp\\a\\"
 	ret = ShellExecuteA(NULL, "open", "C:\\temp\\a\\a.exe", NULL, workDir, SW_SHOWNORMAL);

结果,a.exe可以正常加载,但a.exe显示的工作目录为 C:\\temp\\a

总结:使用ShellExecuteA调用exe文件时,如果需要指定被调程序的工作目录,exe文件的路径尽量使用绝对路径

时间: 2024-10-29 09:03:19

ShellExecuteA加载exe文件指定工作目录找不到文件的问题的相关文章

WORKDIR 指定工作目录 每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更

WORKDIR 指定工作目录 格式为 WORKDIR <工作目录路径>. 使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录. 之前提到一些初学者常犯的错误是把 Dockerfile 等同于 Shell 脚本来书写,这种错误的理解还可能会导致出现下面这样的错误: RUN cd /app RUN echo "hello" > world.txt 如果将这个 Dockerf

Nodejs动态加载路由,Nodejs遍历目录,Nodejs路由工具

工具来源: Nodejs需要手动加载路由文件,如果一个个添加,项目逐渐扩大,比较麻烦. 尤其在项目route目录下,增加模块文件夹的时候,引入路由更是麻烦. 因此写了一个Nodejs动态加载路由,Nodejs遍历目录,Nodejs路由工具,取名为route.js. 支持无限级别目录结构,自动递归引用.有任何更好的建议,欢迎随时留意交流. 使用方法: 1.文件:app.js同级目录增加route.js文件,复制下面贴出源代码: 2.引入:app.js中引入:var route = require(

Win加载exe

1.OD 加载exe --> 运行到用户代码,断下之后 --> 堆栈窗口 ESP 右击 数据窗口中跟随 --> 将数据窗口的下拉框拉到最下面 (或者直接看堆栈窗口) 如下图: ZC: 此图效果为 XPsp3中的效果,有如下信息: (1).此时的 ESP值为 0012FFC4,其值 正好就是 调用kernel32.7C817067 (也就是即将调用 ExitThread) (2).程序正常结束后,就会执行 ExitThread (3).7C817044 这个函数叫什么名字?(看了 OD中k

PHP的文件加载机制到底是什么目录

PHP的文件加载看似简单,其实里面的机制却不是那么简单,相反,经常会在使用中遇到一些让人费解的问题,今天就来说一下这个机制 一句话总结: 如果以./或../开头,那么就是以浏览器访问文件为参考点 如果不是,那么就是先看include_path,再看当前文件,最后看浏览器访问文件 相信从图片上看更清楚

cocos2d-x android 直接加载下载到sd的zip里的资源文件

最近公司要做的一个cocos-x项目,这个项目用的是2.2.6版的cocos-x c++ 版,cocos比较老的版本.由于打包出来的apk超过了300M,而且资源无法热更新.面临这两个问题.我们讨论了一下,如何尽快的把包改到50m以内和在线更新新主题,对此研究了一下cocos的底层.了解到cocos可以通过 CCFileUtils::sharedFileUtils()->addSearchPath(路径); 这样的方法来加载sd 里的资源,然后我们做了第一版.资源的加载方式: 1.将资源下载到s

Swift - 本地数据的保存与加载(使用NSCoder将对象保存到.plist文件)

下面通过一个例子将联系人数据保存到沙盒的“documents”目录中.(联系人是一个数组集合,内部为自定义对象). 功能如下: 1,点击“保存”将联系人存入userList.plist文件中 2,点击“读取”从数据文件中加载解析出联系人 注意: 1,本例使用了NSCoder,这个封装了许多技术细节,使用它我们可以很轻易的将对象写到文件中,也可以用它将文件中的对象转换回来. 2,自定义对象必须添加如下两个方法,这个才能顺利的被序列化编码存储和读取. 1 2 3 4 5 6 7 8 9 10 11

asp.net动态加载程序集创建指定类的实例及调用指定方法

以下类中有三个方法: LoadAssembly:加载指定路径的程序集 GetInstance:根据Type动态获取实例,用泛型接到返回的类型 ExecuteMothod:执行实例中的指定方法 /// <summary> /// 继承自MarshalByRefObject表示允许跨域通信 /// </summary> public class RemoteLoader : MarshalByRefObject { private Assembly _assembly; public

JavaScript实现图片预加载,自适应指定尺寸容器

<!DOCTYPE html> <html> <head> <title>javascript</title> <meta type="viewport" content="width=device-width,initial-scale:1.0,user-scalable:no"/> </head> <body> <input type="button&

Java中动态加载jar文件和class文件

概述 诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下的jar文件以及classes目录下的class文件,另外像spring这类框架,也可以根据指定的路径扫描并加载指定的类文件,这个技术可以实现一个容器,容纳各类不同的子应用. Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,不像C加载动态链接库只要一个文件名就可以搞定,但JDK仍提供了一整套方法来动态加载jar文件和class文件. 动态加载jar文件 // 系统类库路径 File libPath =