Thursday, December 11, 2008 - 文章

CODE-定時自動更新的UpdatePanel

雖然上回已明白揭示過UpdatePanel傳輸效率不佳的事實,剛好有同事請我提供網頁部分內容定期自動更新的範例。想了一下,UpdatePanel還是最佳的解決方案,理由是:

    1. 開發人員較少Javascript的開發經驗,但ASPX經驗豐富。
    2. 該網頁使用者人數不多,更新頻率不高(約一分鐘一次)。
    3. 需求很急迫,不是學新東西的好時機,希望使用的技術愈簡單愈易實作愈好。

符合上述條件的技術選項,毋庸置疑,非UpdatePanel莫屬!! (再次證明,"沒有一無是處的技術,只有用錯場合的白目")

我寫了以下的範例,用一個UpdatePanel包住Label1,另外放了一個Timer1,設定一秒Tick一次,至於UpdatePanel,當然就用Timer1的Tick作為觸發事件,更新Label1.Text就寫在Timer1_Tick裡。另外,我設了按鈕可以透過CSS display屬性決定UpdatePanel顯示與否,驗證隱藏時會持續更新。(為求單純化,我連jQuery都沒拉進來)

UpdatePanel With Timer

程式碼如下,給有需要的人參考吧!

<%@ Page Language="C#" %>
<script runat="server">
    protected void Timer1_Tick(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToString();
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <input type="button" value="Show" 
onclick="$get('dvDisp').style.display='block';" />
    <input type="button" value="Hide" 
onclick="$get('dvDisp').style.display='none';" />
    <div id="dvDisp">
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
        </ContentTemplate>
        <Triggers>
        <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
        </Triggers>
        </asp:UpdatePanel>
        <asp:Timer ID="Timer1" runat="server" 
ontick="Timer1_Tick" Interval="1000">
        </asp:Timer>
    </div>
    </form>
</body>
</html>
你DEP了嗎?

阿碼科技非官方網站在日前公告了IE 7 零時差攻擊(Zero Day Attack) 重大威脅警訊,剛剛讀到保哥的文章,提及昨日真的發現有客戶收到Mail,點擊連結就被植入木馬的情事(雖然無法證實是否就是利用該漏洞攻擊),大驚!

零時差攻擊是指軟體被發現有漏洞後,在廠商還來不及出修補更新前,就有人開發針對該漏洞攻擊的病毒、蠕蟲、木馬等惡意程式。由於軟體在修補漏洞前尚無任何防備,惡意程式如入無人之境,得以為所欲為。

聽來挺可怕的,不過光發抖也不是辦法,我們還是要有積極一點的作為。避用IE7是不錯的主意,不過我還是很有興趣了解這波攻擊的原理,面對可疑狀況時,比較能辨別是真的中鏢或另有原因。

Google了一下,發現目前查得到的資料有限,大多指向Knowsec Team的那篇文章,文章裡並沒有提及太多技術細節(也許是基於負責任揭露的原則吧?),不過由其中提到的"内存越界"、"开启DEP保护"等線索推敲,應屬於緩衝區溢位攻擊(Buffer Overflow Attack)的一種。若是如此,如Windows版本為XP SP2以後的OS,CPU又支援NX開啟DEP防護(Date Execution Prevention)應該就可大幅降低中箭落馬的機會。千萬別因某些程式的不相容,一氣之下就把DEP給關閉。真有不相容問題,建議針對特定程式關閉DEP即可,別嫌重就把防彈衣給脫了。

另外,關於中毒的徵兆,目前看到的是IE會開啟cmd.exe及下載/執行ko.exe木馬程式。不過,駭客界人才濟濟,也許過兩天就會有其他品種的新攻擊手法出籠,因此看到cmd.exe/ko.exe很有可能是中鏢,但沒看到卻不代表沒事。(搞資安就是要如此草木皆兵才稱得上是"政治正確",很辛苦吧!)

既然講到DEP,順道還是要為另一個被罵到臭頭的"好東西"說幾句公道話--害Vista背負罵名的凶手之一,那個惱人至極的UAC(User Access Control)。

我不知為什麼大家都這麼痛恨它,Google一下vista+uac,搜尋結果的第一頁有一半的文章在教你怎麼關掉它,真是諷刺極了。(讓我不禁想到在Share Ware網站上看過網友酸溜溜的評語: 這軟體唯一有用的功能是它的移除程式)

雖然我也覺得UAC很煩人,但打死我都不會關上它! 如果你研究過木馬、病毒是如何潛行鑽營,也發現過防毒軟體黑名單比對法下的漏網之魚,就會覺得忍受Vista/Windows 2008有人走近就大聲嚷嚷的歇斯底里,好過家當被搬個精光後的不勝唏噓。

安全,是要付出代價的!

CODE-用C#將Word內嵌圖另存成JPG檔

目標是寫一個工具程式,將Word中的第一個內嵌圖檔另存成JPG。

以下的程式範例有幾個重點可以參考:

  1. 利用C#操作Word物件
  2. Path.GetFullPath可以將相對路徑轉成絕對路徑,跟ASP.NET的Server.MapPath有異曲同工作之妙
  3. 內嵌圖檔以InlineShape方式存在,網路上有很多範例是將它Copy到Clipboard(剪貼簿)再當作圖檔取出,但我測試不成功,C#看不到Word貼上的東西。最後利用InlineShape轉成Metafile後達到另存圖檔的目標。
  4. Image.GetThumbnailImage可以直接產生縮圖,可惜它不會自動保持寬高比例,要自己計算。
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;
//記得要Reference Microsoft Word 1*.0 Object Library
using Microsoft.Office.Interop.Word;
 
namespace WordPicExtract
{
    class Program
    {
        static void Main(string[] args)
        {
            ApplicationClass wordApp = new ApplicationClass();
            object missing = System.Reflection.Missing.Value;
 
            try
            {
                object fileName = args[0];
                int w = int.Parse(args[1]);
                int h = int.Parse(args[2]);
                if (!File.Exists(fileName.ToString())) {
                    Console.WriteLine("Can't find file[" + fileName + "]");
                    return;
                }
                //Convert to full path, or Word can't find it
                //Path.GetFullPath可以將相對路徑轉成絕對路徑
                fileName = Path.GetFullPath(fileName.ToString());
                object readOnly = true;
                object isVisible = true;
                Console.WriteLine("File [" + fileName + "] opening...");
                //用C#操作Word DOM的小缺點,沒用到的參數要傳入ref missing
                Document doc = wordApp.Documents.Open(
                    ref fileName, ref missing, ref readOnly, ref missing,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref isVisible,
                    ref missing, ref missing, ref missing, ref missing);
                if (doc.InlineShapes.Count > 0)
                {
                    //由Word裡的陣列是從1開始的
                    InlineShape shp = doc.InlineShapes[1];
                    //Google上很多文章都用Clipboard把InlineShape轉成Image
                    //但我在x64上C#抓不到Word裡複製的內容
                    //所以改用Metafile類別
                    MemoryStream ms = new MemoryStream(
                        (byte[])shp.Range.EnhMetaFileBits);
                    Metafile mf = new Metafile(ms);
                    //用縮圖尺寸限制算出寬、高縮放比例
                    double ratioW = Convert.ToDouble(mf.Width) / w;
                    double ratioH = Convert.ToDouble(mf.Height) / h;
                    //需要縮小
                    if (ratioW > 1 || ratioH > 1)
                    {
                        //保持寬/高比例
                        if (ratioW < ratioH)
                            w = Convert.ToInt32(
                                h * (Convert.ToDouble(mf.Width) / mf.Height));
                        else
                            h = Convert.ToInt32(
                                w * (Convert.ToDouble(mf.Height) / mf.Width));
                    }
                    else
                    {
                        //不需縮小,維持原尺寸
                        w = mf.Width; h = mf.Height;
                    }
                    //用Word檔案Rename成.jpg
                    string imgFileName = 
                        Path.ChangeExtension(fileName.ToString(), "jpg");
                    //利用Image.GetThumbnailImage產生縮圖
                    Image thumbnail = mf.GetThumbnailImage(w, h, 
                        new Image.GetThumbnailImageAbort(ThumbnailCallback), 
                        IntPtr.Zero);
                    thumbnail.Save(imgFileName);
                    Console.WriteLine("Image [" + imgFileName + "] saved!");
                }
                doc.Close(ref missing, ref missing, ref missing);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error:" + ex.Message);
            }
            finally
            {
                wordApp.Quit(ref missing, ref missing, ref missing);
            }
        }
 
        public static bool ThumbnailCallback()
        {
            return false;
        }
 
    }
}

注意: 記得要參考Word的COM+ Library物件,版本依你所裝的Word版本而定。Word 12.0是Word 2007,Word 2003則是Word 11.0。

搜尋

Go

<December 2008>
SunMonTueWedThuFriSat
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910
 
RSS
【工商服務】
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


BlogLook Score and Rank

Syndication