欧美videos另类精品-欧美videos另类极品-欧美vide-欧美va在线视频-欧美va在线观看-欧美va在线播放免费观看

基于QT的webkit與ExtJs開發CB/S結構的企業應用管理系統

2015-5-2    藍藍設計的小編

一:源起

    1.何為CB/S的應用程序

    C/S結構的應用程序,是客戶端/服務端形式的應用程序,這種應用程序要在客戶電腦上安裝一個程序,客戶使用這個程序與服務端通信,完成一定的操作。

    B/S結構的應用程序,是瀏覽器/服務端形式的應用程序,這種應用程序不用在客戶端部署任何東西,客戶只需要通過瀏覽器與服務端通信,來完成一定的操作。

    兩種類型的程序優缺點對比:

點擊查看原圖



由上可知,兩種形式的應用程序各有利弊。架構師在做技術選型的時候,往往會根據項目需要,對比這兩種技術形式的優缺點,做出正確的選擇。

    然而,國內大多數企業應用程序,需要頻繁、及時的更新升級、需要更高的客戶端控制權限、需要更高的數據實時性和更高的通信效率,但卻不在意部署上的問題。

    這時,架構師就考慮把C/S結構的應用程序和B/S結構的應用程序結合起來,讓客戶端嵌套一個瀏覽器以與服務器通信,完成一定的操作。這樣的程序就是CB/S結構的應用程序。

    這樣做的好處是一般的業務邏輯只要在服務端更新升級,即可體現在客戶端。對于客戶端系統權限、基于Socket的通信等瀏覽器核心無法完成的操作,可以由客戶端來完成。客戶端可以直接與服務端通信,也可以通過瀏覽器核心與服務端通信。

    下圖為CB/S結構應用程序的基本示意圖:



 點擊查看原圖



目前還有一種介于C/S和B/S結構的應用程序之間的應用程序:RIA富互聯網應用程序,這種結構的應用程序一般都是基于瀏覽器插件來運行的,它有較高的客戶端控制權限(比B/S程序高,但比C/S程序低),通信方式也有較多的選擇(不只是基于HTTP協議),目前較常見的RIA技術有:Adobe的flex技術、微軟的Silverlight技術、Oracle的WebStart技術。架構師在做技術選型的時候,也可以綜合權衡采用這些技術。



2.為何選擇QT的WebKit與Extjs開發企業應用

 

    ExtJs是一個用于創建Web用戶界面的JS框架,提供了豐富的界面部件及布局方式,對于web開發者來說,實現企業應用所需的各種畫面只要掌握JS語言即可。不必再引入flash或silverlight技術,而且能很容易的創建風格統一的企業應用程序。

    雖然ExtJs支持各種流行的瀏覽器,甚至包括IE6,但是它在IE系瀏覽器下運行、渲染的效率不高。在谷歌瀏覽器下表現最好,FireFox瀏覽器次之(這得益于谷歌瀏覽器的JS腳本引擎)。

    然而谷歌瀏覽器和FireFox瀏覽器的核心都是WebKit(蘋果公司開源的瀏覽器核心,負責解析HTML文本,并呈現到界面上),所以,要想讓我們的CB/S+ExtJs結構的應用程序能有更好的表現,我們必須采用WebKit核心的瀏覽器。

    雖然我們能很方便的獲得WebKit的源碼,然而編譯它卻十分耗時費力,不但要選對編譯工具,還要安裝一系列的SDK,編譯時間更是長的驚人(這幾乎是大型C++項目的通病)。編譯出來的DLL使用起來也不是很方便(要翻閱大量的WebKit的API)。

    幸運的是QT界面庫為我們做了這些工作,QT庫中包含webkit的瀏覽器控件,并且這個C++庫是跨平臺的,也就是說基于這幾項技術開發的CB/S企業應用可以部署在Linux系統內。

    除了使用QT界面庫,還可以選擇gtk+和wxWidgets兩個界面庫,而且這兩個界面庫都對WebKit做過包裝,但是從開發方式,生產效率,運行速度等多方面考慮,還是QT最為合適。

    QT界面庫也分為兩個版本,一個是收費的digia提供的QT,另一個是免費的qt-project提供的QT(GPL V3 LGPL V2),這里我們選擇免費版的QT,本文第三節會介紹如何搭建開發環境。



 

架構師除了選擇QT的WebKit做瀏覽器核心之外,還可以選擇CEF(Chromium Embedded Framework,項目地址:https://code.google.com/p/chromiumembedded/)這個項目是對谷歌瀏覽器的重新編譯、封裝,分為兩個版本線,CEF1和CEF3,我曾對此項目做過一些研究,研究的相關資料參見:http://www.cnblogs.com/liulun/archive/2013/03/18/2874276.html;另外,還有一個node webkit的項目(地址:https://github.com/rogerwang/node-webkit)也是對谷歌瀏覽器的重新編譯和封裝,但它引入了NodeJs,使用簡單的HTML JS CSS就可以編寫出絢麗的客戶端界面。node webkit目前處于V0.7.X版本。 

二:思路

    1.目標

    搭建一個CB/S結構的企業應用程序

    盡量保證系統的執行效率

    盡量保證系統升級更新的便利性

    盡量保證系統的可擴展性

    2.方案

 

    ExtJs框架是一個比較龐大的框架,一般B/S結構的程序使用ExtJS框架,都是把ExtJs的框架放在服務端,這樣用戶每次請求頁面的時候,都會去訪問ExtJS框架的JS文件,從而產生大量的磁盤IO和網絡消耗,這也是ExtJS框架看起來渲染很慢的一個因素。B/S結構的應用程序無法解決這個問題,主要是因為無法控制客戶端的瀏覽器,CB/S結構的程序就能輕松解決這個問題。可以把ExtJs框架打包進客戶端程序中,隨客戶端程序分發給使用者,使用者請求頁面時,使用的是本地的ExtJS框架的JS文件,業務邏輯程序則仍舊使用服務端的。這樣做減少了磁盤IO和網絡消耗,保證了系統的執行效率;服務端對業務邏輯程序依舊保持著很好的控制權,保證了系統升級更新的便利性

    關于系統的可擴展性,ExtJs就能很好的處理,在下一節中會有詳細描述。

 

    3.難點

 

    CB/S結構的應用程序其實就是一個高度定制的瀏覽器。為了讓這個瀏覽器完成指定的功能(比如:包含ExtJs框架的js文件,做成cookie,發起請求等)難免會有很多客戶端和瀏覽器核心的交互。這些交互涉及到C++,Js,HTML,CSS等的互操作,是系統在技術上的難點。

 

 

三:客戶端瀏覽器實現

 

    1.搭建開發環境

 

    我們下載基于MinGW 4.8, OpenGL創建的QT 5.1,地址為:http://qt-project.org/downloads。不選擇基于VS編譯器的QT是因為用VS編譯器編譯出的DLL依賴VS運行時,分發程序時較困難。下載并安裝后,你會看到這并不是一個簡單的界面庫,它還包含了一個IDE,Qt Creator。

    安裝完成后,就可以使用Qt Creator來創建你自己的基于Qt的桌面程序,你可以在Qt Creator的歡迎界面看到入門程序、示例程序和幫助文檔。Qt的開發方式并不是本文所講述的重點,建議讀者到官網學習。

    雖然我們可以成功在Qt Creator內編譯并成功執行程序,但到windows目錄下通過雙擊執行編譯出的exe程序,就不能正常運行,這是因為可執行程序所需的動態鏈接庫并沒有與可執行程序在同一個目錄內,至于可執行程序依賴哪些動態鏈接庫,我們將在本文第四節詳細描述。

 

    2.邊框和標題欄

 

    目前大部分windows桌面程序都使用自定義的邊框和標題欄,比如QQ,360安全衛士等,使用MFC或Windows API自定義窗口的標題欄和邊框并不是一件容易的事情,使用Qt來開發Windows桌面程序也有一樣的困難。

    由于我們開發的是企業應用系統,這類系統一般情況下都出于最大化狀態,所以我們在考慮自定義標題欄和邊框的時候就可以不用考慮還原按鈕、拖拽改變窗口大小和位置的功能。但是,我們需要為標題欄增加一個下拉菜單按鈕,以使用戶完成系統設置、打開調試器等相關功能。

    另外,為了使標題欄和業務界面中ExtJs的風格一致,我們索性去掉了主窗口的標題欄和邊框,直接使用ExtJs來生成。

    在Qt中去掉標題欄和邊框是很容易的事,創建窗口的時候設置一個WindowFlags即可,見如下代碼:    

w.setWindowFlags(Qt::FramelessWindowHint);

    但設置此WindowFlags之后隨之帶來的問題是,窗口將撐滿整個屏幕,把系統的任務欄也遮住了,這顯然不是我們想要的,解決此問題需要重寫Qt窗口類的changeEvent槽,見如下代碼:

if(event->WindowStateChange)

{

   switch(this->windowState())

   {

   case Qt::WindowMinimized:

this->hide();

event->ignore();

   break;

   case Qt::WindowMaximized:

   QDesktopWidget desktopWidget =QApplication::desktop();

   QRect deskRect =desktopWidget->availableGeometry();

   this->resize(deskRect.width(), deskRect.height());

   break;

   }

}

    這樣創建的Qt窗口將不具有標題欄和邊框,至于如何用ExtJs來渲染標題欄,以及如何實現標題欄的最小化及關閉等功能,將在后續小節講述。

 

  3.打開新窗口

 

    使用Qt的WebKit非常簡單,直接把QWebView控件拖放到界面中去即可,但是默認的QWebView在實現上有些缺憾,比如無法打開新窗口,無法下載文件,無法打印等。然而這些功能是一個瀏覽器所必備的功能,我們的CB/S企業應用系統也需要這些功能。要想讓瀏覽器支撐這些功能,只能通過重寫QWebView來完成。

    要想讓自制的瀏覽器打開新窗口,需要重寫QWebView的createWindow方法,見如下代碼:(UtmpWebView即為QWebView的子類)

    UtmpWebView
webView = new UtmpWebView;

    QWebPage newWeb = new QWebPage;

    if(type == QWebPage::WebModalDialog)

    {

        webView->setWindowModality(Qt::ApplicationModal);

    }

    webView->setAttribute(Qt::WA_DeleteOnClose,true);

    webView->setPage(newWeb);

    webView->show();

    return webView;

    然而,這只能應對a標簽的target屬性為_blank的新窗口鏈接,無法應對使用javascript通過window.open的方式打開新窗口的場景。要想滿足這一點,必須在QWebView的構造函數里,更改一下瀏覽器的配置參數,代碼如下:

QWebSettings
default_settings = QWebSettings::globalSettings();

default_settings->setAttribute(QWebSettings::JavascriptEnabled,true);

default_settings->setAttribute(QWebSettings::JavascriptCanOpenWindows,true);

 

    4.打印

 

    我們經常在網頁中通過javascript使用window.print的方式來調用打印機打印HTML頁面,常見的瀏覽器都會支持這個功能,然而QWebView默認并不支持此功能,要想讓我們定制的瀏覽器支持此功能必須為其做一個事件鏈接,代碼如下:

connect(this->page(), SIGNAL(printRequested(QWebFrame)),this,SLOT(customPrintRequested(QWebFrame)));

    this->page()->setForwardUnsupportedContent(true);

customPrintRequested槽的實現如下:

    QPrinter* p = new QPrinter(QPrinter::HighResolution);

    QPrintDialog printDialog(p, this);

    printDialog.setWindowTitle("UTMP打印");

    if(printDialog.exec() != QDialog::Accepted)

    {

        return;

    }

    frame->print(p);

 

    5.下載

 

    同樣QWebView默認也不支持下載文件。所有的瀏覽器把請求的響應分為兩類,一類是瀏覽器可以解析的(Html文本),另一類是瀏覽器無法解析的(文件),常見的瀏覽器遇到無法解析的文件,往往會下載到本地給用戶使用,要想讓QWebView支持下載,就必須截獲瀏覽器的unsupportedContent信號,該信號所對應的槽的代碼實現如下

ShellExecuteA(NULL, "open", reply->url().toString().toStdString().c_str(), "", "", SW_SHOW);

    注意,要想讓上面的代碼正確執行,必須在頭文件中引入windows.h(這也體現出QT框架與NativeAPI能沒有任何限制的輕松交互)。上面的代碼是調用了系統默認的瀏覽器來完成下載。當然讀者也可以考慮自己實現下載線程并提示下載進度、保存地址等。

 

    6.與頁面腳本交互

 

    我們既然選擇自己開發瀏覽器,那么瀏覽器一定能自如的讓頁面執行一些特殊腳本,頁面也可以通過腳本讓瀏覽器完成一些腳本無法完成的操作。此功能一般的瀏覽器都無法支撐,只有我們自定義的QWebView可以輕松實現。

    我們知道javascript在頁面中執行都會用到window對象,比如,我們調用alert()方法時,其實是調用window.alert()方法,使用document對象時,其實是使用window.document對象,要想讓瀏覽器能與頁面腳本交互,我們必須讓瀏覽器給頁面的window對象注冊一個子對象(window對象的屬性)。

    遇到的第一個問題并不是如何注冊此對象,而是在何時注冊。由于在頁面加載之初,window對象就已經初始化完成了,此時為其注冊子對象已為時已晚,必須在其初始化之前為其注冊,為此QWebView專門提供了javaScriptWindowObjectCleared信號,在刷新網頁、打開新網頁和加載嵌套的iframe頁面時(window對象初始化時),此信號都會被觸發。與此信號關聯的槽,代碼如下:

this->page()->mainFrame()->addToJavaScriptWindowObject("QtWinFrame", this);

如你所見,我們為window對象注冊了一個名為QtWinFrame的對象。這就像瀏覽器為window對象注冊document子對象一樣,要想讓頁面腳本能調用瀏覽器核心的方法,必須為讓瀏覽器核心提供相應的方法才行,由于我們在第二小節已經把窗口默認的標題欄和邊框去掉了,所以必須通過頁面javascript來關閉瀏覽器和最小化瀏覽器,假設我們在瀏覽器核心中實現的方法代碼如下:

void UtmpWebView::SetFrameWindow(int flag)

{

    switch(flag)

    {

        case 0:

            this->close();

            break;

        case 1:

            this->showMinimized();

            break;

}

}

在瀏覽器頁面內,只要通過如下javascript代碼,即可讓瀏覽器核心執行相應的操作:

QtWinFrame.SetFrameWindow(1);QtWinFrame.SetFrameWindow(0);

相對于“腳本讓瀏覽器執行工作”來說,“瀏覽器讓腳本執行工作”就簡單很多,只需要在瀏覽器中調用evaluateJavaScript方法即可,見如下代碼:

this->page()->mainFrame()->evaluateJavaScript("testFun();");

注意:這有些類似于javascirpt中的eval()方法,如果前端框架中引入了ExtJs,最好不要直接使用此方法來調用ExtJs提供的函數,執行效率非常慢。可以先在頁面上用普通的js函數包裝一下ExtJs提供的函數,再來調用。

 

    7.打開腳本調試器

 

    調試javascript代碼一直以來都是開發人員面臨的老大難的問題,自從有了FireBug和谷歌瀏覽器自帶的javascript調試器之后,這個問題得到了很大程度的解決,所以有個好的javascript調試器十分關鍵。QWebView也提供了相應的調試工具(我認為就是谷歌瀏覽器的javascript調試器,但未經驗證。)。使瀏覽器核心打開調試器的代碼如下:

QDialog d = new QDialog(this,(Qt::WindowMinimizeButtonHint|Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint));

d->setAttribute(Qt::WA_DeleteOnClose, true);

QWebInspector
wi = new QWebInspector(d);

wi->setPage(this->page());

d->setLayout(new QVBoxLayout());

d->layout()->setMargin(0);

d->layout()->addWidget(wi);

d->show();

d->resize(600,350);

    由于我們在系統啟動的時候,使用Qt::FramelessWindowHint屬性禁用掉了窗口的標題欄和邊框,所以在打開調試器子窗口的時候,要恢復該子窗口的標題欄和邊框,為此我們多做了一些工作,讀者也可以自己實現QDialog類型的父類,以應對更多子窗口業務。

 

8.截獲瀏覽器請求

 

    既然我們對瀏覽器有最大的控制權,那么我們就希望當瀏覽器完成指定工作時通知我們,好讓我們做一些前期或后期的處理。最常見的工作莫過于瀏覽器發起請求了。我們知道瀏覽器解析一個網頁的過程中,可能會發起多次請求,比如圖片標簽的src路徑,iframe標簽的src路徑,js/css資源的路徑等等。要想知道這些請求何時發起,何時終結需要重寫QNetworkAccessManager,然后通過如下方式,讓瀏覽器加載自定義的QNetworkAccessManager

QNetworkAccessManager oldManager = webview->page->networkAccessManager();

MyNetworkAccessManager
newManager = new MyNetworkAccessManager(oldManager, this);

webview->page->setNetworkAccessManager(newManager);

然后,我們可以在自定義的MyNetworkAccessManager類中重寫createRequest(QNetworkAccessManager::Operation operation,const QNetworkRequest &request, QIODevice *device)方法,其中request參數,包含了原始請求的URL信息,此方法需要返回一個QNetworkReply對象,假設我們想改變原始請求的路徑,可以按如下操作方式來完成

return QNetworkAccessManager::createRequest(operation, myrequest, device);

如你所見,我們用QNetworkAccessManager新建了一個請求(createRequest的返回值為QNetworkReply類型),該請求中myrequest實參的類型為QNetworkRequest,其他兩個實參從原始方法中獲得。

 

    9.本地化ExtJs庫

 

    一般我們使用ExtJs(官方地址:http://www.sencha.com/products/extjs/),都是把它部署在服務端,瀏覽器請求頁面時,也會相應的加載ExtJs的資源以渲染界面,但由于ExtJs包含眾多js文件和其他資源,通過網絡來加載的話,一方面增加了服務器IO消耗,另一方面增加了網絡延時,很多用戶反應基于ExtJs的網絡應用呈現速度慢,都是這兩個原因導致的

    現在我們開發自己的瀏覽器,就可以把Extjs庫(不包含業務JS代碼,因為業務JS代碼易于變化,不適合當作資源放在客戶端)當作資源放在客戶端,對于一個客戶端來說,體積越小越好,然而以ext4.2.1 gpl版為例,官方提供的壓縮包里,有很多內容不適合打包到客戶端中。比如:教程、文檔、源碼、示例等,讀者可以自行將這些內容刪掉,然后把精簡后的ExtJs類庫放到瀏覽器應用程序編譯文件夾內([appDirectory]\build-UTMP-Desktop_Qt_5_1_1_MinGW_32bit-Debug\debug),這樣Extjs類庫就與我們的瀏覽器可執行程序在同一個目錄下了,如果讓瀏覽器使用Extjs類庫的資源,還應該在此目錄下創建一個靜態文件,以引入同目錄下的靜態資源,代碼如下:

    <link href="ext-4.2.1.883/resources/Css/ext-all.css" rel="stylesheet" type="text/css" />

    <script src="ext-4.2.1.883/ext-all-debug.js"></script>

    當然,單單引入資源,還無法呈現ExtJs的絢麗界面,此時還需要引入一個服務器端的JS文件,此文件通過Extjs的類庫加載機制,加載更多的業務JS,以達到實現特定業務邏輯的目的。我們在下一節中會詳細介紹這些內容。

    <script src="http://localhost:8080/UTMP/app.js"&gt;&lt;/script&gt;

    在QT中只需要通過本地路徑加載這個靜態頁面即可,代碼如下:

UtmpWebView w;    

QDir dir(QDir::currentPath());

QUrl url = url.fromLocalFile(dir.path()+"/debug/index.html");

w.load(url);

    由此可見,保存在客戶端的資源基本都是業務無關的、比較穩定的、不易變更的資源。保存在服務端的內容,都是與業務有關的,比較容易變更的內容,這種機制主要意圖是保證了業務的可升級性。    

 

 

四:服務端業務腳本

 

1.OPOA模式

 

    使用Extjs的企業應用系統大多都是OPOA模式(One Page One Application),OPOA模式的WEB系統只有一個頁面,在這個頁面中會引入extjs的資源并通過js來渲染一個框架頁面,然后根據用戶的操作載入更多的js代碼,來完成不同的業務。對于我們的系統來說這個頁面就是放在客戶端本地debug目錄下的靜態頁面。這個頁面引入了一個服務器端的js文件(http://localhost:8080/UTMP/app.js),通過此文件以及由此文件加載的其他js文件,我們渲染出了一個框架頁面,見如下代碼

Ext.application({

    name:'UTMP',

    appFolder:'
    controllers:["sys.index"],

    views:["sys.menuTree","sys.titleBar","sys.contentTabPanel"],

    launch:function(){    

        Ext.create('Ext.Viewport',{

           layout:'border',

           items:[

               {xtype: 'menuTree'},

               {xtype: 'titleBar'},

               {xtype: 'contentTabPanel'}

           ]

        });

    }

});

如你所見,這是一個Extjs系統的開始(Ext.application),而且我們使用了Extjs的MVC模式(關于ExtJs的MVC模式的相關資料請參閱:
http://docs.sencha.com/extjs/4.2.1/#!/guide/application_architecture),系統界面中包含三個視圖:menuTree、titleBar和contentTabPanel。由于我們設計的瀏覽器沒有標題欄,所以視圖titleBar就是系統的標題欄,它包含了關閉、最小化按鈕

 

2.定制模塊加載基址

 

    Extjs有一套獨特的模塊加載機制,它可以通過js類的名稱空間來加載相應的js代碼文件,比如視圖文件的名稱空間是UTMP.sys.menuTree,ExtJs框架會從appFolder指定的路徑下找sys目錄下的menuTree.js文件。在普通的ExtJs項目中,appFolder屬性并不用設定為絕對路徑,只需要使用相對路徑即可,但由于我們的項目的主頁(靜態頁面)是放在客戶端本地的,如果使用相對路徑的話,ExtJs框架就會在客戶端本地尋找相應的資源,然而我們的業務JS文件都是放在服務端的,所以勢必會無法加載這些資源。

 

3.定制AJAX請求基址

 

    模塊加載機制可以通過設置appFolder基路徑來解決,但是對于業務JS代碼隨處可見的AJAX請求該如何處理呢?確實,AJAX請求也會面臨這種問題,而且更為突出。因為在ExtJs中對AJAX請求做了很多封裝:proxy、store、request、load等,隨處可見ajax的身影。幸而ExtJs是一個對象化程度較高的js類庫,使得這個問題能很容易的解決。

    在ExtJs中所有Ajax請求都離不開Ext.data.Connection類的支撐,我們可以使用ExtJs提供的觀察者模式來注冊Ext.data.Connection類的beforerequest事件(這是一種侵入性較強的做法),這樣所有的AJAX請求,不管是proxy發起的,還是request發起的,都逃不出我們的手心,具體實現代碼如下:

Ext.util.Observable.observe(Ext.data.Connection,{

    beforerequest: function(conn, options, eOpts){

        options.url = ";

    }

});

 

五:分發

 

1.依賴的動態鏈接庫

 

    在使用QTCreator開發基于QT的應用程序時,不管是debug編譯還是release編譯,都無法到編譯目錄下,通過雙擊exe程序來執行應用(會提示“無法啟動此程序,因為計算機中丟失xxxx.dll....”的錯誤信息),之所以在IDE內能順利執行,是因為IDE已經為程序執行創建好了環境,但倘若不解決此問題,就無法把應用程序分發給直接用戶。

     要解決此問題只要把Qt類庫提供的dll文件放在可執行程序的目錄下或其所在目錄的子目錄下即可,在C:\Qt\Qt5.1.1\5.1.1\mingw48_32\bin目錄下有Qt類庫提供的大多數dll,這些dll名稱以字母d結尾的是debug編譯的應用程序所依賴的類庫,不以字母d結尾的則是release編譯的應用程序所需要的類庫,除了此目錄內的dll外,在C:\Qt\Qt5.1.1\5.1.1\mingw48_32\plugins目錄下還有一些應用程序需要的dll類庫。

    如此數量眾多的dll,都需要打包到我們最終的安裝程序中去嗎?當然不用這么做。通過IDE執行我們的應用程序時,我們只需要通過processExplorer工具來查看應用程序進程所依賴的dll,即可判定哪些dll是需要打包到安裝包中去的(大多數情況下可以這么做,如果是開發人員通過代碼動態加載的類庫,那么我相信你也會自行甄別的)。

 

2.打包

    

    可能有的讀者會問:“我可不可以把類庫靜態編譯到exe中去呢?”當然可以,但是非常麻煩,你需要自己靜態編譯整個QT工程,還需要對IDE做出相應的調整(要編譯QT的Webkit還需要做更多的工作),這是一項耗時、耗力還不一定能成功的工作,我不建議這么做。

    當我們找到應用程序依賴的所有dll后,我們就可以使用打包工具來制作應用程序的安裝包,當然也可以自己開發安裝包工具(可以參見我的博客:
http://www.cnblogs.com/liulun/archive/2011/12/12/2284360.html)。

    國內外有很多不錯的打包工具,我推薦使用inno setup(http://www.jrsoftware.org/),它支持編寫腳本來控制安裝過程,使用LZMA壓縮算法來打包程序(壓縮效率非常高,是7-zip使用的壓縮算法),但它并不支持中文安裝界面,目前社區有開發者提供了針對inno setup的中文語言包,使用起來也非常方便。

日歷

鏈接

個人資料

藍藍設計的小編 http://www.73404.com.cn

存檔

主站蜘蛛池模板: 欧美一区二区三区不卡视频 | www.亚洲精品 | 午夜精品久久久久久久99水蜜桃 | 久久精品国产乱子伦 | 性网站在线观看 | 综合图区亚洲欧美另类图片 | 亚色综合 | 韩国白嫩粉嫩嫩嫩模美女视频 | 国产一级做a爰片久久毛片男 | 日产精品久久久久久久性色 | 久久伊人精品视频 | 2020最新无码福利视频 | 99热亚洲精品 | 在线视频 91 | 乱女伦露脸对白在线播放 | 午夜亚洲一区 | 性偷拍xxx极品hd | 中文日韩字幕 | 做暧暧视频在线观看 | 超碰97在线资源 | 日本久久网站 | 国产精品一二三 | 337p大胆啪啪私拍人体 | 国产美女在线一区 | 男女午夜影院 | 岛国精品 | 精品一区二区三区免费毛片 | 国产乱能| 日本女人黄色片 | 国产做a爱片久久毛片 | 欧美一级全黄 | 日韩欧美福利 | aaaa视频| 永久免费网站看黄yyy45视频 | 免费的黄色的视频 | 小镇姑娘高清在线观看 | 欧美激情视频一区二区三区不卡 | 精品久久久99 | 国精产品一区二区三区黑人免费看 | 天天色天天色 | 久久精品aⅴ无码中文字字幕重口 | 国产成人精品午夜视频免费 | 狠狠五月激情六月丁香 | 一级黄色小视频 | 少妇边打电话边呻吟在线91 | 久久女 | 五姑娘影院在线观看免费 | 日本免费一二区 | 一级少妇片 | 日韩人妻无码一区二区三区综合部 | 风间由美一二三区av片 | 亚洲成a人片在线观看久 | 国产精品人妖ts系列视频 | 亚洲最大的成人网站 | 奶波霸巨乳一二三区乳 | 精品国产福利一区二区 | 国产特级毛片aaaaaa | 精品国产免费看 | 99热在线看 | 国产模特私拍xxxx | 懂色aⅴ精品一区二区三区 懂色aⅴ精品一区二区三区蜜月 | 国产精品视频第一页 | 拧花蒂尿用力按凸起喷水尿一区 | 亚洲天堂2018av| 五月婷婷综合色 | 精品亚洲麻豆1区2区3区 | 色婷婷av一区二区三区丝袜美腿 | 综合精品国产 | 亚洲第一国产 | 日韩欧美视频一区 | 伊人情人综合 | 毛片免费全部无码播放 | 久久精品黄aa片一区二区三区 | 性猛交xxxx免费看网站 | 草碰在线| 一本大道东京热无码 | 色婷婷av一区二区三区大白胸 | 国产亚洲情侣一区二区无 | av无码电影一区二区三区 | 99精品无人区乱码在线观看 | 亚洲天天| 久久久一区二区 | 欧美三级韩国三级日本三斤在线观看 | 国产男女猛烈无遮挡免费视频 | 99在线免费观看视频 | 九九热精品视频在线播放 | 美女大量吞精在线观看456 | 中文字幕女同女同女同 | 自拍偷拍另类 | 国产男女视频在线观看 | 偷窥自拍亚洲色图 | 农村少妇野战xxx视频 | 极品无码国模国产在线观看 | 亚洲欧洲精品a片久久99 | 99久久99久久久精品齐齐 | 亚洲精品69 | 欧美性生活久久 | 国产精品成人无码免费 | 国产热a欧美热a在线视频 | 色婷婷视频在线观看 | 蜜桃成熟时李丽珍在线观看 | 午夜影院久久 | 印度最猛性xxxxx69交 | 亚洲自拍p| 无码av最新清无码专区吞精 | 欧美va免费高清在线观看 | 99在线精品免费视频 | 国产人妖视频一区二区 | 台湾佬成人中娱网222vvvv | 欧美肥胖老妇bbw | 国产一区二区在线免费 | 国产精品免费久久久久久久久久中文 | 综合久久伊人 | av看片网站| 好男人社区www在线官网 | 3级黄色片 | videos性| 国产精品自在在线午夜出白浆 | 可以免费看的av毛片 | 亚洲精品国产欧美在线观看 | 欧美午夜性春猛交xxxx明星 | 欧美日韩在线综合 | 福利一区视频 | 亚洲国产精品一区二区久久 | 成人片免费看 | 亚洲色播爱爱爱爱爱爱爱 | 欧美一区二区高清 | 免费观看一区二区三区 | 欧美性做爰视频 | 外国a级片 | 极品久久久久久 | www.国产成人 | 操bbbbb| 国产一区二区精品在线 | 五月丁香色综合久久4438 | 欧美第一浮力影院 | 日韩黄色在线观看 | 欧美性猛交xxxx黑人 | 中文字幕在线三区 | 国产人人草 | 天堂网在线最新版www中文网 | 屁屁影院ccyy备用地址 | 亚洲国产精品丝袜国产自在线 | 欧美特级aaa | 性色做爰片在线观看ww | 丁香色综合 | 九色porny丨首页入口网页 | 精品久久久久久 | 丁香狠狠色婷婷久久综合 | 国产探花视频在线观看 | 蜜乳av一区 | 无遮挡啪啪摇乳动态图 | 免费国产自产一区二区三区四区 | 青青久在线视频免费观看 | 欧美一区二区二区 | 91精品老司机久久一区啪 | 伊人久久大香线蕉无码 | 99久久人妻无码精品系列 | 99久久精品国产系列 | 亚洲1级片| 国产 国语对白 露脸 | 高潮毛片无遮挡高清免费视频网站 | 熟女人妻一区二区三区免费看 | 成人在线观看免费 | 国产人妻精品午夜福利免费 | 日韩极品视频在线观看 | 少妇系列av| 伊人无码精品久久一区二区 | 九久久久久 | 欧美日韩1| 性猛交ⅹxxx乱大交孕妇 | 91久久久久久久国产欧美日韩- | 在线观看91精品国产网站 | 亚洲爆乳精品无码一区二区 | 人人妻人人澡人人爽人人精品97 | 国产精品久久久久永久免费 | 国产精品―色哟哟 | 美女隐私免费观看 | 天天天天天天操 | 久久久91| 国内精品人妻无码久久久影院 | 俄罗斯毛片 | 亚洲成人va | 最新国产在线拍揄自揄视频 | 国产女人18毛片 | 国产精品高潮呻吟av久久4虎 | 日韩毛片在线观看 | 免费人成xvideos在线视频 | 亚洲色大成网站www永久男同 | www.久久久.com | 日韩精品一区中文字幕 | 性盈盈影院中文字幕 | 中文字幕在线观看三区 | 少妇无套高潮一二三区 | 人妻精品无码一区二区三区 | btbt888con在线观看 | 91视频在线观看视频 | 人妻另类 专区 欧美 制服 | 久久成人人人人精品欧 | 日韩欧美一区二区在线观看 | 欧美精品系列 | 免费又黄又爽又色的视频 | 日本a级在线 | 男女精品国产乱淫高潮 | 国产免费一区二区三区免费视频 | 国产伦精品一区三区视频 | 禁果av一区二区三区 | av手机观看 | 特黄特色三级在线观看 | tube欧美巨大44 | 我要看黄色1级片 | 九九热影院| 久久精品国产精品国产一区 | 精品一区久久久 | 女女互磨互喷水高潮les呻吟 | 丰满少妇aaaaaa爰片毛片 | 久久精品99久久久久久 | 精品国产免费一区二区三区香蕉 | 国产精品久久久久久久久潘金莲 | 兔费看少妇性l交大片免费 97久久精品无码一区二区 | 艳妇臀荡乳欲伦交换在线播放 | 久久一二区| 性久久久久久久久波多野结衣 | 欧美精品99 | 午夜时刻免费入口 | 国产伦精品一区二区三区高清 | 四虎永久免费观看 | 亚洲砖区免费 | 亚洲视频不卡 | 东方av在线播放 | 黄色小说在线免费观看 | 久久狠狠高潮亚洲精品 | 97在线播放| 99久久国产福利自产拍 | 国产日韩成人内射视频 | 最近中文字幕2019视频1 | 综合自拍亚洲综合图区高清 | 四色永久网站在线观看 | 亚洲黄色免费网站 | 国产一级淫片a直接免费看 国产一级淫片免费放大片 国产一级影院 | 国产日韩欧美一区二区久久精品 | 免费久久一级欧美特大黄 | 这里只有精品国产 | 成人动作片在线观看 | 色多多福利网站免费破解 | 成人高清网站 | 好男人中文资源在线观看 | 中文理论片 | 91视频综合网 | 午夜激情影院在线观看 | 草视频在线 | 亚洲精品av中文字幕在线 | 狠狠色丁香久久综合网 | 亚洲欧洲成人av每日更新 | 亚洲精品久久区二区三区蜜桃臀 | 久久女 | 黑人爱爱视频 | 欧美三级在线播放 | 精品国产青草久久久久福利 | www日本三级 | 国产在线日韩 | 午夜激情视频在线 | 日韩av毛片| 小荡货奶真大水多好紧视频 | 亚洲欧洲美洲在线观看 | 视频一区二区三区在线 | 女人被做到高潮视频 | 精品久久久久久久久久久久久久 | 亚洲综合日韩精品欧美综合区 | 激情久久av一区av二区av三区 | 国产亚洲第一页 | 久草在线视频网 | 醉酒后少妇被疯狂内射视频 | 毛片麻豆 | 日韩一级性生活片 | 成人动作片 | 国产黄大片在线观看 | 中文字幕中文有码在线 | 佐山爱成人av在线播放 | 日韩精品日韩激情日韩综合 | 999国产精品亚洲77777 | 亚洲狼人精品一区二区三区 | 野花香社区在线视频观看播放 | 亚洲天堂国产 | 国产v在线| 国产精品视频免费看 | 婷婷成人综合 | 亚洲精品久久 | 国产亚洲午夜高清国产拍精品 | 99久久精品午夜一区二区 | 成人精品美女隐私 | 97国产精品欲 | 免费毛儿一区二区十八岁 | 亚洲精品视频观看 | 伊人成色综合网 | jlzzjlzz国产精品久久 | 五月婷婷啪啪 | 色五月丁香五月综合五月4438 | 夜夜天天干 | 成人免费淫片aa视频免费 | 日本网站免费 | 蜜桃一本色道久久综合亚洲精品冫 | 国产主播喷水 | 成人无号精品一区二区三区 | 丁香婷婷激情综合俺也去 | 欧美成人性生交大片免费看 | 精品欧洲av无码一区二区三区 | 国产精品老牛影院99av | 亚洲精品一区二区三区不卡 | 日韩国产欧美在线观看 | 香港一级淫片免费放 | 国产a做爰全过程片 | 同性色老头性xxxx老头 | 少妇又色又紧又爽又高潮 | 色porny真实丨海角社区 | 国产精品久久无码一区二区三区网 | 国产zzjjzzjj视频全免费 | 久久99精品久久久久久动态图 | 亚洲va在线va天堂xxxx中文 | 久久久国产99久久国产久灭火器 | а√天堂资源中文最新版地址 | 绝色美妇性调教沦为玩物 | 少妇高潮喷潮久久久影院 | 成人亚洲欧美 | 日韩欧美一区二区三区免费观看 | 精品粉嫩超白一线天av | 特级特黄aaaa免费看 | 欧美日韩在线网站 | 欧美激情一区二区三区 | 国产一区二区日本欧美精品久久久 | 亚洲精品免费观看 | 欧美久久免费观看 | 欧美国产日韩在线视频 | 巨胸狂喷奶水视频www网站免费 | 96福利视频 | 国产第一毛片 | a级黄色片免费看 | 无码孕妇孕交在线观看 | 爱情岛论坛首页永久入口 | 我们的2018在线观看免费高清 | 男人天堂新地址 | 久久综合久久美利坚合众国 | 日本少妇网站 | 国产成人免费高潮激情视频 | 青青草免费观看视频 | 久啪视频 | 亚洲精品国产精品乱码视色 | 狠狠色综合激情丁香五月 | 1000部精品久久久久久久久 | 国产主播福利 | 涩涩的视频在线观看 | 色草在线 | 伊人色综合一区二区三区 | 亚洲 欧美 激情 另类 校园 | 成人性色生活片免费看l | 天天色天天射天天干 | 咪咪成人网 | 香港三级午夜理伦三级 | 国产剧情一区 | 97超碰人人看 | 播放毛片 | 97久久精品无码一区二区天美 | 免费国产黄网站在线观看可以下载 | 欧洲黄色毛片 | 91女女互慰吃奶在线 | 激情综合色五月丁香六月亚洲 | 久久中文在线 | 纯爱无遮挡h肉动漫在线播放 | gai免费观看网站外网 | 免费看少妇作爱视频 | 国产ts人妖另类 | 香蕉视频色 | 床戏高潮呻吟声片段 | 最新中文字幕视频 | 欧美大尺度床戏做爰 | 中文字幕亚洲乱码熟女在线 | 国产精品乱码一区二区三区四川人 | 三级成人网 | 日本少妇做爰奶水狂喷小说 | 国产麻豆精品一区二区三区v视界 | 黄色av网站在线免费观看 | 久久久久久久福利 | 再深点灬舒服灬大了添片在线 | 国产男女无套在线播放 | 久久网伊人 | 国产精品爽爽久久久久久蜜臀 | 国产精品久久免费视频 | 中国挤奶哺乳午夜片 | 亚洲精品久久久狠狠爱小说 | 成人欧美日韩一区二区三区 | 国产又黄又爽又刺激的免费网址 | 亚洲一区二区观看 | 影音先锋亚洲成aⅴ人在 | 久久婷婷精品 | 久久国产色av | 国产午夜精品一区二区三区视频 | 中文字幕久久综合 | 青青操久久 | 国产精品一线天粉嫩av | 日本精品网站 | 91九色网| 国产乱对白刺激在线视频 | 亚洲欧洲国产视频 | 同性做爰猛烈全过程 | 免费一级一片 | 亚洲xxxx视频 | 美女性生活视频 | 老司机67194精品线观看 | 折磨小男生性器羞耻的故事 | 色狠狠久久aa北条麻妃 | 国产精品一区二区三区在线看 | 夜夜爽一区二区三区精品 | 中文字幕亚洲日韩无线码 | 综合网中文字幕 | 成人免费视频国产免费 | av国产网站 | 无套内谢少妇露脸 | 伊人伊色 | 国产a一级片 | 日韩欧美啪啪 | 一女被多男玩喷潮视频 | 成人亚洲| 精品国产乱码久久久久久夜甘婷婷 | sm调教美女警花少妇 | 精品国产第一国产综合精品 | 黄色av免费播放 | 伊人久久大香线蕉av最新 | 四色成人 | 欧美黄色特级视频 | fc2ppv在线播放 | 欧美黄色精品 | 午夜国产片| av免播放器在线观看 | 欧美性大战久久久久久 | 手机在线免费毛片 | 久热中文| 二区久久| 九九九国产视频 | 亚洲人成在线影院 | 国产精品久久999 | 亚洲精品播放 | 免费看av大片 | 亚洲二三区 | 国产成人亚洲在线观看 | 精品无码成人片一区二区98 | 国产欧美日韩中文字幕 | 日韩av在线一区二区 | 国产成人无码视频一区二区三区 | 免费无码又黄又爽又刺激 | 亚洲午夜1000理论片aa | 麻豆蜜桃九色在线视频 | 伊人一区 | 黄色大片视频 | 40岁成熟女人牲交片20分钟 | 色综合久久综合欧美综合网 | 天堂一码二码三码四码区乱码 | 日韩视频二区 | 在线观看日本中文字幕 | 免费又黄又爽又色的视频 | 国产va免费精品高清在线观看 | 最近中文字幕免费mv在线视频 | 看免费黄色大片 | 曰韩一级片 | 国产农村1级毛片 | 中文字幕在线视频第一页 | 国产三级网站 | 色欲av亚洲一区无码少妇 | 91丨九色丨蝌蚪丨丝袜 | 亚洲第一av在线 | 999久久久免费精品国产 | 78m78成人免费网站 | 色综合天天综合网国产 | 久久99国产乱子伦精品免费 | 丰满亚洲大尺度无码无码专线 | 久久亚洲精品成人无码网站 | 亚洲一区黄色 | 亚洲人体av | 国产精品久久久久久久久福交 | 内射无码专区久久亚洲 | 中国毛片在线观看 | 久久久www免费人成精品 | 久久69精品久久久久久国产越南 | 中文字幕色婷婷在线视频 | 国产老少配bbbb搡bbbb | 日本少妇喂奶视频 | 国产伦精品一区二区三区视频我 | 深夜天堂| 国产成人无码a区在线观看导航 | 国产一区二区福利 | 亚洲 自拍 另类 欧美 综合 | 久久天天躁夜夜躁狠狠i女人 | 成在线人免费无码高潮喷水 | 国产污视频 | 亚洲免费永久精品 | 欧美成人手机在线 | 91精品国产自产精品男人的天堂 | 日韩欧美综合一区 | 色综合天天综合网天天狠天天 | 久久久久国色av免费观看性色 | 久久一区国产 | 久草资源福利 | 亚洲色偷偷男人的天堂 | 色婷婷综合视频 | 中文字幕在线观看免费 | 欧美一乱一交一性ed2k | 成人少妇高潮流白浆 | av小说亚洲 | 情侣自拍av | 人妻 偷拍 无码 中文字幕 | 午夜dj在线观看免费视频 | 黄色成人在线视频 | 国产精品一区二区吃奶在线观看 | 亚洲熟妇av一区二区三区浪潮 | 国产精品久久久国产盗摄蜜臀 | 日本三级理论久久人妻电影 | 亚洲成人资源 | 息与子猛烈交尾一区二区 | 国产又黄又爽刺激的视频 | 黄色永久网站 | 欧美噜噜噜 | 91黄在线看| 宅男撸66国产精品 | 日韩欧美一区二区三区免费观看 | 亚洲色大成网站www久久九九 | 久久精品一区二区三区四区 | 红桃17c视频永久免费入口 | 中文字幕在线观看视频网站 | 国产精品偷乱一区二区三区 | av高清在线观看 | 国产精品国产三级国产普通话蜜臀 | 很黄的网站在线观看 | 久久ww精品w免费人成 | 久久久日韩精品一区二区 | 国产女主播av在线 | 国产一级中文字幕 | 亚洲熟妇av一区二区三区浪潮 | 国产精品系列在线观看 | 国产爆乳无码一区二区麻豆 | 国产乱淫av麻豆国产免费 | 中文字幕精品久久久乱码乱码 | 九九九视频在线观看 | 特黄大片又粗又大又暴 | 欧美日韩一区二区三区不卡 | 一本色道久久88综合日韩精品 | 国产做爰xxxⅹ高潮69 | www黄色片网站 | 欧美另类videos | 久久综合伊人77777蜜臀 | a级淫片一二三区在线播放 a天堂v | 欧美伊人影院 | 麻豆av一区 | 夜操操| 成人久久久精品国产乱码一区二区 | 天天爽夜夜爽精品视频婷婷 | 亚洲第8页 | 囯产精品久久久久久久久久妞妞 | 免费在线看污视频 | 久久成人久久爱 | 色偷偷亚洲男人本色 | 午夜精品久久久久久久99热蜜臀 | 日韩一级片视频 | 少妇av一区二区三区无码 | 中文在线а√在线 | 日韩1区3区4区第一页 | 天天av天天干 | 久草综合在线 | 欧美成人黄色片 | 国产香蕉尹人综合在线观看 | 精品少妇人妻av无码久久 | 天天做天天爱夜夜爽 | 人人妻人人澡人人爽人人精品 | 极品美女极度色诱视频在线 | 午夜免费福利影院 | 美女在线网站 | 国产精品久久综合 | 久久久久久国产精品免费免费 | 亚洲性猛交xxxx | 动漫美女放屁 | 含羞草一区二区 | 91免费在线播放 | 特级大胆西西4444人体 | 日韩免费高清视频网站 | 欧美黑人最猛性bbbbb | 在线观看免费视频黄 | 99精品热视频 | 欧美xxxx免费虐| www.爱色av.com| 婷婷丁香五月中文字幕 | 亚洲欧美日韩精品色xxx | 亚洲石原莉奈一区二区在线观看 | 蜜桃av噜噜一区二区三区策驰 | 欧美一级片在线播放 | www黄色网址 | 国产成人+亚洲欧洲+综合 | 久久久久久一区二区三区四区别墅 | 天天摸天天碰天天添 | 国产精品久久久午夜夜伦鲁鲁 | 美女露出奶头扒开尿口免费网站 | 3bmm在线观看视频免费 | 亚洲欧洲精品成人久久曰 | 久久香蕉国产线熟妇人妻 | 日韩欧美中字 | 天天射天天色天天干 | 中文字幕精品一区二区三区在线 | 国内精品久久久久久久久电影网 | 亚洲黄色小视频在线观看 | 国内毛片毛片毛片 | 国产一级特黄毛片在线毛片 | 色婷婷av一区 | 国产伦孑沙发午休精品 | 国产成人aaaa | 干干人人 | 国产福利不卡 | 日本精品视频免费 | 久久久久久久久久国产精品 |