In C++ habe ich eine serielle Schnittstelle geöffnet, die eine HANDLE
enthält. Wie kann ich überprüfen, ob die HANDLE
noch gültig ist, bevor Daten gelesen werden, da der Port möglicherweise von einer externen Anwendung geschlossen wird?
Ich denke, es kann getan werden, indem die HANDLE
mit einer geeigneten API-Funktion verglichen wird, aber welche? Vielen Dank.
Das Überprüfen, ob ein Handle "gültig" ist, ist ein Fehler. Sie müssen einen besseren Weg finden, damit umzugehen.
Das Problem ist, dass nach dem Schließen eines Handles derselbe Handle-Wert durch ein neues Öffnen eines anderen Objekts generiert werden kann und Ihr Test möglicherweise sagt, dass das Handle gültig ist, aber Sie arbeiten nicht mit der Datei, die Sie für richtig halten.
Betrachten Sie zum Beispiel diese Reihenfolge:
Wenn es Ihr Prozess ist, müssen Sie also nachverfolgen, welche Handles gültig sind und welche nicht. Wenn Sie das Handle von einem anderen Prozess erhalten haben, wurde es mit DuplicateHandle () in Ihren Prozess eingefügt. In diesem Fall sollten Sie die Lebensdauer des Handles verwalten, und der Quellprozess sollte dies nicht für Sie tun. Wenn Ihre Handles von einem anderen Prozess geschlossen werden, gehe ich davon aus, dass Sie derjenige sind, der das tut, und Sie müssen sich mit der Buchhaltung befassen.
Einige WinAPI-Funktionen geben den sinnlosen Wert ERROR_INVALID_PARAMETER zurück, auch wenn gültige Handles an sie übergeben werden. Daher ist vorhanden ein echter Anwendungsfall, um Handles auf Gültigkeit zu prüfen.
Die GetHandleInformation-Funktion erledigt den Job: http://msdn.Microsoft.com/en-us/library/ms724329%28v=vs.85%29.aspx
da der Port durch eine externe Anwendung geschlossen werden kann
Dies ist nicht möglich, eine externe Anwendung kann nicht den richtigen Handle-Wert erhalten, der an CloseHandle () übergeben wird. Sobald Sie den Port geöffnet haben, erhält jeder andere Prozess, der versucht, einen Handle für den Port zu erhalten, AccessDenied.
Das heißt, es gibt Crapware, die diese Einschränkung hackt, indem sie geheimes Wissen über die undokumentierten Kernelstrukturen besitzt, in denen Handles für einen Prozess gespeichert werden. Sie sind machtlos gegen sie, machen Sie nicht den Fehler, diesen Kampf anzunehmen, indem Sie dasselbe tun. Du wirst verlieren. Wenn sich ein Kunde darüber beschwert, geben Sie ihm den Rat meines Arztes: "Wenn es weh tut, dann tun Sie es nicht".
Wenn Sie eine HANDLE
erhalten und einfach herausfinden möchten, ob es sich tatsächlich um eine offene Datei handelt, gibt es die Windows-API-Funktion GetFileInformationByHandle .
Abhängig von den Berechtigungen, die Ihnen Ihr Handle für die Datei erteilt, können Sie auch versuchen, den Dateizeiger mit SetFilePointer zu verschieben, einige Daten mit ReadFile lesen oder einen Schreibvorgang mit WriteFile ausführen mit nNumberOfBytesToWrite
auf 0 gesetzt.
Wahrscheinlich befinden Sie sich unter Windows und verwenden ReadFile
zum Lesen der Daten. Die einzige Möglichkeit, dies zu überprüfen, ist das Lesen. Wenn HANDLE
ungültig ist, wird ein Fehlercode zurückgegeben (verwenden Sie GetLastEror (), um zu sehen, welcher es ist), der wahrscheinlich ERROR_HANDLE_INVALID
ist.
Versuchen Sie es mit der IsWindow () Funktion ;-)
IsWindow () ist eine Funktion der Windows API seit Windows 2000.
Konuyla ilgili örnek `
// File handle: CreateFile(), GetHandleInformation() and CloseHandle()
#include <windows.h>
#include <stdio.h>
int main(void)
{
// handle to a file
HANDLE hFile;
// file and path, change accordingly. LPCWSTR is a pointer to a constant
// null-terminated string of 16-bit Unicode characters. It is a typedef:
// typedef CONST WCHAR *LPCWSTR. The modifier 'L' is for wide character.
LPCWSTR fname = L"c:\\testfile.txt";
DWORD lpdwFlags[100];
BOOL test;
// Create a file with the given information...
hFile = CreateFile(fname, // file to be opened
GENERIC_WRITE, // open for writing
FILE_SHARE_WRITE, // share for writing
NULL, // default security
CREATE_ALWAYS, // create new file only
FILE_ATTRIBUTE_NORMAL |FILE_ATTRIBUTE_ARCHIVE | SECURITY_IMPERSONATION,
// normal file archive and impersonate client
NULL); // no attr. template
if(hFile == INVALID_HANDLE_VALUE)
printf("Could not open %s file, error %d\n", fname, GetLastError());
else
{
printf("File's HANDLE is OK!\n");
test = GetHandleInformation(hFile, lpdwFlags);
printf("The return value is %d, error %d\n", test, GetLastError());
}
// when finished, close the file handle
CloseHandle(hFile);
DeleteFile(fname);
return 0;
}`
von http://www.tenouk.com/cpluscodesnippet/createfilegetclosehandleinfo.html
Ich weiß, dass es ein bisschen spät ist, aber ich hatte eine ähnliche Frage wie Sie, um zu überprüfen, ob eine Pipe (eine Pipe, die ich mit CreateFile erstellt habe) noch offen ist (vielleicht hat das andere Ende die Verbindung geschlossen) und lesen kann, und ob es ist nicht, es wieder zu öffnen. Ich habe das getan, was @Felix Dombek vorgeschlagen hat, und ich habe die Verbindung mit WriteFile überprüft. Wenn 1 zurückgegeben wird, bedeutet dies, dass die Pipe geöffnet ist, ansonsten habe ich sie erneut mit CreateFile geöffnet. Dies impliziert, dass Ihre Pipe Duplex ist. Hier ist die CreateFile:hPipe2 = CreateFile(lpszPipename2, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
und so habe ich nach der Verbindung gesucht:
while(1)
{
bool MessageSent = WriteFile(hPipe2, "Test", 0, &cbWritten, NULL);
if (!(MessageSent))
{
LogsOut("Read pipe has been disconnected");
//Call method to start the pipe again
break;
}
Sleep(200); // I need this because it is a thread
}
Das funktioniert gut für mich :)