2017年5月18日 星期四

【速報】針對WannaCry勒索軟體_微軟系列修補

Windows XP , Windows Vista , Windows 8 , Windows 2003 , Windows Server 2008適用
KB4012598修補快速整理包下載:https://drive.google.com/file/d/0BybxVRTRlzdLclAxV3lrMnpCQXc/view?usp=sharing

Windows 7 , Windows Server 2008 R2 的部分要做4月份的SMB修補MS17-010
下載點:http://www.catalog.update.microsoft.com/Search.aspx?q=KB4015549

2017年5月17日 星期三

Imagine viewer 看圖軟體

這裡做個紀錄用...

最早用過ACDSee,它是最好用的,功能強大,但是後來不僅開始收費了,軟體也越來越肥,啟動時間不再像以前快,也不再小而美,後來就棄用。

再來就是FastStone Image Viewer,捨棄ACDSee後就它,但是也越來越商業化。

以上兩套都不支援Unicode,所以當你的圖變資料夾是簡體中文/日文時就會無法讀取

目前較好用的看圖軟體,可以支援Unicode資料夾或檔案名稱,軟體小而美,但功能有點精簡,可是作者自2014年後就再也沒有更新版,不知道怎麼了...
是不是沒錢繼續維護?建議覺得好用就到官網捐點錢,讓作者好繼續維護吧。

※它有支援很多解碼插件可以自行安裝

官方網站:http://nyam.pe.kr/blog/entry/Imagine
下載點 :http://hqfc.express.com.tw:8080/share.cgi?ssid=0JT5ksH

密碼:qG55oShq

2017年3月17日 星期五

Google 地圖如何得知桌機所在的GPS地理位置

這是在無意中發現的...

先說Google地圖如何取得GPS地理座標位置的吧。

底下是一般上網的模式:


從我們桌上型PC到Google地圖的方法,透過我們的住戶的網路提供者,接駁到中華電信,然後再透過中華電信的機房,連接到海底電纜,一直連.....,直到Google的伺服器上。

當然,連接到Google伺服器的經過路徑沒那麼少,圖案只是用來簡化說明而已。實際上,網路封包它會經過許許多多的線路和路由器。

然後,Google的伺服器會嘗試從網路的末端,也就是最接近你的PC端的任何裝置上獲取GPS的地理位置訊息。

然而,大家都知道,桌上型PC不會裝載GPS接收器,當然我們家中的路由裝置(分享器、社區網路路由器、第四台業者,ISP.....)也都不會有裝載GPS定位點囉。

但是,有一種路由器的地點一定會有GPS定位點的,那就是負責聯接海外線路骨幹的總機房,它一定會有這個GPS的訊號,因為網際網路上就是利用這個來是別是哪個國家/地區負責的網路。

然後,Google地圖會把你的封包來源搭配這個路徑上最後一個GPS定位點,識別出你的電腦位置。

所以,當你第一次在某個地方,申請網路後,只用一台PC,連上網路,打開Google地圖,點一下畫面右下方的小圓點『我的位置』時,你會發現定位點跑到了桃園龜山這個地方,當然你會想:我又不在那地方,為什麼Google地圖會說我在那裏呢?

這就是原因了。

再來,神奇的是,當你有手機時,情況就不一樣了。

眾所周知,現在的智慧手機(幾乎)都有GPS/AGPS,取得定位資訊,然後,把家裡的網路用無線AP分享給手機上網。



此時,如果手機連上了Google地圖,該網路的末端GPS訊號,就會被更新成為最新的地理位置。此時,如果在PC上重新開啟Google地圖瀏覽,然後再按一下右下方『我的位置』,很神奇的,你就會發現PC的定位點變成了你所在的位置,而且位置還蠻準的呦。

PC版上Google地圖右下角的小圓點上面的說明就會變成『根據你的手機定位紀錄』。

2016年11月29日 星期二

C# 設定TcpClient連線時的TimeOut

我在設計一個測試主機是否存活的連線方式,通常除了Ping的方式之外,另外一種就是模擬telnet的連線方式,當伺服器的ICMP被關閉時,或是防火牆未開啟ICMP的通道時,Ping Host 就無法成功,但是通常伺服器都會開啟定服務埠來提供外部的服務,例如 Http(80)、DNS(43)、FTP(21)、RDP(3389)、HTTPS(443)、other Http(8080)、1433(SQL)等等。

此時可以透過基本的 Socket Connection 來確定該服務可以連線,基本上若是不存可以連線的埠,則 Connect 會發生拒絕連線的 Exception,但是在透過防火牆後的連線,有可能連拒絕連線的訊息都不會回應,導致 Connection被 Hang住,故在設計 Scoket Connect 時要有 Timeout 的設計,最好可以自己決定 Timeout 時間,但是 Socket 或 TcpClient 都沒有 Connect 的 Timeout 可以去設定,因此我們使用了 BeginConnect 非同步連線 + ManualResetEvent 等待中斷的事件來處理。


using System.Net.NetworkInformation;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace Test
{
    class tcptool
    {
        //可以取得的回覆訊息
        public string ReplyMessage;
     
        private static bool IsConnectionSuccessful = false;
        private static Exception socketexception;
        private static ManualResetEvent TimeoutEvent = new ManualResetEvent(false);

        public bool connectHost(string sHost, int port , bool onlyTest , int timeoutMS)
        {
            //將執行緒通知事件ManualResetEvent設定為未收到訊號,此時進入的事件會持續執行
            TimeoutEvent.Reset();
            socketexception = null;//清除例外承載物件
            TcpClient tcp = new TcpClient();
            ReplyMessage = "";

            try
            {
                //使用非同步連線方式,當連線完成後會通知CallBackMethod事件
                tcp.BeginConnect(sHost, port, new AsyncCallback(CallBackMethod), tcp);
             
                //進入執行緒等候,指定等候時間,並設定false=不在等候前結束處理程序
                //此時TimeoutEvent會等到被Set()並返回true,或是一直等候時間到期,還沒等到set()指令,就會返回false
                if (TimeoutEvent.WaitOne(timeoutMS , false))
                {
                    if (IsConnectionSuccessful)
                    {
                        //連線成功通知
                        NetworkStream stream = new NetworkStream(tcp.Client);
                        StreamWriter sw = new StreamWriter(stream);

                        sw.WriteLine("Hello");// 將資料寫入緩衝
                        sw.Flush(); // 刷新緩衝並將資料上傳到伺服器

                        if (!onlyTest)
                        {
                            //從伺服器接收的資料
                            StreamReader sr = new StreamReader(stream);
                            ReplyMessage = sr.ReadLine();
                        }
                        else
                        {
                            ReplyMessage = "Test successful!";
                        }
                    }
                    else
                    {
                        //沒有連線成功丟出Exception
                        throw socketexception;
                    }
                }
                else
                {
                    //當等候時間逾時
                    tcp.Close();
                    throw new TimeoutException("Time Out Exception !");
                }
            }
            catch (Exception ex)
            {
                ReplyMessage = " Exception:" + ex.Message;
                return false;
            }
            return true;
        }
        /// <summary>
        /// 當連線完成後,進入此事件處理
        /// </summary>
        /// <param name="asyncresult"></param>
        private static void CallBackMethod(IAsyncResult asyncresult)
        {
            try
            {
                IsConnectionSuccessful = false;
                //檢查回傳物件是否存在(存在代表連線成功)
                TcpClient tcpclient = asyncresult.AsyncState as TcpClient;
                if (tcpclient.Client != null)
                {
                    tcpclient.EndConnect(asyncresult);
                    IsConnectionSuccessful = true;
                }
            }
            catch (Exception ex)
            {
                //發生連線意外
                IsConnectionSuccessful = false;
                socketexception = ex;
            }
            finally
            {
                //通知等候結束
                TimeoutObject.Set();
            }
        }
    }
}

這裡要注意的是,如果只是要測試連線存在與否,必須要設定 onlyTest 為 true ,否則遇到某些伺服器沒有回應資料,可能會讓程式 Hang 在 ReplyMessage = sr.ReadLine(); 這一行上面。

2016年9月1日 星期四

C# PrintDocument的解析度

這次在製作列印文件時,需要繪製圖像與文字

但是每次在PrintDocument列印時,圖像解析度一直始終都是不佳的狀態,
儘管把 Imag 或 Bitmap 繪製的時候把 Resolutions都調高,但在列印時依然沒變好。

後來,反覆研究測試後發現,原來是最終輸出影響了整個列印品質,
可以看下面的成型原因:



為什麼 Graphics 只有 100 DPI?
原因就在於 Graphics 成像時的參考單位是『螢幕』,而一般螢幕都是在 72~96 DPI左右的。

2016年8月31日 星期三

C# 列印純黑白圖像要點

給自己備註的

如果使用的是條碼印表機列印圖像,由於條碼印表機沒有所謂顏色深淺的特性
其不是黑(Black)就是白(non-Black),如果要列印圖像(像是標籤上的LOGO),
圖片若是彩色的情況就會出現像是毛邊的點。

解決的方式就是要將圖片做灰階的二階化(threshold)

下面這個方法可以先產生一個二階化圖像的ImageAttributes:


        static ImageAttributes BWThreshold(Image sourceImage, float ThresholdLevel)
        {
            var gray_matrix = new float[][] {
                new float[] { 0.299f, 0.299f, 0.299f, 0, 0 },
                new float[] { 0.587f, 0.587f, 0.587f, 0, 0 },
                new float[] { 0.114f, 0.114f, 0.114f, 0, 0 },
                new float[] { 0,      0,      0,      1, 0 },
                new float[] { 0,      0,      0,      0, 1 }
            };
            var ia = new System.Drawing.Imaging.ImageAttributes();
            using (Graphics gr = Graphics.FromImage(sourceImage))
            {
                ia.SetColorMatrix(new System.Drawing.Imaging.ColorMatrix(gray_matrix));
                ia.SetThreshold(ThresholdLevel); // Change this threshold as needed
            }
            return ia;
        }


再把這個ImageAttributes丟給DrawImage當成參數輸入,即可繪製。

Image logopic = Image.FromFile(logoFile);
Rectangle logoRect = new Rectangle(10,10,230,120);
Graphics.DrawImage(
     logopic ,
     logoRect ,
     0 ,
     0 ,
     logopic.Width ,
     logopic.Height ,
     GraphicsUnit.Pixel ,
     BWThreshold(logopic,0.8f));

這樣可以把黑白圖像印製的比較清晰。

2016年8月30日 星期二

統一發票列印小程式


因為公司會在一堆系統上都有可能要印發票(真不懂要怎麼搞?)

希望可以有個小工具可以列印電子發票,

原本發票列印程式要使用條碼機專用語言(ZPL、EPL),但容易被某種機型綁定。

當然可以考慮使用ESC/POS指令的方式,但也是要印表機支援這種指令列印模式(當然多數表機都有支援),不過要列印QR碼,就有點不是那麼容易了,除了要自己編碼外還要注意中文問題。

後來我想改用Windows Printer Driver來列印,雖然不如指令式快速,但可以方便各類型程式應用,因此考慮了以下的條件:

使用C#開發、.Net 2.0平台、Console呼叫

本來想用RDLC來做,但是很不幸的,失敗了,原因就在於條碼,
國稅局訂定的Code39條碼內要放入21個字元(19+2)長度,
如果使用RDLC的話,解析度只有100DPI,密度不夠,條碼線條沾黏嚴重。

一般的條碼機至少都有200DPI得等級,這RDLC也太彆腳了吧,
網路上找盡RDLC條整解析度的方式都沒有比較好的效果。

因此,改用直接C#繪製的方式來做,
當然中間為了條碼圖像清晰度的問題花了不少心力解決。

下載點:PrintInvoice