Your SQL Server Desktop Engine installation may stop responding when you use the WaitForSingleObject function in a Win32 bootstrap wrapper application (841061)
The information in this article applies to:
- Microsoft SQL Server 2000 Desktop Engine (MSDE)
SYMPTOMSWhen you install Microsoft SQL Server 2000 Desktop Engine
(also known as MSDE 2000) and other third-party applications by using a Win32
bootstrap wrapper application, and your bootstrap application calls the
WaitForSingleObject function with the time-out interval parameter set to INFINITE,
the application may stop responding.CAUSEThis problem occurs because during the installation of SQL Server Desktop Engine, executable files such as
Sqlredis.exe and Setupre.exe communicate their progress by broadcasting messages
to all top-level windows. Because the messages are sent synchronously, if the
calling application owns a top-level window and is not processing the messages that are sent
to its message loop, the installation process may stop responding until the
application quits.WORKAROUNDTo work around this problem, you must call the
MsgWaitForMultipleObjects function in a message loop to process the window
messages that are posted by different executable files to the top-level windows. Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements. Note You must assign a strong password to the sa account when you install any instance of SQL Server Desktop Engine. You must do this even if the instance uses Windows
authentication mode. You must pass the generated password as a command-line
parameter to the CreateProcess function.
For additional information about how to specify a strong sa password when you install SQL Server Desktop Engine, click the following article number to view the article in the Microsoft Knowledge Base:
814463
How to specify a strong sa password when you install SQL Server 2000 Desktop Engine (MSDE 2000)
To call the
MsgWaitForMultipleObjects function in a message loop, follow these steps: - Start Microsoft Visual Studio .NET 2003.
- On the File menu, point to
New, and then click Project.
- Under Project Types, click Visual
C++ Projects, and then click Win32 Project under
Templates.
- In the Name box, type
win32bootstrap, and then click
OK.
- In the Win32 Application Wizard -
Win32bootstrap dialog box, click Finish.
- In Solution Explorer, double-click
Win32bootstrap.cpp under Source
Files.
- Add the following code to the end of the Win32bootstrap.cpp file:
int DoMSDEInstall(HWND hWnd)
{
int iResult = 1; // You can also use whatever app logic for error control requires
TCHAR msgText[256]; // Informational message buffer
TCHAR msgCaption[] = _T("Information"); // Message Box caption
UINT msgType = MB_ICONEXCLAMATION; // Message Box type spec
DWORD dwECode; // Exit code from the SQL Server Desktop Engine Setup process
MSG msg; // Message to peek and process
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
// Specify the complete path of the Setup.exe file.
// You must add code to specify a strong sa password
// as specified in 814463.
TCHAR szCommandLine[] = TEXT("setup.exe SAPWD=SomePassword REBOOT=ReallySuppress");
// Start the SQL Server Desktop Engine Setup process by sending the appropriate parameters.
// You must customize this code according to your installation requirements.
BOOL fSuccess = CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
if (fSuccess)
{
CloseHandle(pi.hThread);
// The following code replaces the call to
// WaitForSingleObject(pi.hProcess, INFINITE);
while (1)
{
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
// If it is a quit message, exit.
if (msg.message == WM_QUIT)
return 1;
// Otherwise, dispatch the message.
DispatchMessage (&msg);
}
// Wait for any message that is sent to or is posted to this queue
// or for the process handle to be signaled.
if (MsgWaitForMultipleObjects (1, &pi.hProcess,
FALSE, 1000, QS_ALLINPUT) == WAIT_OBJECT_0)
break;
}
GetExitCodeProcess(pi.hProcess, &dwECode);
CloseHandle(pi.hProcess);
}
wsprintf(msgText, _T("Exit Code is %d"), dwECode);
MessageBox(hWnd, msgText, msgCaption, msgType);
return iResult;
}
void DisplayError (DWORD dwError)
{
//Resolve the error code to a message string.
LPCTSTR MessageBuffer;
DWORD dwBufferLength = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, // module to get message from (NULL == system)
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language.
(LPTSTR) &MessageBuffer,
0,
NULL
);
DWORD dwBytesWritten;
// Output message string on stderr.
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
MessageBuffer,
dwBufferLength,
&dwBytesWritten,
NULL
);
} - Add the following function declarations at the top of the
code window after the other forward function declarations:
int DoMSDEInstall(HWND hWnd);
void DisplayError (DWORD); - Add code to call the newly added functions from an
appropriate location, according to your installation requirements. For
example, add the following code inside the Main message loop of the _tWinMain function to start the SQL Server Desktop Engine installation and to start the third-party (or
custom) application installation:
DWORD dwRes = 0;
// Call the SQL Server Desktop Engine installation function.
if (!DoMSDEInstall(msg.hwnd))
{
//Failed to install SQL Server Desktop Engine, log the error and return failure.
dwRes = GetLastError();
DisplayError(dwRes);
return dwRes;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
//Start the custom application installation or the third-party application installation.
// Provide the correct path of the executable file and the appropriate parameters.
CreateProcess(_T("Myappsetup.exe"), NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
return 0; Note You must customize this sample code according to your installation
requirements. - On the File menu, click Save
All to save all the files.
- On the Build menu, click Rebuild
Solution.
You can also work around this problem by using a console
bootstrap wrapper application to install SQL Server Desktop Engine. To do this, follow these
steps:
- Start Visual Studio .NET 2003.
- On the File menu, point to
New, and then click Project.
- Under Project Types, click Visual
C++ Projects, and then click Win32 Console Project
under Templates.
- In the Name box, type
consolebootstrap, and then click
OK.
- In the Win32 Application Wizard -
Consolebootstrap dialog box, click Finish.
- In Solution Explorer, double-click
Consolebootstrap.cpp under Source
Files.
- Replace the code in the Consolebootstrap.cpp file with the
following code:
#pragma once
#include "stdafx.h"
#include <stdio.h>
#include <atlenc.h>
#define SAPWDSWITCH _T("SAPWD=")
#define INSTANCENAME _T("INSTANCENAME=MSDETEST")
void DisplayError (DWORD);
int main(void)
{
DWORD dwRes = 0;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Specify the complete path of the Setup.exe file.
// You must add code to specify a strong sa password
// as specified in 814463.
TCHAR szCommandLine[] = TEXT("setup.exe SAPWD=SomePassword REBOOT=ReallySuppress");
// Start the SQL Server Desktop Engine Setup process by sending the appropriate parameters.
// You must customize this code according to your installation requirements.
if (!CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE,
0, NULL, NULL, &si, &pi))
{
dwRes = GetLastError();
DisplayError(dwRes);
return 0;
}
// Close main thread handle first.
CloseHandle(pi.hThread);
//
//Wait for the SQL Server Desktop Engine Setup to return.
// Important This call only works for the console application type.
// If you are using a Win32 project, use MsgWaitForMultipleObjects() instead of WaitForSingleObject().
//
WaitForSingleObject(pi.hProcess, INFINITE);
// Close the process handle.
CloseHandle(pi.hProcess);
//
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
//Start the custom application installation or the third-party application installation.
//Provide the correct path of the executable file and the appropriate parameters.
CreateProcess(_T("Myappsetup.exe"), NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
return 0;
}
void DisplayError (DWORD dwError)
{
//Resolve the error code to a message string.
LPCTSTR MessageBuffer;
DWORD dwBufferLength = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, // module to get message from (NULL == system)
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language.
(LPTSTR) &MessageBuffer,
0,
NULL
);
DWORD dwBytesWritten;
// Output message string on stderr.
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
MessageBuffer,
dwBufferLength,
&dwBytesWritten,
NULL
);
} - On the File menu, click Save
All to save all the files.
- On the Build menu, click Rebuild
Solution.
REFERENCES
For additional information about this problem, click the following article numbers to view the articles in the Microsoft Knowledge Base:
247221
PRB: Unattended install of SQL Server 7.0 or MSDE 1.0 stops responding
824042 PRB: The SQL Server Desktop Engine Setup program may stop responding when it is started from an external application
For additional information about SQL Server Desktop Engine installation, deployment, and patching, click the following article number to view the article in the Microsoft Knowledge Base:
817788
Support WebCast: Microsoft SQL
Server 2000 Desktop Engine (MSDE) installation, deployment, and patching
Modification Type: | Major | Last Reviewed: | 7/5/2005 |
---|
Keywords: | kbsetup kbConsole kbAuthentication kbAppSetup kbhowto kbcode kbinfo KB841061 kbAudDeveloper |
---|
|