基於visual c++之windows核心編程程式碼分析(60)實現系統硬碟定製與軟體自動安裝

來源:互聯網
上載者:User

我們定製特殊的系統硬碟,就不需要,一遍遍的安裝驅動,軟體了,安裝好就是一個現成的模子。省時方便。

現在的大部分軟體,其安裝都具備一定的智能性,換句話說,許多軟體的安裝都能採取全自動或半自動的方式進行。
  下面以不同的安裝方式進行討論:
  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_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CAboutDlg dialog used for App Aboutclass 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// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_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_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CAddshellDlg dialogCAddshellDlg::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 Win32m_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_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CAddshellDlg message handlersBOOL 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 dialogSetIcon(m_hIcon, TRUE);// Set big iconSetIcon(m_hIcon, FALSE);// Set small icon// TODO: Add extra initialization herereturn 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 paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint 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 icondc.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);}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.