1. 程式人生 > >編寫NSIS外掛輸出安裝過程的日誌

編寫NSIS外掛輸出安裝過程的日誌

實現列印安裝過程中的日誌到臨時目錄的檔案中。日誌檔案以年月日為檔名。

static void MakeTempFileName(char* buf, int bufSize)
{
	char TempPath[MAX_PATH] = {0};
	GetTempPathA(MAX_PATH,TempPath);
	StringCbCopyA(buf,bufSize,TempPath);
	char TempName[MAX_PATH] = {0};
	struct tm *local;
	time_t t;
	t = time(NULL);
	local = localtime(&t);
	StringCbPrintfA(TempName,sizeof(TempName),"%d-%d-%d.txt",local->tm_year,local->tm_mon,local->tm_mday);
	StringCbCatA(buf,bufSize,TempName);
}

static FILE* fp = NULL;

extern "C" void __declspec(dllexport)
	Log(HWND hwndParent, 
	int string_size,
	CHAR *variables, 
	stack_t **stacktop,
	extra_parameters *extra)
{
	int iFunctionCode = 0;
	BOOL bValue = FALSE;
	//外掛初始化
	g_hwndParent = hwndParent;
	EXDLL_INIT();
	//獲取NSIS指令碼傳入的引數,檢查有效性
	char sz[4096] = {0};
	memset(sz,0,sizeof(sz));
	struct tm *local;
	time_t t;
	t = time(NULL);
	local = localtime(&t);
	StringCbCopy(sz,sizeof(sz),asctime(local));
	StringCbCat(sz,sizeof(sz),"    ");
	popstring(sz + strlen(sz));
	StringCbCat(sz,sizeof(sz),"\r\n");
	//NSIS會頻繁LoadLibary、FreeLibary。所以下面需要以追加方式寫入。
	if (!fp)
	{
		char szFilePath[MAX_PATH] = {0};
		MakeTempFileName(szFilePath,sizeof(szFilePath));
		fp = fopen(szFilePath,"ab");
		if (!fp)
		{
			return;
		}
	}

	fwrite(sz,1,strlen(sz),fp);
	fflush(fp);//這一句可有可無
}

//這個函式需要在DLL_PROCESS_DETACH時呼叫它以關閉檔案控制代碼。
extern "C" void Uninitialize()
{
	if (fp)
	{
		fclose(fp);
		fp = NULL;
	}
}

DLL被卸掉時儲存檔案,這裡可能被多次呼叫。似乎NSIS每次呼叫一個外掛的函式時都是LoadLibary,用完就FreeLibary
extern void Uninitialize();

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		Uninitialize();
		break;
	}
	return TRUE;
}