win32 API for running other .exe
I wanted to know the win32 API to run the regsvr32
programatically.
I have one application through which I can communicate with COM port devices, but to achieve communication, I have to register MSCOMM32.ocx
using reg开发者_运维知识库svr32.exe
.
But now I wanted to add this provision in my code, so that there is no need to run regsvr
manually.
MSDN is your friend.
- How Regsvr32.exe Registers and Unregisters COM DLLs
- COM Server Responsibilities
I'll copy and paste the code in:
#include <tchar.h>
#include <afxole.h>
#include <stdlib.h>
#define FAIL_ARGS 1
#define FAIL_OLE 2
#define FAIL_LOAD 3
#define FAIL_ENTRY 4
#define FAIL_REG 5
static char szAppName[] = "Register";
static char szUsage[] = "\n\nUsage: Register [/u] dllname";
static char szDllRegSvr[] = "DllRegisterServer";
static char szDllUnregSvr[] = "DllUnregisterServer";
int PASCAL WinMain(
HINSTANCE hInstance,
HINSTANCE hPrev,
LPSTR pszCmdLine,
int nCmdShow)
{
int iReturn = 0;
HRESULT (FAR STDAPICALLTYPE * lpDllEntryPoint)(void);
static TCHAR szMsgBuffer[_MAX_PATH*4];
BOOL bVisualC = FALSE;
BOOL bSilent = FALSE;
BOOL bUnregister = FALSE;
LPSTR pszDllEntryPoint = szDllRegSvr;
LPSTR pszDllName = NULL;
char szCmdLineCopy[_MAX_PATH];
strcpy(szCmdLineCopy, pszCmdLine);
LPSTR pszTmp = szCmdLineCopy;
LPSTR pszTok;
while ((pszTok = strtok(pszTmp, " \t")) != NULL)
{
pszTmp = NULL;
if ((pszTok[0] == '-') || (pszTok[0] == '/'))
{
switch (pszTok[1])
{
case 'v':
case 'V':
bVisualC = TRUE;
break;
case 's':
case 'S':
bSilent = TRUE;
break;
case 'u':
case 'U':
bUnregister = TRUE;
pszDllEntryPoint = szDllUnregSvr;
break;
default:
wsprintf(szMsgBuffer,
"Unrecognized flag: %s%s",
pszTok,
(LPCSTR)szUsage);
if (!bSilent)
MessageBox(NULL,
szMsgBuffer,
szAppName,
MB_TASKMODAL | MB_ICONEXCLAMATION);
return FAIL_ARGS;
}
}
else
{
if (pszDllName == NULL)
pszDllName = pszTok;
else
{
wsprintf(szMsgBuffer,
"Extra argument on command line: %s%s",
pszTok,
(LPCSTR)szUsage);
if (!bSilent)
MessageBox(NULL,
szMsgBuffer,
szAppName,
MB_TASKMODAL | MB_ICONEXCLAMATION);
return FAIL_ARGS;
}
}
}
if (pszDllName == NULL)
{
if (!bSilent)
{
if (bVisualC)
{
MessageBox(NULL,
"This command is only valid when "
"an OLE Custom Control project is open.",
bUnregister ?
"Unregister Control" : "Register Control",
MB_TASKMODAL | MB_ICONEXCLAMATION);
}
else
{
wsprintf(szMsgBuffer,
_T("No DLL name specified%s"),
(LPCSTR)szUsage);
MessageBox(NULL,
szMsgBuffer,
szAppName,
MB_TASKMODAL | MB_ICONEXCLAMATION);
}
}
return FAIL_ARGS;
}
if (FAILED(OleInitialize(NULL)))
{
if (!bSilent)
MessageBox(NULL,
"OleInitialize failed.",
szAppName,
MB_TASKMODAL | MB_ICONINFORMATION);
return FAIL_OLE;
}
HINSTANCE hLib = LoadLibrary(pszDllName);
if (hLib < (HINSTANCE)HINSTANCE_ERROR)
{
wsprintf(szMsgBuffer,
"LoadLibary(\"%s\") failed.",
pszDllName);
MessageBox(NULL,
szMsgBuffer,
szAppName,
MB_TASKMODAL | MB_ICONEXCLAMATION);
iReturn = FAIL_LOAD;
goto CleanupOle;
}
(FARPROC&)lpDllEntryPoint = GetProcAddress(hLib, pszDllEntryPoint);
if (lpDllEntryPoint == NULL)
{
#ifdef _WIN32
int nLen = strlen(pszDllName);
if ((nLen > 4) &&
(stricmp(pszDllName + nLen - 4, ".dll") != 0) &&
(stricmp(pszDllName + nLen - 4, ".ocx") != 0))
{
wsprintf(szMsgBuffer,
"%s was loaded, but the %s entry point "
"was not found. %s does not appear to be "
"an .DLL or .OCX file.",
pszDllName,
pszDllEntryPoint,
pszDllName);
}
else
{
wsprintf(szMsgBuffer,
"%s was loaded, but the %s entry point "
"was not found. %s may not be exported, "
"or a corrupt version may be in memory. "
"Consider using PView to detect and remove it.",
pszDllName,
pszDllEntryPoint,
pszDllEntryPoint);
}
#else
wsprintf(szMsgBuffer,
"%s was loaded, but the %s entry point "
"was not found. %s may not be exported, "
"or a corrupt version may be in memory. "
"Consider using WPS to detect and remove it.",
pszDllName,
pszDllEntryPoint,
pszDllEntryPoint);
#endif
if (!bSilent)
MessageBox(NULL,
szMsgBuffer,
szAppName,
MB_TASKMODAL | MB_ICONEXCLAMATION);
iReturn = FAIL_ENTRY;
goto CleanupLibrary;
}
if (FAILED((*lpDllEntryPoint)()))
{
wsprintf(szMsgBuffer,
"%s in %s failed.",
pszDllEntryPoint,
pszDllName);
if (!bSilent)
MessageBox(NULL,
szMsgBuffer,
szAppName,
MB_TASKMODAL | MB_ICONEXCLAMATION);
iReturn = FAIL_REG;
goto CleanupLibrary;
}
wsprintf(szMsgBuffer,
"%s in %s succeeded.",
pszDllEntryPoint,
pszDllName);
if (! bSilent)
MessageBox(NULL,
szMsgBuffer,
szAppName,
MB_TASKMODAL | MB_ICONINFORMATION);
CleanupLibrary:
FreeLibrary(hLib);
CleanupOle:
OleUninitialize();
return iReturn;
}
Why do you want to run regsvr.exe to register a COM component ?
you can use the below code to directly call DllRegisterServer() from the COM component.
void RegisterDll()
{
typedef HRESULT (WINAPI *pDllRegisterServer)(void);
pDllRegisterServer pfnDllRegisterServer;
HMODULE hModule = LoadLibrary("MSCOMM32.ocx");
pfnDllRegisterServer = (pDllRegisterServer) GetProcAddress(hMoudle , "DllRegisterServer");
pfnDllRegisterServer();
}
Thanks, Shaarang Tyagi
精彩评论