我们定制特殊的系统盘,就不需要,一遍遍的安装驱动,软件了,安装好就是一个现成的模子。省时方便。
现在的大部分软件,其安装都具备一定的智能性,换句话说,许多软件的安装都能采取全自动或半自动的方式进行。
下面以不同的安装方式进行讨论:
1、基于 msi 包的 Windows Installer 安装文件:常用的静默安装参数为 /qb (显示基本安装界面)或 /q 或 /qn,若为了不重新启动,还可以加上 REBOOT=SUPPRESS
如安装虚拟光驱 DaemonTools:msiexec /i dtools.msi /qb REBOOT=SUPPRESS
2、Windows 补丁包:有两种情况,一种是类似 IE 增量补丁包的那种安装文件,要使之静默安装,只需要在执行文件后加上 /q:a /r:n 参数即可;一种是 Windows 常用的补丁文件,一般情况下加上 /U /N /Z 即可实现静默安装(对于新的系统补丁,也可使用 /passive /norestart)。这通用大部分情况,但某些特定的补丁不能用此法进行静默安装。
3、使用 InstallShield 制作的安装文件,可以使用如下命令行运行一遍安装程序并获得静默安装参数文件 setup.iss:
setup.exe -r -f1:c:\setup.iss
然后将此 setup.iss 拷贝到安装文件目录,并执行如下命令即可:setup.exe -s [-sms]
4、InstallShield with MSI 制作的安装文件,请使用类似:setup.exe /s /v"/qb" 来安装
5、Wise InstallMaster 的安装文件,请使用:setup.exe /s
6、Inno Setup 制作的安装文件,请使用:setup.exe /sp- /silent /norestart
7、使用 NSIS (NullSoft Installation System) 制作的安装文件,可用 /S (注意大写)来进行静默安装。示例:setup.exe /S
8、Wise Installation Professional 制作的安装文件,可用 /silent 参数进行静默安装。
反正拿到一个安装程序,大家用各静默安装参数试试就知道了([/s] [/S] [/silent [/noreboot]] [/verysilent [/sp-] [/norestart]] [/q] [/qn] [/qb] [REBOOT=SUPPRESS] [/s /v/qn] [/q:a /r:n] [/u /n /z] [/quiet] [/SilentInstallNoSponsor] [/SilentInstall] [/s /qn] [/s /qd] [-s] [-q] 等)
下面我们基于VC++实现XP的自动安装与软件的自动安装
#include "stdafx.h"
#include "addshell.h"
#include "addshellDlg.h"
#include "Shlwapi.h"
#include "direct.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//全局变量
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAddshellDlg dialog
CAddshellDlg::CAddshellDlg(CWnd* pParent /*=NULL*/)
: CDialog(CAddshellDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CAddshellDlg)
m_FilePathName = _T("");
m_CatalogName = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CAddshellDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAddshellDlg)
DDX_Control(pDX, IDC_RICHEDIT_PROCINFO, m_RichEditProcInfo);
DDX_Text(pDX, IDC_EDIT_FILEPATHNAME, m_FilePathName);
DDX_Text(pDX, IDC_EDIT_CATALOG, m_CatalogName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAddshellDlg, CDialog)
//{{AFX_MSG_MAP(CAddshellDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_OPENFILE, OnButtonOpenfile)
ON_BN_CLICKED(IDC_BUTTON_PACKING, OnButtonPacking)
ON_BN_CLICKED(IDC_BUTTON1, OnButtonOpenCatalog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAddshellDlg message handlers
BOOL CAddshellDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CAddshellDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CAddshellDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
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;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CAddshellDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CAddshellDlg::OnButtonOpenfile()
{
// TODO: Add your control notification handler code here
//设置文件过滤,默认打开哪些文件类型,最后“||”结束。
char szFilter[]="可执行文件(*.exe)|*.exe|全部文件(*.*)|*.*||";
//通过查阅MSDN,了解CFileDialog中构造函数的用法。
//第一个参数为TRUE,表示打开文件对话框;为FALSE,表示保存对话框。
//其他详细参数说明见后面。
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter,NULL);
//通过模态对话框显示文件对话框
if (dlg.DoModal()==IDOK)
{
//获取文件路径
m_FilePathName=dlg.GetPathName();
//设置RICHEDIT内容
//将指针设置到编辑框最后
m_RichEditProcInfo.SetSel(-1,-1);
//替换编辑框最后的内容,实际上就是在最后添加内容。
m_RichEditProcInfo.ReplaceSel("文件路径:");
m_RichEditProcInfo.ReplaceSel(m_FilePathName);
m_RichEditProcInfo.ReplaceSel("\r\n");
//用获取的文件路径更新编辑框内容。
UpdateData(FALSE);
}
}
void CAddshellDlg::OnButtonPacking()
{
//获得当前目录
CString path_directory,path_txt; //path_directory:路径 path_txt:路径+文件名
GetModuleFileName(NULL,path_txt.GetBuffer(MAX_PATH),MAX_PATH); //得到当前执行程序的路径
path_txt.ReleaseBuffer();
int path_directory_length = path_txt.ReverseFind('\\');
path_directory = path_txt.Left(path_directory_length + 1);
//获得WINNT.sif文件路径
char SIFFilePath[255];
strcpy(SIFFilePath,path_directory);
strcat(SIFFilePath,"WINNT.sif");
if (!PathFileExists(SIFFilePath))
{
MessageBox("WINNT.sif不在该程序的目录中","注意",MB_OK);
return;
}
//创建$OEM$\$1\install\目录
char InstallPath[255];
char AppCMDPath[255];
strcpy(InstallPath,m_CatalogName);
strcat(InstallPath,"\\$OEM{1}quot;);
CreateDirectory(InstallPath,NULL);
strcat(InstallPath,"\\$1");
CreateDirectory(InstallPath,NULL);
strcat(InstallPath,"\\install");
CreateDirectory(InstallPath,NULL);
strcpy(AppCMDPath,InstallPath);
strcat(AppCMDPath,"\\applications.cmd");
strcat(InstallPath,"\\applications");
CreateDirectory(InstallPath,NULL);
strcat(InstallPath,"\\RunSoft.exe");
CopyFile(m_FilePathName,InstallPath,FALSE);
if (!PathFileExists(InstallPath))
{
MessageBox("EXE文件拷贝失败","注意",MB_OK);
return;
}
//设置RICHEDIT内容
//将指针设置到编辑框最后
m_RichEditProcInfo.SetSel(-1,-1);
//替换编辑框最后的内容,实际上就是在最后添加内容。
m_RichEditProcInfo.ReplaceSel("可执行文件拷贝完成: ");
m_RichEditProcInfo.ReplaceSel(InstallPath);
m_RichEditProcInfo.ReplaceSel("\r\n");
//用获取的文件路径更新编辑框内容。
UpdateData(FALSE);
//创建applications.cmd文件
FILE *AppCMDFile;
if((AppCMDFile = fopen(AppCMDPath,"wt+")) == NULL) //文本文件,允许读写
{
MessageBox("Applications.cmd文件创建失败","注意",MB_OK);
}
fseek(AppCMDFile,0L,SEEK_SET);
fputs("CLS\r\n",AppCMDFile);
fputs("@echo off\r\n",AppCMDFile);
fputs("start /wait %systemdrive%\\install\\applications\\RunSoft.exe\r\n",AppCMDFile);
fputs("RD /S /Q %systemdrive%\\install\r\n",AppCMDFile);
fputs("EXIT",AppCMDFile);
fclose(AppCMDFile);
//设置RICHEDIT内容
//将指针设置到编辑框最后
m_RichEditProcInfo.SetSel(-1,-1);
//替换编辑框最后的内容,实际上就是在最后添加内容。
m_RichEditProcInfo.ReplaceSel("Applications.cmd文件创建完成: ");
m_RichEditProcInfo.ReplaceSel(AppCMDPath);
m_RichEditProcInfo.ReplaceSel("\r\n");
//用获取的文件路径更新编辑框内容。
UpdateData(FALSE);
//exe文件拷贝完成
//开始拷贝winnt.sif文件
char SIFI386Path[255] ={0};
strcpy(SIFI386Path,m_CatalogName);
strcat(SIFI386Path,"\\I386\\WINNT.sif");
CopyFile(SIFFilePath,SIFI386Path,FALSE);
if (!PathFileExists(SIFI386Path))
{
MessageBox("WINNT.sif文件拷贝失败","注意",MB_OK);
return;
}
//将要运行的文件路径加入WINNT.sif文件
FILE *SIFFile;
if((SIFFile = fopen(SIFI386Path,"at+")) == NULL) //文本文件,允许读和追加
{
MessageBox("WINNT.sif文件追加打开失败","注意",MB_OK);
}
fseek(SIFFile,0L,SEEK_END);
fputs("\r\n",SIFFile);
fputs("[GuiRunOnce]\r\n",SIFFile);
fputs("%systemdrive%\\install\\applications.cmd\r\n",SIFFile);
fclose(SIFFile);
//设置RICHEDIT内容
//将指针设置到编辑框最后
m_RichEditProcInfo.SetSel(-1,-1);
//替换编辑框最后的内容,实际上就是在最后添加内容。
m_RichEditProcInfo.ReplaceSel("WINNT.sif文件设置完成,可以打包");
m_RichEditProcInfo.ReplaceSel("\r\n");
//用获取的文件路径更新编辑框内容。
UpdateData(FALSE);
}
void CAddshellDlg::OnButtonOpenCatalog()
{
char szDir[255];
BROWSEINFO bi;
ITEMIDLIST *pidl;
bi.hwndOwner = this->m_hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = szDir;
bi.lpszTitle = "选择要添加的文件夹";
bi.ulFlags = BIF_RETURNONLYFSDIRS|BIF_DONTGOBELOWDOMAIN;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;
pidl = SHBrowseForFolder(&bi);
if(pidl == NULL) return;
SHGetPathFromIDList(pidl, szDir);
m_CatalogName=szDir;
//判断输入的目录是否存在
if (!PathFileExists(szDir))
{
MessageBox("目录不存在","注意",MB_OK);
return;
}
char I386String[255];
strcpy(I386String,m_CatalogName);
strcat(I386String,"\\i386");
if (!PathFileExists(I386String))
{
MessageBox("I386目录不存在","注意",MB_OK);
return;
}
//设置RICHEDIT内容
//将指针设置到编辑框最后
m_RichEditProcInfo.SetSel(-1,-1);
//替换编辑框最后的内容,实际上就是在最后添加内容。
m_RichEditProcInfo.ReplaceSel("系统文件目录:");
m_RichEditProcInfo.ReplaceSel(m_CatalogName);
m_RichEditProcInfo.ReplaceSel("\r\n");
//用获取的文件路径更新编辑框内容。
UpdateData(FALSE);
}