Асинхронный WinBioVerify против WinBioVerifyWithCallback

Я написал программу, которая работает в Windows 8.1 & 10 для проверки отпечатка пальца по идентификатору текущего пользователя, вошедшего в систему, с помощью WinBioVerify. Я делаю это асинхронно, начиная сеанс с WinBioAsyncOpenSession. Я попытался запустить ту же программу в Windows 7, и оказалось, что WinBioAsyncOpenSession не существует в Win7-версии WinBio.dll.

Это не должно было быть проблемой, поскольку было достаточно легко создать отдельный EXE-файл для Win7, который обычно открывал сеанс и вместо этого вызывал WinBioVerifyWithCallback. Проблема, с которой я столкнулся, теперь имеет те же симптомы, что и в том случае, если исходная программа неправильно настраивала фокус окна приложения: при касании загорается блок отпечатка пальца, но результат не возвращается в код.

Поиск Google обнаруживает некоторые ссылки на то, что SetForegroundWindow () ненадежен в Win7, но ни одна из опробованных мною альтернатив не сработала (BringWindowToTop, AttachThreadInput, WinBioAcquireFocus), предполагая, что фокус — даже проблема.

Кто-нибудь имеет или знает какие-либо рабочие примеры WinBioVerifyWithCallback на Windows 7?

ИЗМЕНЕНО ДЛЯ ДОБАВЛЕНИЯ:

Вот код, который работает (на Win8.1 / Win10):

unsigned int verifyUser(string &userName) {

string libPath;

OutputDebugString("verifyUser: getApplicationPath");

libPath = getApplicationPath();

try {

//Make sure path ends with backslash
if (libPath[libPath.length()-1] != '\\') libPath += "\\";
string  userHash = getHash(userName);

//Get timeout from globals
int timeoutValue = globals.timeout * 1000;

//Check to see if we need an infinite timeout
if (globals.disable_timeout)
{
timeoutValue = 1000 * 60 * 5;
}
TotalTickCount = timeoutValue; //5 minutes
startTick = GetTickCount();
globals.last_scan_result = BIO_INPROGRESS;
countdownTimer = SetTimer(hMainWnd, ID_COUNTDOWN, 1000, NULL);

CString lsr;
lsr.Format("globals.last_scan_result = %d", globals.last_scan_result);
OutputDebugString(lsr);

sessionHandle = NULL;
HRESULT hr = WinBioAsyncOpenSession(
WINBIO_TYPE_FINGERPRINT,    // Service provider
WINBIO_POOL_SYSTEM,         // Pool type
WINBIO_FLAG_DEFAULT,        // Configuration and access
NULL,                       // Array of biometric unit IDs
0,                          // Count of biometric unit IDs
NULL,                       // Database ID
WINBIO_ASYNC_NOTIFY_MESSAGE,// Notification method
hMainWnd,                   // Target window
WM_APP+BIO_INPROGRESS,      // Message code
NULL,                       // Callback routine
NULL,                       // User data
FALSE,                      // Asynchronous open
&sessionHandle              // [out] Session handle
);
if (FAILED(hr))
{
CString s;
s.Format("WinBioAsyncOpenSession failed. hr = 0x%x\n", hr);
OutputDebugString(s);
KillTimer(hMainWnd, countdownTimer);
ShowWindow(hMainWnd, SW_HIDE);
LockSetForegroundWindow(LSFW_UNLOCK);
if (sessionHandle != NULL)
{
WinBioCloseSession(sessionHandle);
sessionHandle = NULL;
}
return BIO_ERROR;
}

// Find the identity of the user.
WINBIO_IDENTITY identity = { 0 };
hr = GetCurrentUserIdentity(&identity);
if (FAILED(hr))
{
CString s;
s.Format("User identity not found. hr = 0x%x\n", hr);
OutputDebugString(s);
KillTimer(hMainWnd, countdownTimer);
ShowWindow(hMainWnd, SW_HIDE);
LockSetForegroundWindow(LSFW_UNLOCK);
if (sessionHandle != NULL)
{
WinBioCloseSession(sessionHandle);
sessionHandle = NULL;
}
return BIO_USER_NOT_ENROLLED;
}

// Verify a biometric sample.
WINBIO_UNIT_ID unitId = 0;
WINBIO_REJECT_DETAIL rejectDetail = 0;
BOOLEAN match = FALSE;
OutputDebugString("Calling WinBioVerify");
SetWindowText(hStaticWnd, "To sign in, scan your finger on the fingerprint reader.");
UpdateWindow(hStaticWnd);
ShowWindow(hMainWnd, SW_SHOW);
SetForegroundWindow(hMainWnd);
LockSetForegroundWindow(LSFW_LOCK);
hr = WinBioVerify(
sessionHandle,
&identity,
WINBIO_SUBTYPE_ANY,
&unitId,
&match,
&rejectDetail
);
CString msg;
msg.Format("Swipe processed - Unit ID: %d\n", unitId);
OutputDebugString(msg);

lsr.Format("globals.last_scan_result = %d", globals.last_scan_result);
OutputDebugString(lsr);
while (globals.last_scan_result == BIO_INPROGRESS)
{
OutputDebugString("Waiting for verify...");

lsr.Format("globals.last_scan_result = %d", globals.last_scan_result);
OutputDebugString(lsr);

MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if (globals.last_scan_result == BIO_INPROGRESS)
{
WaitMessage();
}
}
OutputDebugString("Waiting for verify DONE.");

if (globals.last_scan_result == BIO_INPROGRESS)
{
globals.last_scan_result = BIO_CANCEL;
}
lsr.Format("globals.last_scan_result = %d", globals.last_scan_result);
OutputDebugString(lsr);
ShowWindow(hMainWnd, SW_HIDE);
LockSetForegroundWindow(LSFW_UNLOCK);
if (sessionHandle != NULL)
{
/*
if (globals.last_scan_result == BIO_CANCEL || globals.last_scan_result == BIO_TIMEOUT)
{
WinBioCancel(sessionHandle);
//WinBioWait(sessionHandle);
}
*/
WinBioCloseSession(sessionHandle);
sessionHandle = NULL;
}
return globals.last_scan_result;
} catch (...) {
OutputDebugString("Verify catch Error");
}
return BIO_ERROR;

}

Вот код, который не работает на Win7:

unsigned int verifyUser7(string &userName) {

string libPath;

OutputDebugString("verifyUser7: getApplicationPath");

libPath = getApplicationPath();
//  HWND capwnd;try {

//Make sure path ends with backslash
if (libPath[libPath.length() - 1] != '\\') libPath += "\\";
string  userHash = getHash(userName);

//Get timeout from globals
int timeoutValue = globals.timeout * 1000;

//Check to see if we need an infinite timeout
if (globals.disable_timeout)
{
timeoutValue = 1000 * 60 * 5;
}
TotalTickCount = timeoutValue; //5 minutes
startTick = GetTickCount();
globals.last_scan_result = BIO_INPROGRESS;
countdownTimer = SetTimer(hMainWnd, ID_COUNTDOWN, 1000, NULL);

CString lsr;
lsr.Format("globals.last_scan_result = %d", globals.last_scan_result);
OutputDebugString(lsr);

sessionHandle = NULL;
HRESULT hr = WinBioOpenSession(
WINBIO_TYPE_FINGERPRINT,    // Service provider
WINBIO_POOL_SYSTEM,         // Pool type
WINBIO_FLAG_DEFAULT,        // Configuration and access
NULL,                       // Array of biometric unit IDs
0,                          // Count of biometric unit IDs
NULL,                       // Database ID
&sessionHandle              // [out] Session handle
);
if (FAILED(hr))
{
CString s;
s.Format("WinBioOpenSession failed. hr = 0x%x\n", hr);
OutputDebugString(s);
KillTimer(hMainWnd, countdownTimer);
ShowWindow(hMainWnd, SW_HIDE);
LockSetForegroundWindow(LSFW_UNLOCK);
if (sessionHandle != NULL)
{
WinBioCloseSession(sessionHandle);
sessionHandle = NULL;
}
return BIO_ERROR;
}

// Find the identity of the user.
WINBIO_IDENTITY identity = { 0 };
hr = GetCurrentUserIdentity(&identity);
if (FAILED(hr))
{
CString s;
s.Format("User identity not found. hr = 0x%x\n", hr);
OutputDebugString(s);
KillTimer(hMainWnd, countdownTimer);
ShowWindow(hMainWnd, SW_HIDE);
LockSetForegroundWindow(LSFW_UNLOCK);
if (sessionHandle != NULL)
{
WinBioCloseSession(sessionHandle);
sessionHandle = NULL;
}
return BIO_USER_NOT_ENROLLED;
}

// Verify a biometric sample.
WINBIO_UNIT_ID unitId = 0;
WINBIO_REJECT_DETAIL rejectDetail = 0;
BOOLEAN match = FALSE;
OutputDebugString("Calling WinBioVerifyWithCallback");
SetWindowText(hStaticWnd, "To sign in, scan your finger on the fingerprint reader.");
UpdateWindow(hStaticWnd);
ShowWindow(hMainWnd, SW_SHOW);
SetForegroundWindow(hMainWnd);
LockSetForegroundWindow(LSFW_LOCK);
hr = WinBioVerifyWithCallback(
sessionHandle,
&identity,
WINBIO_SUBTYPE_ANY,
VerifyCallback,             // Callback function
NULL                        // Optional context
);
CString msg;
//msg.Format("Swipe processed - Unit ID: %d\n", unitId);
//OutputDebugString(msg);

lsr.Format("globals.last_scan_result = %d", globals.last_scan_result);
OutputDebugString(lsr);
while (globals.last_scan_result == BIO_INPROGRESS)
{
OutputDebugString("Waiting for verify...");

lsr.Format("globals.last_scan_result = %d", globals.last_scan_result);
OutputDebugString(lsr);

MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if (globals.last_scan_result == BIO_INPROGRESS)
{
WaitMessage();
}
}
OutputDebugString("Waiting for verify DONE.");

if (globals.last_scan_result == BIO_INPROGRESS)
{
globals.last_scan_result = BIO_CANCEL;
}
lsr.Format("globals.last_scan_result = %d", globals.last_scan_result);
OutputDebugString(lsr);
ShowWindow(hMainWnd, SW_HIDE);
WinBioReleaseFocus();
//LockSetForegroundWindow(LSFW_UNLOCK);
if (sessionHandle != NULL)
{
WinBioCloseSession(sessionHandle);
sessionHandle = NULL;
}
return globals.last_scan_result;
}
catch (...) {
OutputDebugString("Verify catch Error");
}
return BIO_ERROR;

}

0

Решение

Решается добавлением SetFocus () после SetForegroundWindow (). Не уверен, почему этот дополнительный шаг необходим в Windows 7.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]