So I'm trying to run a series of commands via using system()
, however I noticed that changes don't carry on. For example, I define a variable p as user input set /p p=Enter name
(or in powershell $p=Read-Input "Enter Name"
Now if I want to use P again, I use system("echo %p%")
(or %p I forgot which), but p is undefined here since a new system call creates a new cmd call. I also tried system("CD test")
yet the CD remains the same and doesn't change in the next system call.
How can I make sure the system calls use each others' variables and such?
Asked
Active
Viewed 76 times
-2

thethiny
- 1,125
- 1
- 10
- 26
-
2https://stackoverflow.com/questions/49518662/unix-commands-with-c/49518756#49518756 – Mar 29 '18 at 22:13
-
@NeilButterworth I saw this but his solution only mentions the CD thing, while I want a general solution that works for anything else. I can try to add parenthesis and semicolons but that doesn't work if I need some C++ in the middle. – thethiny Mar 29 '18 at 22:15
-
3@thethiny: `system()` spawns a new process for the OS's command processor (`cmd.exe` on Windows, etc). Any changes made to that process's environment are lost when the process exits. That is exactly what Neil's other answer explains. Same thing here. What you are attempting to do cannot be done with `system()`. Use platform APIs instead (on Windows, `(Get|Set)EnvironmentVariable()`, `(Get|Set)CurrentDirectory()`, etc) to update the environment of the calling process, which can then be inherited by child processes – Remy Lebeau Mar 29 '18 at 22:16
-
@RemyLebeau I was hoping there would be some alternative solution that someone can guide me to, since I need to rely on batch for curl. Since you suggested platform APIs I believe they will do the trick. Go ahead and suggest it as an answer so I can accept it. Thanks! – thethiny Mar 29 '18 at 22:20
-
1@thethiny: you do know that curl has [a library](https://curl.haxx.se/libcurl/) that you can use directly in your C++ code, don't you? You don't need to spawn batch processes to use it – Remy Lebeau Mar 29 '18 at 22:21
-
@RemyLebeau the library required me to manually submit the version and additional info (like the protocol with its version) which I found to be more complex that its powershell equivalent. – thethiny Mar 29 '18 at 22:32
-
@thethiny you could use Environment Variables as a simple trick for this. – douglasjfm Mar 29 '18 at 22:46
-
@thethiny: the libcurl library is not that hard to use, and you can let it pick a default protocol and version for you. I think you are making things harder for yourself than you should be. But whatever, it is your choice. – Remy Lebeau Mar 29 '18 at 22:54
-
Please take a look on [What is the reason for '...' is not recognized as an internal or external command, operable program or batch file?](https://stackoverflow.com/a/41461002/3074564) There you can read how environment variables are managed and that each running process has its own set of environment variables. – Mofi Mar 30 '18 at 11:08
-
But honestly I have no idea why you are writing a C++ application which uses PowerShell or batch files at all. Everything which can be done with a PowerShell script or a batch file can be done with C++ code using Windows kernel and library functions as well, including simple things like prompting user for an input and setting environment variables for current process (C++ application) and all processes created from this process. I think your real problem is not reading available and free C++ documentation. – Mofi Mar 30 '18 at 11:13
-
For example read the documentation for function [system](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/system-wsystem) and the documentation of the alternatives in __See Also__ section. I strongly recommend using in C++ application the [Process Class](https://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx) instead of __system()__. – Mofi Mar 30 '18 at 11:18
-
@Mofi I'm still new to this so I'm learning. I never knew that there is a kernel function until I posted this. Thanks. – thethiny Mar 30 '18 at 17:20
1 Answers
1
Each call of system
has it's own environment, by definition.
On Linux and Mac, you can use popen
and MSVC has a similar _popen
.
That said, Remy's comment is a viable alternative. You can still use system
to start curl after you've called SetCurrentDirectory()
from your own code. Your problem is that successive children don't inherit each others environment; they all inherit from the parent process (i.e. your C++ code). So get that parent right.

MSalters
- 173,980
- 10
- 155
- 350