Click here to Skip to main content
15,891,846 members
Articles / Desktop Programming / MFC

dotNetInstaller - Setup Bootstrapper for .NET Application

Rate me:
Please Sign up or sign in to vote.
4.96/5 (87 votes)
4 Jan 2004MIT22 min read 1M   2.2K   310  
With this tool the developer can define the application prerequisites and install the correct version of these components in the correct order based on the user operating system type and language, allow the user to download these components from the web or install these components directly.
// dotNetInstallerDlg.cpp : file di implementazione
//

#include "stdafx.h"
#include "dotNetInstaller.h"
#include "dotNetInstallerDlg.h"
#include ".\dotnetinstallerdlg.h"

//user defined include
#include <tchar.h>
#include "XMLite.h"
#include "OsIdentifier.h"
#include "InstallComponentDlg.h"
#include "ConfigFile.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// finestra di dialogo CdotNetInstallerDlg



CdotNetInstallerDlg::CdotNetInstallerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CdotNetInstallerDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CdotNetInstallerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_INSTALL, m_btnInstall);
	DDX_Control(pDX, IDCANCEL, m_btCancel);
	DDX_Control(pDX, IDC_REINSTALL_ALL, m_chkReinstallAll);
	DDX_Control(pDX, IDC_MESSAGE, m_lblMessage);
	DDX_Control(pDX, IDC_COMPONENTS_LIST, m_ListBoxComponents);
	DDX_Control(pDX, IDC_PICTUREBOX, m_PictureBox);
	DDX_Control(pDX, IDC_OPERATING_SYSTEM, m_lblOperatingSystem);
}

BEGIN_MESSAGE_MAP(CdotNetInstallerDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_INSTALL, OnBnClickedInstall)
END_MESSAGE_MAP()


// gestori di messaggi di CdotNetInstallerDlg

BOOL CdotNetInstallerDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Impostare l'icona per questa finestra di dialogo. Il framework non esegue questa operazione automaticamente
	//  se la finestra principale dell'applicazione non � una finestra di dialogo.
	SetIcon(m_hIcon, TRUE);			// Impostare icona grande.
	SetIcon(m_hIcon, FALSE);		// Impostare icona piccola.


	//remove the Run key if exist
	RemoveRegistryRun();

	//determinating operating system
	m_lblOperatingSystem.SetWindowText(DVLib::GetOsVersionString());

	//load xml file
	if (LoadXmlSettings() == false)
	{
		AfxMessageBox("Failed to read configuration file.", MB_OK|MB_ICONSTOP);
		PostQuitMessage(-1);
	}
	else
	{
		this->SetWindowText(m_Settings.dialog_caption);
		m_btCancel.SetWindowText(m_Settings.cancel_caption);
		m_btnInstall.SetWindowText(m_Settings.install_caption);
		m_chkReinstallAll.SetWindowText(m_Settings.reinstallflag_caption);
		m_lblMessage.SetWindowText(m_Settings.dialog_message);

		try
		{
			HBITMAP hBitmap;
			if ( m_Settings.dialog_bitmap.GetLength() > 0 &&
				DVLib::FileExists(m_Settings.dialog_bitmap) )
			{
				hBitmap = DVLib::LoadBitmapFromFile(m_Settings.dialog_bitmap);
			}
			else
			{
				//l'immagine non � inserita come risorsa tipo BITMAP perch� avevo dei problemi poi a chiamare UpdateResource
				// � quindi inserita come risorsa di tipo CUSTOM e letta manualmente
				//hBitmap = LoadBitmap(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDB_BANNER));
				hBitmap = LoadBannerFromResource(AfxGetApp()->m_hInstance);
			}

			m_PictureBox.SetBitmap(hBitmap);
		}
		catch(...)
		{
			//errore nel caricamento dell'immagine
		}

		LoadComponentsList();
	}	

	return TRUE;  // restituisce TRUE a meno che non venga impostato lo stato attivo su un controllo.
}

// Se si aggiunge alla finestra di dialogo un pulsante di riduzione a icona, per trascinare l'icona sar� necessario
//  il codice sottostante. Per le applicazioni MFC che utilizzano il modello documento/vista,
//  questa operazione viene eseguita automaticamente dal framework.

void CdotNetInstallerDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // contesto di periferica per il disegno

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Centrare l'icona nel rettangolo client.
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Disegnare l'icona
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// Il sistema chiama questa funzione per ottenere la visualizzazione del cursore durante il trascinamento
//  della finestra ridotta a icona.
HCURSOR CdotNetInstallerDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

//returns true if the functions sucessfully load the setting m_Setting
bool CdotNetInstallerDlg::LoadXmlSettings(void)
{
	try
	{
		//riferimento standard
		CString l_SettingFile = DVLib::PathCombineCustom(DVLib::GetAppPath(), "configuration.xml");

		if (DVLib::FileExists(l_SettingFile))
			LoadConfigFile(l_SettingFile, m_Settings); //riferimento
		else
			LoadConfigFromResource(AfxGetApp()->m_hInstance, m_Settings);

		return true;
	}
	catch(char * p_Message)
	{
		AfxMessageBox(p_Message, MB_OK|MB_ICONSTOP);
		return false;
	}
	catch(...)
	{
		return false;
	}
}

void CdotNetInstallerDlg::OnBnClickedInstall()
{
	try
	{
		InsertRegistryRun();
		bool l_bRemoveRunOnce = true;

		for (size_t i = 0; i < m_Settings.components.size();i++)
		{
			bool l_retVal = false;
			try
			{
				if (m_chkReinstallAll.GetCheck() == BST_CHECKED || m_Settings.components[i]->IsInstalled() == false)
				{
					if (m_Settings.components[i]->DownloadComponents())
					{
						InstallComponentDlg l_dg;
						l_dg.LoadComponent(&m_Settings, m_Settings.components[i]);
						l_dg.DoModal();
						
						if (l_dg.m_bSkipped) //premuto il tasto cancel
						{
							l_retVal = false;
						}
						else if (m_Settings.components[i]->IsExecuting()) // se l'installazione � ancora attiva non continuo con gli altri componenti ma aggiorno solo la lista e lascio il Run nel registry per fare in modo che al prossimo riavvio venga rilanciato
						{
							l_bRemoveRunOnce = false;
							break; //esco dal for
						}
						else
						{
							DWORD l_ExitCode = m_Settings.components[i]->GetExitCode();
							if (l_ExitCode == ERROR_SUCCESS || l_ExitCode == ERROR_SUCCESS_REBOOT_REQUIRED)
							{
								//se � presente un messaggio di completamento installazione
								CString l_completeMsg = m_Settings.components[i]->installcompletemessage;
								if (l_completeMsg.Trim().GetLength() > 0)
									AfxMessageBox(l_completeMsg, MB_OK|MB_ICONINFORMATION);

								if (m_Settings.components[i]->mustreboot ||
									l_ExitCode == ERROR_SUCCESS_REBOOT_REQUIRED) //se l'installazione ha chiesto di riavviare non continuo con gli altri componenti ma aggiorno solo la lista e lascio il Run nel registry per fare in modo che al prossimo riavvio venga rilanciato
								{
									l_bRemoveRunOnce = false;

									//chiedo di riavviare
									if (AfxMessageBox(m_Settings.reboot_required, MB_YESNO|MB_ICONQUESTION) == IDYES )
										InitiateReboot();

									break; //esco dal for
								}
								else //installazione completata con sucesso
									l_retVal = true;
							}
							else //error restituito dal setup
							{
								l_retVal = false;
							}
						}
					}
					else //download non riuscito
					{
						l_retVal = false;
					}
				}
				else //gi� installato
				{
					l_retVal = true;
				}
			}
			catch(...)
			{
				l_retVal = false;
			}

			if (l_retVal == false)
			{
				CString l_msg;
				l_msg.Format( m_Settings.failed_exec_command_continue, m_Settings.components[i]->description );

				if (AfxMessageBox(l_msg,MB_YESNO, MB_YESNO|MB_ICONEXCLAMATION) == IDNO )
					break;
			}
		}

		if (l_bRemoveRunOnce)
			RemoveRegistryRun();

		if (LoadComponentsList())
		{
			if (m_Settings.installation_completed.Trim().GetLength() > 0)
				AfxMessageBox( m_Settings.installation_completed, MB_OK|MB_ICONINFORMATION);

			OnOK();
		}
	}
	catch(...)
	{
		AfxMessageBox("Failed to install one or more components", MB_OK|MB_ICONSTOP);
	}
}

//restituisce true se risultano installati tutti i componenti
bool CdotNetInstallerDlg::LoadComponentsList(void)
{
	m_ListBoxComponents.ResetContent();

	bool l_AllInstalled = true;
	for (size_t i = 0; i < m_Settings.components.size();i++)
	{
		CString l_descr = m_Settings.components[i]->description;
		if (m_Settings.components[i]->IsInstalled())
		{
			l_descr += " ";
			l_descr += m_Settings.status_installed;

			l_AllInstalled = l_AllInstalled && true;
		}
		else
		{
			l_descr += " ";
			l_descr += m_Settings.status_notinstalled;

			l_AllInstalled = false;
		}
		m_ListBoxComponents.AddString(l_descr);
	}

	return l_AllInstalled;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Software Developer
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions