Is it safe to pass CComVariant declared locally to other function
1. Can I pass the CommVariant to other function, when not created using new ?
2. Should I free it/delete expecitly some where ?
3. Is it safe ? any precauions ?
You must also check the vt member. When expecting a boolean value, it must be VT_BOOL. When the requested property exists but did not contain a value, VT_EMPTY or VT_NULL are returned (the return type depends on the property value type).
The result of an expression is temporary, and it is destroyed an the and of the expression evaluation.
In your first case, you are getting a temporary string as a result of s1+s2, whose buffer pointer is saved in s. After that, the expression finish, the temporary is destroyed, and so it is its buffer and s is left dangling. You had been lucky in having printed nothing. accessing a deleted buffer can even result in a crash.
In your second example, the temporary string resulting from s1+s2 is kept alive until the expression it belongs ( cout<<(s1+s2).c_str()<<endl; ) is evaluated. Hence its buffer (renturned from c_str()) is still there at the time its pointer is given to cout.
Your first sample works correctly if you retain the string:
void SetStr(string& s1, string& s2)
string ss; //the place to store the result
ss = s1+s2; //the result of s1+s2 is moved to ss, that survives the expression itselfconst char* s = ss.c_str(); //ss buffer pointer obtained
cout << s << endl; //your original cout
The original problem that lead to the question was that when the program running in the process was canceled, or halted due to a requirement missing, the cosmetic loop would still be running, instead of exiting and sending the appropriate message to the message pump to go to the next stage. So I added the GetExitCode to double check that the process was still running, or if the process had been halted.
Just didn't think my quick fix was the correct way to check, and just wanted to do it right.
The original problem that lead to the question was that when the program running in the process was canceled, or halted due to a requirement missing, the cosmetic loop would still be running, instead of exiting and sending the appropriate message to the message pump to go to the next stage.
I actually have something to say about this. I have noticed over the last few years that many of the younger junior programmers coming out of college are no longer using exit codes. I have noticed this in many of the recent Microsoft products and applications from various other software vendors. I believe it is probably because most of us older engineers have experience with the Unix and DOS shell and have extensively used exit codes in bash,cshrc scripts and/or DOS batch files.
Unfortunately since the installer you are using is not returning an exit code upon cancellation... you may need to think outside the box and come up with a creative way to determine if your installer has completed. I noticed that one of your variable names was associated with Microsoft SQL Server... so maybe you could check the registry keys under the tree: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\
Finally, I would encourage you (and anyone reading this) to think of this experience as a lesson; Exit codes might be useful to someone... rather than always return 0; consider returning a useful value that reflects the outcome of the task.
There's nothing wrong with using WaitForSingleObject() on the hProcess returned from CreateProcess(). Its very purpose is to give you a waitable object that's signalled when the process teminates. Until it terminates, the GetExitCodeProcess() cannot tell you the exit code
Some folks might comment on the fact that your wait loop includes a message pump which implies that you are waiting during processing of a GUI element / button but to each his own. This works.
That's the defined behavior of GetExitCodeProcess(). The exit code does not exist until the process exits! The defined return is "Still Active", meaning "No exit code exists", or colloquially expressed, "Yo, Dude, What Exit Code? It Ain't Exited Yet".
Well, the call inside the loop is pretty useless but if it makes you happy...
The sole purpose, as written, is to cause the big while loop to break out if the response is anything but "still running". But the WaitForSingleObject() returning anything other than "WAIT_TIMEOUT" (that is, WAIT_OBJECT_0) also breaks out of the loop (the "else clause") which will happen as soon as the thread stops running (which sets the exit code and signals the hProcess object).
Now, I'll grant you that by having the call at the bottom of the while loop may cause you to notice the process termination a couple of microseconds earlier than if you went to the top of the loop but you counter act that miniscule gain by discarding the status you might have received then and issue another GetExitCodeProcess() immediately upon exiting the while loop.
So, it adds nothing to the code, adds processing at each iteration. But, like I said, if it makes you happy ....
If I were a malicious / devious person, I'd write my process to "return 259;" as the exit status. Since GetExitCodeProcess() returns either status STILL_ACTIVE or the return code from the process. If 259 is my exit code, following Microsoft's method for testing the status would be fooled into thinking the process is still running. Does this count as "Amusing Microsoft API Tricks"
Anyway, WaitForSingleObject() on the hProcess object is the only way to be sure.
I observe that you are passing a variable named sz_SQLServer_Install_FileName to CreateProcess which would obviously imply that you are installing SQL Server. Are you using a MSI installer? According to the documentation... the MsiExec.exe and InstMsi.exe MSI installers will return useful status/error codes.
I'm running these programs. I think Microsoft wrote the installer.
I just finished running the test, and put the line back in. Can't detect a cancel when I click the red X square during the expansion of the files to the temp dir. With the line, I can detect the click. So I guess the line is useful. I just want to cover my butt, who knows what the user will do.
So I detect the cancel, use the message pump to acknowledge the cancel, messagebox, start the installation again.
Thanks for your help last night Randor. Your open and closed probe questions help me understand why I needed that line of code, to detect if the process was still running.
It did not dawn on me that that the exit code came from the program that I was running, and that I can't trust the program to produce an exit code upon exit.
As far as the WaitForSingleObject goes, I have it set for 10, because I needed the cosmetic loop to run, and needed to be able to send messages to the pump.
I like the way it is, so I will leave it, and add something to make a check for completion, like checking to see if the final install log file exist or something.
I was tired last night so I left the office.
Almost done with the initial version of my program, and everything actually works. I was able to translate all my vb programs so far which amazes me. Should be done by the end of the month, and will then make the deployment package.
Going to need some alpha testers, I wonder if Code Project can help me with that.
Last Visit: 31-Dec-99 19:00 Last Update: 29-Nov-23 9:08