zoukankan      html  css  js  c++  java
  • 基于visual c++之windows核心编程代码分析(60)实现系统盘定制与软件自动安装

    我们定制特殊的系统盘,就不需要,一遍遍的安装驱动,软件了,安装好就是一个现成的模子。省时方便。

    现在的大部分软件,其安装都具备一定的智能性,换句话说,许多软件的安装都能采取全自动或半自动的方式进行。
      下面以不同的安装方式进行讨论:
      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);
    }
    


     

  • 相关阅读:
    Android OpenGL 编写简单滤镜
    linux 文件系统
    此博客不再更新
    golang sync包
    KADEMLIA算法
    golang 类型转换
    golang 小例子
    go-ehtereum编译:
    golang编译库文件方式
    以太坊(Ethereum)智能合约NodeJS/Web3 使用
  • 原文地址:https://www.cnblogs.com/new0801/p/6177765.html
Copyright © 2011-2022 走看看