在可执行程序中运行 bat 批处理的问题

xt_xiaotian 2010-07-01 12:12:20
使用了一个第三方的 bat 处理包,整个 bat 包文件大小为 500KB(全部是 bat 文件),非常复杂,现在要对这个 bat 添加一些功能。
由于这个批处理太复杂,不想直接进行更改,目前更改想法为:建立一个 C++ 工程,在 C++ 代码中运行 bat 文件,然后再加入自己想要的功能,但出现了一些问题,功能加不上,示例代码如下:

test.bat 内容:
set PATH=%PATH%;c:\MyPath

C++ 工程中 cpp 文件内容:
#include <Windows.h>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[]) {
ShellExecute(NULL, L"open", L"c:\\Users\\admi\\Desktop\\test.bat", NULL, NULL, SW_SHOW);
wchar_t buffer[1024] = {0};
GetEnvironmentVariable(L"PATH", buffer, 1024);
wcout << buffer << endl;

return 0;
}

在我机器上运行结果为:
1、在 cmd 下直接运行 test.bat
C:\>test.bat
C:\>set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\Common Files\Thunder Network\KanKan\Codecs;C:\Program Files\TortoiseSVN\bin;C:\Program Files\depot_tools\;C:\Program Files\OpenVPN\bin;c:\MyPath
可见,新添加的路径“c:\MyPath”已经加入了。

2、在 C++ 程序中执行的结果为:
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\Common Files\Thunder Network\KanKan\Codecs;C:\Program Files\TortoiseSVN\bin;C:\Program Files\depot_tools\;C:\Program Files\OpenVPN\bin;C:\Program Files\Microsoft Visual Studio 8\;C:\ProgramFiles\Microsoft Visual Studio 8\VC\bin
“c:\MyPath”并没有被加入。也就是说在 C++ 中执行的批处理并没奏效,请问如何才能使执行的批处理奏效呢?
...全文
969 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Erorr 2010-07-01
  • 打赏
  • 举报
回复
ShellExecute(NULL, L"open", L"c:\\Users\\admi\\Desktop\\test.bat", NULL, NULL, SW_SHOW);
打开一个Console,执行完又关闭了,所以没用
xt_xiaotian 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 mstlq 的回复:]
即使楼主在cmd里面运行test.bat之后,到我的电脑属性里查看环境变量,c:\MyPath也是没有加入到PATH里面的……
[/Quote]
我并不是想改变系统的环境变量,只想在当前进程奏效而已,但上述做法在当前进程中都没奏效。
mstlq 2010-07-01
  • 打赏
  • 举报
回复
即使楼主在cmd里面运行test.bat之后,到我的电脑属性里查看环境变量,c:\MyPath也是没有加入到PATH里面的……
mstlq 2010-07-01
  • 打赏
  • 举报
回复
没记错的话,set PATH=%PATH%;c:\MyPath改变不了环境变量,只是暂时起作用而已……
所以楼主检测的方法不当……
xt_xiaotian 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 loaden 的回复:]
引用 14 楼 xt_xiaotian 的回复:

引用 13 楼 loaden 的回复:
子进程会继承环境变量。
你要Wait进程,直到结束。

比如:A.exe 调用了bat,则已经拥有了临时的环境变量。
此时,A.exe千万不能结束,即在调用了bat后,要调用你的目标程序:B.exe
则B.exe自然拥有了A.exe的环境变量。

似乎你理解错我的意思了,我的意思是,C+……
[/Quote]
谢谢你的答复,问题解决了。在批处理最后加入一行不会造成太大影响。
在父进程(即bat所执行的进程中)直接创建子进程,子进程会继承父进程的配置环境,然后在我的C++中作自己想做的事情即可。
也试了start some.exe,程序也可正常继承环境配置,试了一下,没问题。
DuGuloveUU 2010-07-01
  • 打赏
  • 举报
回复
学习了~~~
「已注销」 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 xt_xiaotian 的回复:]

引用 13 楼 loaden 的回复:
子进程会继承环境变量。
你要Wait进程,直到结束。

比如:A.exe 调用了bat,则已经拥有了临时的环境变量。
此时,A.exe千万不能结束,即在调用了bat后,要调用你的目标程序:B.exe
则B.exe自然拥有了A.exe的环境变量。

似乎你理解错我的意思了,我的意思是,C++程序调用 bat 处理程序,调用完成后在执行响应命令……
[/Quote]
是你没理解我的意思,这是我描述的问题。
可以在该bat文件的最后加一行么?
这加的一行,就是调用你的C++程序。
然后通过另一个C++程序来调用这个bat,并等待结束。
在bat中不要用:
start some.exe

而是直接单写一行:
@some.exe
xt_xiaotian 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 loaden 的回复:]
子进程会继承环境变量。
你要Wait进程,直到结束。

比如:A.exe 调用了bat,则已经拥有了临时的环境变量。
此时,A.exe千万不能结束,即在调用了bat后,要调用你的目标程序:B.exe
则B.exe自然拥有了A.exe的环境变量。
[/Quote]
似乎你理解错我的意思了,我的意思是,C++程序调用 bat 处理程序,调用完成后在执行响应命令, C++ 程序需要用到 bat 所设置过的环境。
「已注销」 2010-07-01
  • 打赏
  • 举报
回复
子进程会继承环境变量。
你要Wait进程,直到结束。

比如:A.exe 调用了bat,则已经拥有了临时的环境变量。
此时,A.exe千万不能结束,即在调用了bat后,要调用你的目标程序:B.exe
则B.exe自然拥有了A.exe的环境变量。
xt_xiaotian 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 zhao4zhong1 的回复:]
试试这个
system("cmd /c cd /d c:\\Users\\admi\\Desktop\\&test.bat");
[/Quote]
不明白你的意思,执行这行代码后,GetLastError:18(没有更多的文件)。
你是现在 cmd 后面加参数吗?
赵4老师 2010-07-01
  • 打赏
  • 举报
回复
试试这个
system("cmd /c cd /d c:\\Users\\admi\\Desktop\\&test.bat");
xt_xiaotian 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 xt_xiaotian 的回复:]
引用 8 楼 mstlq 的回复:
引用 6 楼 xt_xiaotian 的回复:
引用 4 楼 erorr 的回复:
ShellExecute(NULL, L"open", L"c:\\Users\\admi\\Desktop\\test.bat", NULL, NULL, SW_SHOW);
打开一个Console,执行完又关闭了,所以没用

这个现象我也看到了,但一时找不到办法解……
[/Quote]
说错。
system 函数是调用 CreateProcess 实现的,至少 VS 是这样做的。
ShellExcute 内部也是调用 CreateProcess 的。
xt_xiaotian 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 mstlq 的回复:]
引用 6 楼 xt_xiaotian 的回复:
引用 4 楼 erorr 的回复:
ShellExecute(NULL, L"open", L"c:\\Users\\admi\\Desktop\\test.bat", NULL, NULL, SW_SHOW);
打开一个Console,执行完又关闭了,所以没用

这个现象我也看到了,但一时找不到办法解决。

弃ShellExecute……
[/Quote]
system 函数是调用 ShellExcute 实现的,至少 VS 是这样做的。
mstlq 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 xt_xiaotian 的回复:]
引用 4 楼 erorr 的回复:
ShellExecute(NULL, L"open", L"c:\\Users\\admi\\Desktop\\test.bat", NULL, NULL, SW_SHOW);
打开一个Console,执行完又关闭了,所以没用

这个现象我也看到了,但一时找不到办法解决。
[/Quote]
弃ShellExecute改用system试试……
xt_xiaotian 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 erorr 的回复:]
如果仅仅是设置环境变量,可以用API
SetEnvironmentVariable(L"PATH", L"ABC");
[/Quote]
没这么简单的,那个第三方 bat 库有 500KB,里面处理了很多逻辑。
xt_xiaotian 2010-07-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 erorr 的回复:]
ShellExecute(NULL, L"open", L"c:\\Users\\admi\\Desktop\\test.bat", NULL, NULL, SW_SHOW);
打开一个Console,执行完又关闭了,所以没用
[/Quote]
这个现象我也看到了,但一时找不到办法解决。
Erorr 2010-07-01
  • 打赏
  • 举报
回复
如果仅仅是设置环境变量,可以用API
SetEnvironmentVariable(L"PATH", L"ABC");

65,194

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧