📄 setupinf.cpp
字号:
// SetupInf.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <prsht.h> // includes the property sheet functionality
#include "setupapi.h" // includes the inf setup api
#include <regstr.h>
#include "SetupWiz.h"
#include "SetupInf.h"
//#define INFFILENAME "kmoufilt.inf"
#define INFFILENAME "app.inf"
void InstallFinish(BOOL DoRunOnce);
// global value
INSTALLINFO g_InstallInfo;
CHAR g_szInfPathName[MAX_PATH];
BOOL m_bCreated = FALSE; // Keep us minimized once we are created
#if 0
LRESULT
WINAPI
MyQueueCallback (
IN MY_INSTALL_DATA* pMyInstallData,
IN UINT Notification,
IN UINT Param1,
IN UINT Param2
)
{
if (SPFILENOTIFY_DELETEERROR == Notification)
{
// Skip any file delete errors
// this sample only deletes files on an unintall
// so if the delete encounters an error simply skip the operation
// and continue processing the queue
return FILEOP_SKIP;
}
else
{
// Pass all other notifications through without modification
return SetupDefaultQueueCallback(pMyInstallData->pDefaultContext,
Notification, Param1, Param2);
}
}
#endif
//
// FUNCTION: BOOL DoInstallation( HWND hWnd, INSTALLINFO * si )
//
// PURPOSE: Install components via setupapi.dll.
//
// COMMENTS:
//
// The function does inf install operations based
// on the content of the INSTALLINFO data.
// These steps could be done during the wizard but
// this technique allows for installations with user input.
//
// This routine will take a INSTALLINFO
// and do an installation based on those settings
// using the setupapi.dll
BOOL DoInstallation( HWND hWnd, INSTALLINFO * si )
{
HINF hInf;
char szSourcePath[MAX_PATH];
char szInfFileName[MAX_PATH];
DWORD dwResult;
BOOL bResult = FALSE;
// Context for my call back routine
// MY_INSTALL_DATA MyInstallData;
// HSPFILEQ FileQueue;
//
// In this sample we assume the inf is in the base of the
// base installation source path--it usually is for most installs
//
GetModuleFileName(NULL, szSourcePath, MAX_PATH);
*(strrchr(szSourcePath, '\\') + 1) = '\0'; // Strip setup.exe off path
strcpy(szInfFileName, szSourcePath);
strcpy(g_szInfPathName, szSourcePath); // save the path to global value
strcat(szInfFileName, INFFILENAME);
//
// Get inf handle
// must know where the inf is located
// SetupOpenInfFile will only look in windows\inf by default
//
hInf = SetupOpenInfFile (
szInfFileName, // If path,needs full path, else looks in %windir%\inf
NULL, // Inf Type, matches Class in [Version] section SetupClass=SAMPLE
INF_STYLE_WIN4, // or INF_STYLE_OLDNT
NULL // Line where error occurs if inf is has a problem
);
if (hInf == INVALID_HANDLE_VALUE)
{
dwResult = GetLastError();
//
// TODO: handle case where inf cannot be opened
// by asking the user to locate the inf
return FALSE;
}
si->hInf = hInf;
// Run the wizard
bResult = CreateWizard(hWnd, si->hInst);
SetupCloseInfFile(hInf);
if(bResult)
{
InstallFinish(TRUE);
SetupPromptReboot(NULL, hWnd, FALSE);
}
return TRUE;
}
//
// FUNCTION: MainWndProc(HWND, UINT, UINT, LONG)
//
// PURPOSE: Processes messages for the main window procedure
//
// MESSAGES:
//
// WM_CREATE - creates the main MLE for the window
// WM_COMMAND - processes the menu commands for the application
// WM_SIZE - sizes the MLE to fill the client area of the window
// WM_DESTROY - posts a quit message and returns
//
LONG APIENTRY MainWndProc(
HWND hWnd, // window handle
UINT message, // type of message
UINT wParam, // additional information
LONG lParam) // additional information
{
switch (message)
{
case WM_CREATE:
// Start up the install
PostMessage(hWnd, WM_COMMAND, ID_INSTALL, 0 );
return 0;
case WM_WINDOWPOSCHANGING:
if (m_bCreated)
{
LPWINDOWPOS lpwp;
lpwp = (LPWINDOWPOS) lParam; // points to size and position data
lpwp->flags = SWP_NOMOVE | SWP_NOOWNERZORDER |
SWP_NOSIZE | SWP_NOREDRAW |
SWP_NOREPOSITION;
}
else
{
m_bCreated = TRUE;
}
break;
case WM_COMMAND:
switch( LOWORD( wParam ))
{
/*******************************************************\
*
* Here is where the real work takes place
* Do the wizard to collect the user information
* Do the installation with the setupapis
* Update the registry with runtime user data
*
\*******************************************************/
case ID_INSTALL:
// Do installation
DoInstallation(hWnd, &g_InstallInfo);
//installs done so go away
PostMessage(hWnd, WM_DESTROY, 0, 0 );
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
break;
case WM_DESTROY: /* message: window being destroyed */
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
//
//
// FUNCTION: InitApplication(HANDLE)
//
// PURPOSE: Initializes window data and registers window class
//
// COMMENTS:
//
// This function registers the window class for the main window.
//
BOOL InitApplication(HINSTANCE hInstance)
{
WNDCLASS wcSample;
// Fill in window class structure with parameters that describe the
// main window.
wcSample.style = 0;
wcSample.lpfnWndProc = (WNDPROC)MainWndProc;
wcSample.cbClsExtra = 0;
wcSample.cbWndExtra = 0;
wcSample.hInstance = hInstance;
wcSample.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SETUP));
wcSample.hCursor = LoadCursor(NULL, IDC_ARROW);
wcSample.hbrBackground = (HBRUSH)GetStockObject(COLOR_BACKGROUND);
wcSample.lpszMenuName = NULL;
wcSample.lpszClassName = TEXT("SampleWClass");
return (RegisterClass(&wcSample));
}
//
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Creates the main window.
//
// COMMENTS: N/A
//
//
BOOL InitInstance(
HINSTANCE hInstance,
int nCmdShow)
{
HWND hWndMain;
hWndMain = CreateWindow(
TEXT("SampleWClass"),
TEXT("Install Driver"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
/* If window could not be created, return "failure" */
if (!hWndMain)
return (FALSE);
/* Make the window visible; update its client area; and return "success" */
ShowWindow(hWndMain, SW_MINIMIZE);
UpdateWindow(hWndMain);
return (TRUE);
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
g_InstallInfo.hInst = hInstance;
// if the initialization fails, return.
if (!InitApplication(hInstance))
return (FALSE);
// Perform initializations that apply to a specific instance
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
// Acquire and dispatch messages until a WM_QUIT message is received.
while (GetMessage(&msg, NULL, 0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}
void InstallFinish(BOOL DoRunOnce)
{
HKEY hKey, hSetupKey;
DWORD Error;
LONG l;
//
// First, open the key "HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce"
//
if((l = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REGSTR_PATH_RUNONCE,
0, KEY_ALL_ACCESS, &hKey)) != ERROR_SUCCESS) {
return;
}
//
// If we need to run the runonce exe for the setup key...
//
if(RegOpenKeyEx(hKey,
TEXT("Setup"),
0,
KEY_READ,
&hSetupKey) == ERROR_SUCCESS) {
//
// We don't need the key--we just needed to check its existence.
//
RegCloseKey(hSetupKey);
//
// Add the runonce value.
//
Error = (DWORD)RegSetValueEx(hKey,
TEXT("Wrapper"),
0,
REG_SZ,
(BYTE *)TEXT("runonce"),
sizeof(TEXT("runonce"))
);
} else {
//
// We're OK so far.
//
Error = NO_ERROR;
}
//
// GroupConv is always run.
//
if(RegSetValueEx(hKey,
TEXT("GrpConv"),
0,
REG_SZ,
(BYTE *)TEXT("grpconv -o"),
sizeof(TEXT("grpconv -o"))) != ERROR_SUCCESS) {
//
// Since GrpConv is always run, consider it a more serious error than any error
// encountered when setting 'runonce'. (This decision is rather arbitrary, but
// in practice, it should never make any difference. Once we get the registry key
// opened, there's no reason either of these calls to RegSetValueEx should fail.)
//
Error = (DWORD)l;
}
RegCloseKey(hKey);
if(DoRunOnce) {
WinExec("runonce -r", SW_SHOWNORMAL);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -