今天下載了Z-Blog v1.4的安裝文件,解壓一看只有兩個文件:install.asp和install.dat。本來以為是一個gz或者zip的壓縮文件,將install.dat改變了后綴依然不能解壓,于是引起了我的興趣。
1、先看install.asp文件,發現install.asp文件中對install.dat文件操作方式是objXmlFile。原來install.dat是一個XML文件?
2、用UltraEdit打開install.dat文件,發現果真是XML文件。格式為:
</file><file><path>\atom.css</path><stream xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64">這里是編碼</stream>
在<path>中保存的是路徑
在<stream>中保存的是數據的內容
就是將asp css gif jpg等文件以bin.base64 類型的節點內容存放,現在新版本的word文檔都用這種格式了。
3、可以參考一個技術文檔
因為最近要做的項目中,我要通過XML動態生成窗體,看了UI圖樣,我有些叫苦:我通過XML動態生成窗體,可是主窗體中UI要用圖標來確定要使用的窗體,怎么才能使主窗體的圖標也是動態加載而且圖標和要生成的窗體還有關聯呢?我又想到用XML,查MSDN,看到只有XmlTextWriter 和XmlTextReader里分別有XmlTextWriter.WriteBase64和XmlTextReader.ReadBase64可以操作圖片這種二進制字節的數據。但是XmlTextWriter和XmlTextReader遠不如XmlDocument操作方便,如果用這兩者我就得寫太多的代碼。
困擾了我一天,記得以前看到過一篇文章介紹怎樣將圖片數據存儲到Xml文件,可是怎么也找不到,后來終于在一個英文網站上找到了相關內容,而且還是2003年貼出來的,汗。
好了,不廢話了,我把我的實現代碼貼給大家吧。
private XmlDocument document;
private string FilePath = Application.StartupPath + "\\..\\..\\FormStyle.xml"; // FormStyle.xml 文件地址
private void frmMain_Load(object sender, System.EventArgs e)
{
if(document == null)
{
document = new XmlDocument();
document.Load(FilePath);
}
// 只挑選含有Form的節點
XmlNodeList FormNodes = document.GetElementsByTagName("Form");
lbIcons.BeginUpdate();
lbIcons.Items.Clear();
foreach(XmlNode node in FormNodes)
{
// 把節點的名稱放到下拉列表里
lbIcons.Items.Add(node.Attributes["Name"].Value);
}
lbIcons.EndUpdate();
}
private void lbIcons_SelectedValueChanged(object sender, System.EventArgs e)
{
// 查找下拉框所選的窗體下是否有Image元素,若無則退出
XmlNode node = document.DocumentElement.SelectSingleNode(string.Format("descendant::Form[@Name='{0}']/Image", lbIcons.SelectedItem.ToString()));
if(node == null)
return;
// 如果含有Image元素,就將元素值轉換為Base64String,然后放到內存流
using (MemoryStream mem = new MemoryStream(Convert.FromBase64String(node.InnerText)))
{
// 加載內存流數據為位圖
Bitmap bmp = Bitmap.FromStream(mem) as Bitmap;
pictureBox1.Image = bmp;
}
}
private void btnAdd_Click(object sender, System.EventArgs e)
{
// 如果不存在txtFilePath.Text所指文件,就退出
if(!File.Exists(txtFilePath.Text) || lbIcons.Items.Count == 0)
return;
if(lbIcons.SelectedIndex == -1)
lbIcons.SelectedIndex = 0;
if(document == null)
{
document = new XmlDocument();
document.Load(FilePath);
}
//Read the bitmap.
string data = null;
Bitmap bmp = new Bitmap(txtFilePath.Text);
using (MemoryStream mem = new MemoryStream())
{
bmp.Save(mem, System.Drawing.Imaging.ImageFormat.Bmp);
// 將位圖數據轉換為Base64String放入字符串中
data = Convert.ToBase64String(mem.ToArray());
}
// 查找當前所選的窗體是否含有Image節點,若就新建一個
XmlNode node = document.DocumentElement.SelectSingleNode(string.Format("descendant::Form[@Name='{0}']", lbIcons.SelectedItem.ToString()));
XmlNode ImageNode = document.DocumentElement.SelectSingleNode(string.Format("descendant::Form[@Name='{0}']/Image", lbIcons.SelectedItem.ToString()));
if(ImageNode == null)
{
ImageNode = document.CreateElement("Image");
node.AppendChild(ImageNode);
}
// 將位圖數據保存到XML文檔
ImageNode.InnerText = data;
document.Save(FilePath);
}
4、這種方式制作安裝包是做第一次見到的,有兩個好處:一是可以網絡安裝,不需要上傳幾十個文件,只需要上傳一個安裝文件和一個安裝包即可;二是可以使ASP程序變得更加專業業和商業化,安裝文件構造和修改都很簡單,如果有一個很好的制作數據文件的工具,或許還能制作出來一個像樣的安裝工具來。
5、我所遇到的問題:我的系統是win2000+sp4+.net平臺,在使用安裝程序的過程中發現不能創建目錄,或許是我的系統禁止了某些組件的原因,估計是禁用了fso?不知道。
6、這個安裝方式還有很有研究價值的,先寫一篇日志記錄一下。下班。

