WbemObject.Terminate failure reason - wmi

As for now, I'm improving logging in my Inno Setup installer, so if consumer will get some sort of error, I can easily see, what went wrong.
As one of installation actions, I kill application process, if it is running, to overwrite files gracefully. To kill application, I use approach, which is described in question Inno Setup Kill a running process - getting WbemObject and calling WbemObject.Terminate.
As for now, I want to track, if Terminate was successful. From my testing, I've found out, that it actually returns boolean, indicating, whether application was terminated successfully. But if it fails, it simply returns "false". And I want to know more detailed reason.
So, is there way to get actual failure reason for WbemObject.Terminate?

What you have, is not WbemObject, it's Win32_Process object.
The Win32_Process.Terminate method does return uint32 (Cardinal in Pascal), not Boolean:
Returns a value of 0 (zero) if the process was successfully terminated, and any other number to indicate an error. For additional error codes, see WMI Error Constants or WbemErrorEnum. For general HRESULT values, see System Error Codes.
Successful completion (0)
Access denied (2)
Insufficient privilege (3)
Unknown failure (8)
Path not found (9)
Invalid parameter (21)
Other (22–4294967295)

Related

C++ std::filesystem::copy fail with "Network location cannot be reached"

I have written a small c++ application which is being automatically started after Windows boot on a couple of clients. This application will copy a file from a network share (same network share for all clients) to the local disk. When I reboot all clients at once, a bunch of them will get an error 1231 from the std::filesystem::copy function with following message:
"Network location cannot be reached"
If I reboot all clients with an interval of a couple of seconds between them, then there is no problem.
This makes me think that the copy function might be blocking the file during copying.
Is there some setting that I am missing that prevents this? Is this normal behaviour?
EDIT: I have been able to fix the network problem, I now however get an error 32 which states that "the process cannot access the file because it is being used by another process". Does the copy function lock the files that are currently being copied?
It sounds more like the network share has not been mounted yet. If all clients attempt to mount the same network share at the same time this may mean a lot of work for the server handing out the share. Consequently, some clients may time out and may have to repeat their request. Make sure the network share is actually mounted before you attempt to copy from it.
You are facing a problem due to an uninitialized network of your client workstations.
The error ERROR_NETWORK_UNREACHABLE - 1231 (0x4CF) indicates that the path provided is not reachable at an instance.
You can use two approaches:
1) Continue with while-loop until you get the success to check whether filepath exists. Handle the error situation with try-catch if any.
When you get the success go for download/copy.
2) Sleep for 60 sec to 180 sec before download/copy file in the current program.
I edited my question; there was indeed a problem with active directory where the client was not immediately given an IP address and thus not being able to access the share.
After some more testing, I now see that I am only able to perform a copy command on one of the clients using std::filesystem::copy, while the others show an error message 32, stating that "the process cannot access the file because it is being used by another process". If I use the xcopy command in a batch file instead on all devices simultaneously, I do not get any error...

Websphere MQ - error with reason code 2042 on a get

We're getting an intermittent error on a ImqQueue::get( ImqMsg &, ImqGetMessageOptions & ); call with reason code 2042, which Should Not Happen™ based on the Websphere documentation; we should only get that reason code on an open.
Would this error indicate that the server could not open a queue on its side, or does it indicate that there's a problem in our client? What is the best way to handle this error? Right now we just log that it occurs, but it's happening a lot. Unfortunately I'm not well-versed in Websphere MQ; I'm kind of picking this up as I go, so I don't have all the terminology correct.
Our client is written in C++ linking against libmq 6.0.2.4 and running on SLES-10. I don't know the particulars for the server other than it's running version 7.1. We're requesting an upgrade to bring our side up-to-date. We have multiple instances of the client running concurrently; all are using the same request queue, but each is creating its own dynamic reply queue with MQOO_INPUT_EXCLUSIVE + MQOO_INPUT_FAIL_IF_QUIESCING.
If the queue is not already open, the ImqQueue::get method will implicitly open the queue for you. This will end up with the MQOO_INPUT_AS_Q_DEF option being used which will therefore use the DEFSOPT(EXCL|SHARED) attribute on the queue. You should also double check that the queue is defined SHARE rather than NOSHARE, but I suspect that will already be correctly set.
You mention that you have multiple instances of the application running concurrently so if one of them has the queue opened implicitly as MQOO_INPUT_AS_Q_DEF resulting in MQOO_INPUT_SHARED from DEFSOPT, then it will get 2042 (MQRC_OBJECT_IN_USE) if others have it open. If nothing else had it open at the time, then the implicit open will work, and later instances will instead get the 2042.
If it is intermittent, then I suggest there is a path through your application where ImqQueue::open method is not invoked. While you look for that, changing the queue definition to DEFSOPT(SHARED) should get rid of the 2042s.

How should I handle an error in libpq for postgresql

I'm creating a few simple helper classes and methods for working with libpq, and am wondering if I receive an error from the database - (e.g. SQL error), how should I handle it?
At the moment, each method returns a bool depending on whether the operation was a success, and so is up to the user to check before continuing with new operations.
However, after reading the libpq docs, if an error occurs the best I can come up with is that I should log the error message / status and otherwise ignore. For example, if the application is in the middle of a transaction, then I believe it can still continue (Postgresql won't cancel the transaction as far as I know).
Is there something I can do with PostgreSQL / libpq to make the consequences of such errors safe regarding the database server, or is ignorance the better policy?
You should examine the SQLSTATE in the error and make handling decisions based on that and that alone. Never try to make decisions in code based on the error message text.
An application should simply retry transactions for certain kinds of errors:
Serialization failures
Deadlock detection transaction aborts
For connection errors, you should reconnect then re-try the transaction.
Of course you want to set a limit on the number of retries, so you don't loop forever if the issue doesn't clear up.
Other kinds of errors aren't going to be resolved by trying again, so the app should report an error to the client. Syntax error? Unique violation? Check constraint violation? Running the statement again won't help.
There is a list of error codes in the documentation but the docs don't explain much about each error, but the preamble is quite informative.
On a side note: One trap to avoid falling into is "testing" connections with a trivial query before using them, and assuming that means the real query can't fail. That's a race condition. Don't bother testing connections; simply run the real query and handle any error.
The details of what exactly to do depend on the error and on the application. If there was a single always-right answer, libpq would already do it for you.
My suggestions:
Always keep a record of the transaction until you've got a confirmed commit from the DB, in case you have to re-run. Don't just fire-and-forget SQL statements.
Retry the transaction without a disconnect and reconnect for SQLSTATEs 40001 (serialization_failure) and 40P01 (deadlock_detected), as these are transient conditions generally resolved by re-trying. You should log them, as they're opportunities to improve how the app interacts with the DB and if they happen a lot they're a performance problem.
Disconnect, reconnect, and retry the transaction at least once for error class 08 (connection exceptions).
Handle 53300 (too_many_connections) and 53400 (connection limit exceeded) with specific and informative errors to the user. Same with the other 53 class entries.
Handle class 57's entries with specific and informative errors to the user. Do not retry if you get a query_cancelled (57014), it'll make sysadmins very angry.
Handle 25006 (read_only_sql_transaction) by reporting a different error, telling the user you tried to write to a read-only database or using a read-only transaction.
Report a different error for 23505 (UNIQUE violation), indicating that there's a conflict in a unique constraint or primary key constraint. There's no point retrying.
Error class 01 should never produce an exception.
Treat other cases as errors and report them to the caller, with details from the problem - most importantly SQLSTATE. Log all the details if you return a simplified error.
Hope that's useful.

ADO Command Execute fails

I am using Execute method on the ADO command object to execute a stored procedure. This call throws an exception when the network adapter is disabled and re-enabled
why would the Execute fail in this case ?
The Execute fails because the underlying network connection has been lost (though the logical state of the Connection object will still appear as Open)
What you can do about this :
as a general rule, open your connection just before using it. Release it just after use,
have an error handling process which, on error, checks if the connection is closed, reopens it and rerun the Command.
I guess the answer depends on your use of your DB.
You could also imagine having a monitorig thread which performs simple select on a regular basis and reopens the connection if it is closed.

Error handling in overlapped socket IO

Can anyone please suggest a reliable way to handle system errors in case of using overlapped socket IO and IOCP?
MSDN description is cumbersome on this aspect. It says that for GetQueuedCompletionStatus return code FALSE there should be a subsequent GetLastError call to get error code on the failed operation. However, we know that for WSA-functions one should call WSAGetLastError instead (GetLastError returns 0 upon a socket error). So the first part of question is - how does it work in practice?
Another problem is handling errors if completion packets are extracted by GetQueuedCompletionStatusEx. MSDN describes only error handling for this call itself, saying nothing about obtaining error codes of individual failed operations.
Thanks in advance for all responses and comments.
After few hours of experimenting and studying MSDN with a magnifying glass I've found the following:
http://msdn.microsoft.com/en-us/library/ms684342%28v=VS.85%29.aspx (an article on OVERLAPPED structure, description of the Internal field):
The error code for the I/O request. When the request is issued, the system sets this member to STATUS_PENDING to indicate that the operation has not yet started. When the request is completed, the system sets this member to the error code for the completed request.
The Internal member was originally reserved for system use and its behavior may change.
The last phrase doesn't look good, but I guess it is what it is.