开发者

Is there a better way to shell out a command in C++ than system()?

开发者 https://www.devze.com 2023-01-22 23:34 出处:网络
I have a C++ windows service that sometimes crashes when I call the system() function to shell out a command. I\'ve run the exact text of the command in the windows command-line, and it runs just fine

I have a C++ windows service that sometimes crashes when I call the system() function to shell out a command. I've run the exact text of the command in the windows command-line, and it runs just fine, but for some reason it fails when system() is run.

To make matters worse, I can't seem to get any information as to why system() is failing. There doesn't seem to be an exception raised, because I'm doing a catch(...) and nothing's getting caught. My service just stops running. I know that it's the call to system() that is failing because I've put logging information before and after the call, and anything after just doesn't log anything.

So, is there a different way that I can shell out my command? At the very least, something that will give开发者_StackOverflow中文版 me some information if things go wrong, or at least let me handle an exception or something.


I belive system() is technically part of the C standard library, and therefore wouldn't throw exceptions. You should be able to check the return code or the ERRNO variable to get some information about what happened. This MSDN link has some information about the possible return codes on Windows.

I've also seen system() fail for other external reasons, such as virus scanners, so you might investigate that as well.

I don't know of a better way to run shell commands, but I could be wrong.

EDIT: If it still just seems to crash for no reason, you might try using process monitor to see what is going on at a lower level. Since the output from process monitor can be kind of overwhelming, a trick I like to use is to add a statement right before the call to system() to your program to open a nonexistent file like "C:\MARKER.TXT" or something, then you can search the process monitor output for the name of the file and look at the entries right afterward that may have something to do with the problem.


Ordinary catch() will not catch fatal exceptions (e.g. segmentation fault). You have to use structured exception handling. Better yet, enable post-mortem debugging; this article explains how you can enable post-mortem debugging of services.


You could use fork/exec, but I think that is what the system is doing.


I think your problem could be the user account associated on your service.

Either there's an environment problem (missing entry in path) or the account the service is using to run doesn't have the rights to exec whatever you're trying to run.

Run services.msc and look at the properties for your service. On the logon page, as a test, change the setup so it uses your account to run the service. If it succeeds, you know what the problem is.

Another thing to look at is the path while inside the service. Use getenv( "PATH" ) and see if a path you might be reliant on is missing.

Hope this helps...


I ended up using CreateProcess. It's been working out so far.

0

精彩评论

暂无评论...
验证码 换一张
取 消