⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 install.cpp

📁 zip算法的源码
💻 CPP
字号:
#include <vcl\vcl.h>
#pragma hdrstop

#include "Install.h"
#include "Main.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TInstForm *InstForm;
String     EXEName, EXETitle;

//---------------------------------------------------------------------------
__fastcall TInstForm::TInstForm( TComponent *Owner ) : TForm( Owner ) {
}

//---------------------------------------------------------------------------
void __fastcall TInstForm::FormCreate( TObject *Sender ) {
	EXEName  = ExtractFileName( ParamStr( 0 ) );
	EXETitle = "ViewZip - Auto Install Application Example";
	ProgramNameLabel->Caption = ParamStr( 0 );

	StartMenuCB->Checked	= true;
	DesktopCB->Checked	= true;
	SendToCB->Checked		= true;
	RegistryCB->Checked	= true;
	AssocCB->Checked		= true;
	KillCB->Checked		= false;

	if ( MainForm->AutoUnInstall ) {
		ShowMessage( "Now beginning ViewZip auto uninstall" );
		UnInstButClick( this );
	}
}

//---------------------------------------------------------------------------
void __fastcall TInstForm::FormActivate( TObject *Sender ) {
	if ( MainForm->AutoUnInstall )
		PostMessage( Handle, WM_CLOSE, 0, 0 );
}

//---------------------------------------------------------------------------
void __fastcall TInstForm::InstButClick( TObject *Sender ) {
	String path;

   Screen->Cursor = crHourGlass;
	if ( StartMenuCB->Checked ) {
		GetSpecialFolder( (StartMenuRB->Checked) ? CSIDL_STARTMENU : CSIDL_PROGRAMS, path );
		MakeLink( ParamStr( 0 ),	// The full pathname of this executable program.
				"",						// No arguments.
				path + EXETitle + ".lnk",
				"Sample Self-install Program" );
	}
	if ( DesktopCB->Checked ) {
		GetSpecialFolder( CSIDL_DESKTOPDIRECTORY, path );
		MakeLink( ParamStr( 0 ),	// The full pathname of this executable program.
				"",						// No arguments.
				path + EXETitle + ".lnk",
				"Sample Install Program" );
	}
	if ( SendToCB->Checked ) {
		GetSpecialFolder( CSIDL_SENDTO, path );
		MakeLink( ParamStr( 0 ),	// The full pathname of this executable program.
				"",						// No arguments.
				path + EXETitle + ".lnk",
				"Sample Install Program" );
	}
	if ( RegistryCB->Checked ) {
		// Define the application path.
		SetValInReg( HKEY_LOCAL_MACHINE,
					"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" + EXEName,
					"",					// Specify the default data item.
					ParamStr( 0 ) );	// Full pathname with program name.
		path = ExtractFilePath( ParamStr( 0 ) );
		SetValInReg( HKEY_LOCAL_MACHINE,
					"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" + EXEName,
					"Path",				// Specify the Path data item.
					path.SubString( 1, path.Length() - 1 ) );	// Full pathname without end slash.

		// Define the un-install command line.
		SetValInReg( HKEY_LOCAL_MACHINE,
					"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + EXEName,
					"DisplayName",
					EXETitle );			// Show user this name in control panel.
		SetValInReg( HKEY_LOCAL_MACHINE,
					"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + EXEName,
					"UninstallString",
					ParamStr( 0 ) + " /UNINSTALL" ); // Program name and parameter.

		// Define the main application program settings key.
		SetValInReg( HKEY_LOCAL_MACHINE, "SOFTWARE\\" + EXEName, "InstalledVersion", "1.40" );

		// These are settings that only apply to the current logged-in user.
		SetValInReg( HKEY_CURRENT_USER, "SOFTWARE\\" + EXEName, "InstalledVersion", "1.40" );
		SetValInReg( HKEY_CURRENT_USER, "SOFTWARE\\" + EXEName, "Setting1", "y" );
		SetValInReg( HKEY_CURRENT_USER, "SOFTWARE\\" + EXEName, "Setting2", "n" );
	}
	if ( AssocCB->Checked ) MakeAssociation( "zip", ParamStr( 0 ) );

	Screen->Cursor = crDefault;

	if ( KillCB->Checked ) KillMySelf2( 0, false );
	Close();
}

//---------------------------------------------------------------------------
/* Create a Win95 file association in the registry.  This uses the Quick-and-
 * Dirty method used by Explorer when you right click on a file and choose
 * "Open With...".  Basically, the file extension is created as a class, and
 * a dummy file type is created for that class to tell Win95 which program to
 * run.  Once this is done, you can easily test it from a DOS Shell by typing:
 * START FILENAME.EXT
 * Be advised: This is where I expected file associations to be (because
 * there are already some associations there), but they seem to have no effect:
 * HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Extensions"
 */
void __fastcall TInstForm::MakeAssociation( String Ext, String PgmToLinkTo ) {
	// ALL extensions must be in lowercase to avoid trouble!
	Ext = LowerCase( Ext );
	if ( FileExists( PgmToLinkTo ) ) {
		SetValInReg( HKEY_CLASSES_ROOT,
				"." + Ext,					// Extension we want to define.
				"",							// Specify the default data item.
				Ext + "_auto_file" );	// This is the value of the default data item -
												// this references our new type to be defined.
		SetValInReg( HKEY_CLASSES_ROOT,
            Ext + "_auto_file",		// this is the type we want to define
				"",							// Specify the default data item.
				Ext + " Files" );			// This is the value of the default data item -
												// this is the English description of the file type.

		SetValInReg( HKEY_CLASSES_ROOT,
				Ext + "_auto_file\\DefaultIcon",				// Create a file...DefaultIcon.
				"",							// Specify the default data item.
				PgmToLinkTo + ",0");		// Executable where icon is in and it's Sequence number.
		::SHChangeNotify( SHCNE_ASSOCCHANGED, SHCNF_FLUSH	, (void *)NULL, (void *)NULL );

		// SetValInReg( HKEY_CLASSES_ROOT,
		//          Ext + "_auto_file\\QuickView",	 	// Create a key for QuickView compat.
		//          "",					// Specify the default data item.
		//          "*" );				// Flag to tell Explorer that QuickView is OK.
		SetValInReg( HKEY_CLASSES_ROOT,
				Ext + "_auto_file\\shell\\open\\command",	// Create a file...open key.
				"",							// Specify the default data item.
				PgmToLinkTo + " %1");	// Command line to open file with.
	} else
		ShowMessage( "Error: Program not found: " + PgmToLinkTo );
}

//---------------------------------------------------------------------------
void __fastcall TInstForm::RemoveAssociation( String Ext ) {
	Ext = LowerCase( Ext );
	RegDeleteKey( HKEY_CLASSES_ROOT, "." + Ext );	// Extension we want to undefine.
	RegDeleteKey( HKEY_CLASSES_ROOT, Ext + "_auto_file\\DefaultIcon" );
	RegDeleteKey( HKEY_CLASSES_ROOT, Ext + "_auto_file\\shell\\open\\command" );
	RegDeleteKey( HKEY_CLASSES_ROOT, Ext + "_auto_file" );
	::SHChangeNotify( SHCNE_ASSOCCHANGED, SHCNF_FLUSH	, (void *)NULL, (void *)NULL );
}

//---------------------------------------------------------------------------
void __fastcall TInstForm::RegDeleteKey( HKEY RKey, String KeyPath ) {
	TRegistry *rg = new TRegistry();

	rg->RootKey = RKey;	// Set to the 'new' rootkey.
	// Under Win95, all keys under this one are auto. deleted also.
	// But, under WinNT, the keys under this one will be left alone.
	rg->DeleteKey( KeyPath );
	delete rg;
}

//---------------------------------------------------------------------------
/* Set a value in the registry. This is NOT related to the .LNK code.
 * This will create a new registry key if it doesn't already exist. */
void __fastcall TInstForm::SetValInReg( HKEY RKey, String KeyPath, String ValName, String NewVal ) {
	TRegistry *rg = new TRegistry();

	rg->RootKey = RKey;	// Set to the 'new' rootkey.
	rg->OpenKey( KeyPath, true );
	try {
		rg->WriteString( ValName, NewVal );
	} catch ( ... ) { }
	delete rg;
}

//---------------------------------------------------------------------------
/* Make a Shell Link, also called a "shortcut".
 * MakeLink - uses the shell's IShellLink and IPersistFile interfaces
 * to create and store a shortcut to the specified object.
 * Returns the result of calling the member functions of the interfaces.

 * PgmPath  - address of a buffer containing the path of the object.
 * LinkPath - address of a buffer containing the path where the shell link is to be stored.
 * Descr    - address of a buffer containing the description of the shell link.
 * PgmArgs  - address of a buffer containing the arguments for the shell link.
 */
HRESULT __fastcall TInstForm::MakeLink( String PgmPath, String PgmArgs, String LinkPath, String Descr ) {
	IShellLink *ShLink;

	if ( UpperCase( ExtractFileExt( LinkPath ) ) != ".LNK" ) {
		ShowMessage( "Error: link path extension must be .LNK" );
		return 0;
	}
	HRESULT hRes = CoInitialize( NULL );
	if ( hRes == S_OK || hRes == S_FALSE ) {
		if ( hRes == S_OK ) {
			// Get a pointer to the IShellLink interface.
			hRes = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&ShLink );
			if ( SUCCEEDED( hRes ) ) {
				IPersistFile *PFile;

				// Set the path to the shortcut target, and add the description.
				ShLink->SetPath( PgmPath.c_str() );
				ShLink->SetDescription( Descr.c_str() );
				ShLink->SetArguments( PgmArgs.c_str() );
				ShLink->SetIconLocation( PgmPath.c_str(), 0 );
				ShLink->SetWorkingDirectory( ExtractFilePath( PgmPath ).c_str() );


				// Query IShellLink for the IPersistFile interface for saving the
				// shortcut in persistent storage.
				hRes = ShLink->QueryInterface( IID_IPersistFile, (void **)&PFile );
				if ( SUCCEEDED( hRes ) ) {
					WideChar WFileName[MAX_PATH];

					// Ensure that the string is ANSI.
					MultiByteToWideChar( CP_ACP, 0, LinkPath.c_str(), -1, WFileName, MAX_PATH );

					// Save the link by calling IPersistFile::Save.
					PFile->Save( WFileName, false );
					hRes = PFile->SaveCompleted( WFileName );
					PFile->Release();
				}
				ShLink->Release();
			}
		} else ShowMessage( "COM already initialized" );
		CoUninitialize();
	} else 		// E_INVALIDARG, E_OUTOFMEMORY, o E_UNEXPECTED.
		ShowMessage( "COM library could not initialize" );
	return hRes;
}

//---------------------------------------------------------------------------
void __fastcall TInstForm::CancelButClick( TObject *Sender ) {
	Close();
}

//---------------------------------------------------------------------------
void __fastcall TInstForm::UnInstButClick( TObject *Sender ) {
	String path;

	Screen->Cursor = crHourGlass;
	if ( StartMenuCB->Checked ) {
		GetSpecialFolder( (StartMenuRB->Checked) ? CSIDL_STARTMENU : CSIDL_PROGRAMS, path );
		String Temp = path + EXETitle + ".lnk";
		DeleteFile( Temp );
	}
	if ( DesktopCB->Checked ) {
		GetSpecialFolder( CSIDL_DESKTOPDIRECTORY, path );
		String Temp = path + EXETitle + ".lnk";
		DeleteFile( Temp );
	}
	if ( SendToCB->Checked ) {
		GetSpecialFolder( CSIDL_SENDTO, path );
		String Temp = path + EXETitle + ".lnk";
		DeleteFile( Temp );
	}
	if ( RegistryCB->Checked ) {
		RegDeleteKey( HKEY_LOCAL_MACHINE,
					"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" + EXEName );
		RegDeleteKey( HKEY_LOCAL_MACHINE,
					"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + EXEName );
		RegDeleteKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\" + EXEName );
		RegDeleteKey( HKEY_CURRENT_USER, "SOFTWARE\\" + EXEName );
	}

	if ( AssocCB->Checked ) RemoveAssociation( "zip" );

	Screen->Cursor = crDefault;

	/* If we are auto-uninstalling, then we are still in OnCreate,
	 * so we can't close this form yet. */
	if ( !MainForm->AutoUnInstall ) Close();
}

//---------------------------------------------------------------------------
/* Folder types are a.o.
 *	CSIDL_DESKTOPDIRECTORY, CSIDL_STARTMENU, CSIDL_SENDTO,
 * CSIDL_PROGRAMS, CSIDL_STARTUP etc.
 */
long __fastcall TInstForm::GetSpecialFolder( int aFolder, String &Location ) {
	long		   FolderErr = 0;   // No error.
	char		  *RealPath;
	ITEMIDLIST *pidl;
	LPMALLOC    g_pMalloc;

	// Get the shell's allocator.
	if ( ::SHGetMalloc( &g_pMalloc ) == E_FAIL ) return E_FAIL;

	// Allocate a buffer to receive the path information.
	if ( (RealPath = (char *)g_pMalloc->Alloc( MAX_PATH )) != NULL ) {
		HRESULT hRes = ::SHGetSpecialFolderLocation( Handle, aFolder, &pidl );
		if ( hRes == NOERROR ) {
			bool Success = ::SHGetPathFromIDList( pidl, RealPath );
			if ( Success ) {
				Location = RealPath;
				Location += "\\";
			} else FolderErr = E_UNEXPECTED;
			// Free the PIDL allocated by SHGetSpecialFolderLocation.
			g_pMalloc->Free( pidl );
		} else FolderErr = hRes;
		// Free the string buffer used for the name
		g_pMalloc->Free( RealPath );
	} else FolderErr = E_OUTOFMEMORY;
	// Release the shell's allocator.
	g_pMalloc->Release();
	return FolderErr;
}

//---------------------------------------------------------------------------
void __fastcall TInstForm::StartMenuCBClick( TObject *Sender ) {
	StartMenuRB->Enabled = StartMenuCB->Checked;
	ProgramRB->Enabled   = StartMenuCB->Checked;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -