Yearly Archives: 2010

無線 Hub 接線設定方式


前幾天去現場查找無線網路,因為對方網管說沒有擋 TeamViewer ,但是 TeamViewer 要輸入密碼建立連線時,就會中斷,現場的電腦有收到 TeamViewer 建立連線的要求,就是建立不起來。

對方的網路是委外管理,所以聯絡委外的公司,委外的公司對我提供我拿到的虛擬 IP 感到困惑,說根本沒那網段 IP ,應該是現場的管理單位自行安裝,所以他們也不清楚,因此我就去找現場的無線基地台,看看是不是自行安裝的網路設備擋到了。

現場是用合勤的,應該是這台:http://www.zyxel.com.tw/zyxel/product/prod_detail.php?no=0000857

安裝在安全門的燈箱後方,第一次拆接時,是由水電師傅幫忙爬上去拆卸,所以我不知道原來如何接線,換上先前同事測過,他說有無線 Hub 的這台,他也測試過的:

http://buy.yahoo.com.tw/gdsale/gdsale.asp?gdid=1943558&co_servername=1e2d5ab87dff191dd4c0547de27c5982

我之前用過的無線 Hub 是 Microsoft MN-700 這台,這台在無線模式可以在網頁設定直接點選,接線方式不變,所以我就當成無線基地台方式接這台,接上後,機器收到的 IP 是 192.168.1.x ,並非是原網段,經過測試後,變成是又多一層虛擬網路,打電話去問同事測試的情形,叫我試試設定頁面內的 client 模式看看,結果更慘,連無線網路都不見了,只好自己爬上去把機器拆下來重新設定。

抓了硬體的使用手冊對照,智鼎這台只有四種模式,AP / Client / AP+WDS / WDS ,完全沒有 Hub 模式,而 Client 其實是把基地台模擬成無線網卡,所以用 Client 模式後,要用網路線接電腦,顯然也不是我要的 Hub 模式。WDS 漫遊模式算是變相的 Hub ,但上游的基地台要支援,設 WDS 才有意義,只好放棄先接回原來的設備。

一測也是 192.168.2.x ,不是原來的網段?

我是親眼看見機器原先在上面的樣子,所以我唯一能猜測的就是上游的網路線原先不是依照標準接線方式接在 WAN 孔上,而是接在 LAN ,經過測試果然又是原先的網段,再拿智鼎的以 AP 模式將上游的網路線插在 LAN 上,果然是原先的網段。

我滿驚訝的,沒見過說明書說可以這樣玩,不知道有幾家的產品可以接受這樣玩?透過無線網路可以直接以 AP 虛擬 IP 連入設定頁,也可以使用原先網段連到網際網路,對我來說,又是一個嶄新的窗戶打開了。

但是 TeamViewer 仍然不能連,所以可見得是上游網段就擋掉了,既然功能差不多,就不替換硬體,順便把這台內建的 2dB 天線換成 5dB 的,原先距離較遠的機器,馬上通訊強度從 50% 上升到 96% 以上,連線速度也從 24Mbp 升到 150Mbp ,讚啦~

到了辦公區直接用網孔測,辦公區那邊也是擋 TeamViewer ,也懶得跟對方委外的網管揮,請對方設定遠端桌面,閃人。

Categories: 電腦和網際網路, 工作點滴, 技術分享 | 1 則迴響

電腦不能開機只因水銀電池沒電~


昨天上午不在家,據說小朋友在電腦旁邊玩躲貓貓,下午去家樂福、湯姆熊,還去民生綠園看耶誕樹,晚上洗完澡小朋友就睡了,我發現電腦開不起來,先是開機一長三短的嗶聲,然後又顯示無開機區,看了一下 BIOS ,時間正常在跑,又因為小朋友睡了,也不知道他們怎樣搞得,所以等今天白天再處理。

中午把機器拆起來,天啊,都是灰,拿了吸塵器狂吸,再把機器上的前面板、前風扇等都拆下來清乾淨,順便把硬碟拆下來目視,看看有沒有明顯徵狀。

疑?BIOS 開機碟是 WD ,但是明明我正在用的開機碟不是 WD 的… 拆了水銀電池下來測試,果然,水銀電池完全沒電,用電壓記去量,不到 0.5V ,清完主機換好水銀電池再開機,重設 BIOS 後,就一切正常了。

不過比較納悶的是,BIOS 時間為啥還能跑,沒變成出廠值啊~~

不然一開始就會猜是水銀電池沒電了…

Categories: 組織 | 2 則迴響

[Win7]需使用網路芳鄰連入時網路位置別亂選


最近在論壇上常看到有人問到 Win7 網芳相關問題,若是用 Google 搜尋時,可能會看到要求群組用 MSHome 或是改加入 HomeGroup 群組之類的,其實都不用,重點是網路位置不能是公用網路,只有家用網路或工作場所網路這兩種才能使用網芳,否則就算你防火牆全開還是不讓你用的~

 當你電腦第一次連線上網時,你會看到下面第二張圖,第一次用 Win7 的人可能會隨便選,所以你可能忘了,不過沒關係,你可以叫出網路和共用中心,看看作用中的網路下方寫的是哪種網路位置,如下圖,有工作場所網路、公用網路等。若是你設定成公用網路,則在該張網卡不能使用網路芳鄰連入功能,你可以點選該連結後,會開啟下面第二張圖。

若你要開放你的檔案讓其他電腦透過 Win7 連入,請千萬記得選擇家用網路或工作場所網路。

當然最後防火牆這邊也要勾選。我試過設為公用網路、防火牆這邊也勾選,但是沒效果,不知道哪裡擋住了,仍然不能連入。

Categories: 工作點滴, 技術分享 | 1 則迴響

[VBNET]讀取簡易氣象站觀測資訊


週三收到一套簡易型氣象站,是 Davis 出的 Vantage Pro2 Weather Stations ,要能抓出其資料到電腦上。

http://www.davis.com/catalog/product_view.asp?sku=8640313

本來先打電話給廠商,詢問通訊協定,台灣代理商也不清處,只知道連線設備是 USB 轉 Serial 。期待他是 485 的心情等待,到了周四開始測試… 居然是自訂通訊協定… 台灣代理商說原廠不提供通訊協定,就是要賣他們自己的軟體,但是依據軟體說明書的網址上去看,根本通訊協定就放在網頁上嘛~ 分兩個年次的版本,2007 跟 1999 年的,2007 的有提供 VB2005 的範例。

抓下範例當然是先跑跑看,沒想到範例是呼弄人的,原始碼故意多兩個變數不能打開 WinForm 設計畫面,好在這個我熟,直接幹掉 Form1.Designer.vb 裡面多的敘述後,再跑跑看,沒想到這個範例版本太舊,不支援新版的 USB Driver ,所以找不到 Serial Port ,此外這個範例是呼叫這家廠商自己寫的 DLL ,讀 Data 時是每 byte 逐次讀,令我不喜,我喜歡一次讀多一點的方式。

因此祭出前陣子介紹的工具:
[推薦]通訊必備監聽軟體 AccessPort
先用原廠的程式讀取,原廠的程式是用 VS2008 寫的,安裝好後,把程式目錄抽出來,再反安裝,就可以當成綠色軟體獨立執行,這隻程式還滿鳥的,啟動時要先人工選取氣象站設定,每次要讀取資料還要手動點選下載資料的按鈕,不適合自動執行,但從 AccessPort 讀出來的通訊協定,對應說明後,再由 AccessPort 終端機模式進行測試,經過不斷精簡指令所得到的測試結果,只需要輸入 LOOP 1<CR> 即可。

把先前寫給485的程式碼改一下,讓它支援自訂輸入位元組,就可讀回所有的資料並分項目輸出,不過 485 是以 Word (2 bytes) 為單位,這是以 byte 為單位,懶得改程式碼,就把 Offset 全部以 0.5 為單位來跳… 先是用內建單位跑,這家輸出的大部分都是英制,例如雨量 in ,連氣壓也用 in Hg ,風速則用 mph ,還得上網查公式轉成公制,面板是支援輸出成公制,所以還可以比較一下,不過因為上網查公式的小數點位數有限,在接近進位點時,會出現最後一位的誤差。

這個氣象站也很怪,因為內建記憶體有限,所以可以寫入記憶卡的最小時間間隔是 5 分鐘一筆,但是無線電傳卻是每 2 秒更新一次… 反正已經可以即時從氣象站讀出,就先設每 2 秒讀一筆並寫入資料庫,從週五下班前開始跑,週一到公司時再看結果了。

目前寫入資料庫含時間共 17 欄,暫時先選擇其中 7 欄顯示在螢幕上。

Categories: 工作點滴, 技術分享 | 5 則迴響

[VB6]讓介面支援簡中


話說公司有個 VB6 的程式要銷往內地的合作廠商,廠商需求是支援簡體中文,我就負責改版讓它支援。

這隻程式歷經多任軟工修改,主要處理介面部分是透過 ProFile (.ini) 格式檔案的方式來讀入,但因為過去有保密需求,所以檔案另外有加密。

考慮眾多需求後,基本上採用 utf8 格式解決跨語系問題,另外為了工作方便,把自己另外寫的小工具改成針對這個檔案需要的功能,加入讀入、寫出編碼的定,考慮到目前需求,只有 Default / big5 / gb2312 / Unicode / utf-8 / utf-16 的功能,並允許未加密的檔案可以被記事本編輯。

內容就簡單了,逐個檔用 Word 繁轉簡,重新剪貼就可以了。

程式碼的部分比較亂,歷經多任軟工,所以有直接呼叫 API 跟用自建類別處理的,我也沒空慢慢寫,把我以前寫的 ProFile.bas 函數庫拷貝進去,另外加一段自動偵測加密檔的功能,再把以前寫的 FileTool.bas / StrTools.bas 放進去,讓它可以處理文字檔的 Unicode 識別字元,把處理檔案讀取跟寫入的呼叫部分替換成我寫的新函數,就搞定這塊。

第一次處理時,沒注意到有呼叫 API 的部分,所以必須把檔案存成 gb2312 ,只能在簡中跑,然後慢慢找程式碼中哪裡有使用到 API ,加以替換,才完成所有的更新。

在 WinXP en + MUI 設為簡中下,直接就可以跑了:

當然,由於 VB6 是 ANSI Window ,在 WinXP en + MUI 設為繁中下,若要顯示簡中,還是得祭出 Unicode 補完計畫,增加 Unicode 與 big5 轉換表的字數:

註:舊版的函數庫可在此處找到 http://www.hisdt.com/TLCheng/Net/NetList.aspx ,舊版本並沒有偵測 Unicode 檔頭的片端,我檔案沒帶回來,有空再補這段。

2011/1/2 補:

VB6 程式碼
Public Function DetectCodePageByHeader(ByRef arrBytes() As Byte) As enuCodePage
   Dim
byteHeader(2) As Byte
   CopyMemory byteHeader(0), arrBytes(1), 3
   strHeader = UCase(ByteToHex(byteHeader))
   Dim rtnCodePage As enuCodePage   If left(strHeader, 4) = “FFFE" Then ‘ Unicode
        rtnCodePage = enuCodePage.CP_Unicode
   ElseIf left(strHeader, 4) = “FEFF" Then ‘ Big Unicode
        rtnCodePage = enuCodePage.CP_Big_Endian_Unicode
   ElseIf left(strHeader, 6) = “EFBBBF" Then   ‘ UTF8
        rtnCodePage = enuCodePage.CP_UTF8
  Else
        rtnCodePage = enuCodePage.CP_ACP
   End If

   DetectCodePageByHeader = rtnCodePage
End Function

Public Function myGetStringBinaryFile(ByVal lpFilename As String, Optional ByVal nCodePage As enuCodePage = CP_Auto) As String
   Dim FileBuffer As String
   Dim arrBytes() As Byte
   arrBytes = myGetBinaryFile(lpFilename)
   If nCodePage = CP_Auto Then nCodePage = DetectCodePageByHeader(arrBytes)

   Select Case nCodePage
   Case CP_Unicode
       FileBuffer = arrBytes
   Case CP_Big5
       FileBuffer = StrConv(arrBytes, vbUnicode)
   Case Else
       FileBuffer = myMultiByteToWideChar(arrBytes, nCodePage)
   End Select

   If left(FileBuffer, 1) = ChrW(&HFEFF) Then FileBuffer = Mid(FileBuffer, 2)

   myGetStringBinaryFile = FileBuffer
End Function

Categories: 工作點滴, 技術分享 | 發表留言

個人網站換 IP ~


週二從宜蘭大學出差回來,五點多開始上網,才點了兩篇連結網路就不通了,打電話去 HiNet 問,是說機房維修,約 3 小時復原。那就先吃晚餐吧。

晚上上網後,發現靜態 IP 改變,再打去 HiNet 問,說機房還在維修,要再幾天,所以這幾天都是動態 IP ,等到完成後,才會恢復原先 IP 。

週三因為去宜蘭的路程中感冒,所以回來吃了晚餐就掛在床上,週四晚上才看 IP …

週四這天也很不順,早上到公司網路就掛了,打到中華電信去問,說有緊急狀況,從 8:00 開始維修公司那邊的機房,聽說範圍影響很大,有小東路那邊的朋友說也被影響了,公司網路到了下午 13:00 時恢復。

所以晚上想說我家這邊機房應該修好了吧?讓無線主機重新連線,IP 又換了一次,打到中華電信去問,說機房已經維修好了,但是機房有機板整個更換,所以所有固定 IP 都換掉了,有發通知信了。

原先 IP 59.127.4.39 從 2006/7/11 用到  2010/12/02 ,這次換新 IP 了,趕緊去 http://twbbs.org/ 更新,沒想到當天主機掛點,沒辦法改,拖到凌晨才能連入。

Categories: 組織 | 發表留言

與發信蠕蟲對決經驗分享


話說前幾天,接近中午吃飯的時候有同事反映說不能寄信,就跑去他電腦幫忙看。

按照我除錯的習慣:

telnet 公司MailServer 25 、telnet msa.hinet.net 25

都是能連線,但是螢幕上沒有登入的回應。

接下來打開 Outlook ,依照這篇「[Outlook]啟用紀錄 追蹤收發郵件的問題」啟用追蹤功能來看,連線紀錄看起來是正常連到 Server ,但是卻被 Server 拒絕連線,接著公司的老大也反映無法寄信,就先回去測試我自己,的確我也沒辦法寄信,首先猜想會不會像前次一樣,有人中毒了,然後猛發封包造成上傳封包滿載,一看,果然有兩個問題 IP 上傳封包很大,有一個問題 IP 連線數過高,先把這三個 IP 封鎖 5 分鐘測測看,仍然不能連線,就先跟著大夥出去吃飯了。

吃完飯回來以後,其他網路服務都正常,但仍然不能寄信,用 telnet msa.hinet.net 25 變成完全不能連線,接著我測了多家網域的 port 25 ,由於標準 SMTP 是走 port 25 溝通,所以測了幾台 Mail Server 都不通時 (例如考選部寄發通知信的 telnet mail.moex.gov.tw 25),我判定應該是網路連線被擋,確認路由防火牆內沒有被加入規則後,重開路由再試看看,當然仍然完全不能連線。

我印象中我以前忘了不知道幫哪個單位處理不能寄信問題時,曾經碰上被 HiNet 斷網的,所以我就打 0800080412 去問,那個接電話的實在很菜,我已經跟他說我用 telnet 測,就直接連不上了,他還一直問我是哪個 Outlook 版本… 只好換個方法問,我說:「我記得 HiNet 有個網址,可以看哪個 IP 因為廣告信被停權,這個網址在哪?我想要確認一下。」

http://spam.web.hinet.net/black_list_fixed.html

果然,公司的 eMail 被擋,然後我就問了一下原因跟復權的申請步驟。HiNet 說在 10 月底已經有發信通知,說有被檢舉發廣告信,然後周一有發通知信說會被停權,申請復權要跟 Spam 小組聯絡,給了我一支電話。這可糗了,HiNet 說發的 eMail 信箱完全沒人知道帳號密碼,是申請 HiNet 附贈的 eMail ,但是公司有另外租用信箱服務,所以根本沒人用,也沒人知道這個信箱,要到這個網址去重設新的密碼:

http://msweb.hinet.net/USER/forget_password.htm

又糗了,這邊需要輸入連線密碼,連線上網密碼卡也沒人留下來,也沒交接,連附掛電話是幾號都不知道,HiNet 說這樣要去臨櫃辦理,要帶負責人印章、公司章及最近的繳費收據作為證明…

山不轉路轉,路不轉人轉,我就只好去路由主機偷連線密碼出來。熟 dhtml 的都知道怎樣偷密碼,這邊就不教壞菜鳥群了~

連入 HiNet WebMail 後,看了兩封信,第一封10月底的信件是說有人檢舉發送主題為「Hello」的郵件,請我們內部檢查。第二封是說上周仍然觀查到持續發送廣告郵件,將於這天開始停權到12月上旬。由於 WebMail 上面這兩封郵件都有迴紋針標記,但是讀不到附件,所以先跟 Spam 小組聯絡,請對方將問題郵件寄過來,這樣我可以依據信頭來追是哪台發的,此外登記一個我最近才申請的列入職務交接公司信箱做為聯絡之用,Spam 小組要求要先排除問題才能解除封鎖,在等 Spam 小組發信過來之前,先把每台電腦的 IP 及電腦名登記起來。找到目標電腦後,祭出這篇「iThome 電腦報 306 期」提到的微軟免費工具,TcpView 及 Process Explorer,首先先用 TcpView 找出是哪些程式在連網路,發現是 updates.exe 這隻程式嫌疑很大,再用 Process Explorer 找出這隻程式的實體路徑跟命令列看看,這隻程式放在 %AppData%\亂數目錄\updates.exe 下,顯然不是正常程式的位置,之後搜尋註冊資訊檔,清掉相關資料後,把相關程式砍掉,這台有裝某家一年免費的防毒程式,看起來到期很久了,之後上網搜尋,看起來應該是 2010/9/10 改版的這隻會發 eMail:

http://www.eranger.com.tw/virus.php?v_id=818

http://about-threats.trendmicro.com/Malware.aspx?language=tw&name=WORM_MEYLME.B , http://www.trendmicro.com.tw/solutionbank/2/details.asp?id=36459

另外有一台用 TcpView 檢查是 Skype 一直在發送封包,但是把 Skype 關掉後,變成是 System 發送封包,怕是 RootKit 等級的… 但是那台電腦急著用,只好先放行,還有一台電腦是另一位主管的,連線數過高,但不確定是不是因為不能寄信時,他一直重寄造成,所以列入觀察名單。

HiNet 解除封鎖後,還是一直不能寄信,打電話去 0800080412 問,對方說要把小烏龜關掉重開… 擋的時候都不需要關機重開,為啥解鎖要關機重開?只好乖乖的關小烏龜重開,重開完就正常了。

Categories: 資訊管理, 技術分享 | 發表留言

[生活情報] 便宜的機車強制責任險-續


話說去年在網路上狂找便宜的機車責任險:
 
今年又到了要保險的時間了,找來找去,這次還是以 東森保險生活網 最低價奪冠:
(今年是配合旺旺友聯)
 
前年 629 ,去年 584 ,今年 546 (=666-120) ,相當於 82 折,。如果有看到更優惠的,也請分享給我。
 
註:去年旺旺友聯有寄續保單給我,今年蘇黎世沒寄,大概是沒優惠也沒臉寄吧…
Categories: 新聞與政治 | 1 則迴響

迪愛波歷險記II-地球生存戰~


昨天大女兒參加學校合作的迪迪舞蹈教室在台南市立文化中心表演迪愛波歷險記II-地球生存戰,因為先前帶大女兒去看過她同學的表演,所以原本我以為只是一般舞蹈教室的招生行程,並沒有很放在心上。

因為晚上正式演出,禁止攝影,所以下午總彩排時開放家長拍攝。

剛到的時候個別彩排還沒完成,大女兒還穿著便服:

總彩總共大概 12 個橋段,女兒參加其中三個橋段及一個謝幕,表演的角色是鍬形蟲:

在週五報紙地方新聞還有寫到,門票售出率達七成,晚上正式表演時,台南市立文化中心演藝廳一樓全部坐滿,二樓大概坐一半,只有邊邊的位置是家屬的免費貴賓席,其他是真的售出,而不是親友團,倒讓我有點驚訝。

賀大女兒演出成功~

Categories: 娛樂 | 發表留言

[惡意程式] 開機跳出 .Net framework 錯誤


最近常有人在論壇提到開機跳出 .Net framework 錯誤的對話盒,若點選左下角詳細資料展開對話盒,將會看到 System.Net.Mail.SmtpException 錯誤 (詳細錯誤訊息見文末轉貼)。

今天剛好朋友碰到此問題,就幫忙抓了一下,發現是一隻程式放在:

%AppData%\Microsoft\Templates\Server.exe

並在啟動時執行,標記為 Microsoft Update 。

這隻程式的圖形偽裝成 VB6 預設圖示,實際上卻是 VS2008 開發的 .Net 3.5 ,欲透過 gMail 發信,可能是被人檢舉後,帳密被停用,才會因為認證失敗跳出錯誤訊息。

壓縮以後傳到我的電腦來,小紅傘跳出該程式為惡意程式:

Virus or unwanted program ‘TR/Dropper.Gen [trojan]’
detected in file ‘D:\xxxx\xxxx\Temp\Server\Server.exe.
Action performed: Allow access

參考資訊為:

http://www.avira.com/en/support-threats-summary/tid/3647/threat/TR.Dropper.Gen

檔案資訊做得滿認真的,不過很瞎,因為 .Net 3.5 程式版權寫 1998 … 騙鬼喔~

繼續閱讀

Categories: 技術分享 | 發表留言

用線性規劃解圖論郵差送信問題


話說剛剛一位當兵友人問我郵差送信的問題怎樣用線性規劃解決…

我也忘掉了,離開學校好久了說,哪還會想這種問題啊~ 後來重新想了一下,大概是這樣處理:

命題:郵差從 A 點出發,回到 A 點,路徑為距離,必須每一點都走過,如下圖上半張圖。

線性規劃命題轉換:

每一點都分成,除 A 點外,進入點到離開點的成本為 0 ,固定流量為 1 ,因為郵差只有一個人,所以固定為 1 。

因此分別對八個點做平衡方程式,就可以得到線性規劃的限制式,再對每條線做 Minimum 就完成目標函數了。

用線性規劃解圖論,還真是大材小用啊~

註:圖論中的 span tree 用張成樹這個翻譯去搜尋,找到的文章很少呢,不知道是怎樣翻才對。

Categories: 圖書 | 2 則迴響

我家第一個上 youtube 的居然是大女兒


話說今天大女兒今天上網看她上周參加作文比賽,得到佳作:

http://www.facebook.com/notes/she-tuan-fa-ren-yuan-qi-wen-jiao-xie-hui/99nian-du-yuan-qi-wen-jiao-xie-hui-di-si-jie-xie-zuo-bi-sai-cheng-ji-gong-gao/146147035430120

接著就很興奮的東翻西找,最後找到她在學校今年四月的校內演講比賽第一名的影片:

身為老爸的我給女兒鼓掌~

Categories: 娛樂 | 發表留言

[推薦]通訊必備監聽軟體 AccessPort


我在做 RS-485(Modbus Ascii/RTU) 跟 RS-232 時,都會用到這套有繁中介面軟體:

http://www.sudt.com/en/ap/index.html

幹嘛呢?監看送出、接收的位元陣列。

一個通訊程式寫得好不好,可以透過這支程式看,一個個 byte 的收,就是最浪費 CPU 的初學者寫法,能把時間算得剛剛好,一次全部收下來,就是最省 CPU 的寫法。 (當然以不超過 Buffer 為限) 

此外有時程式沒寫錯,就是 CRC 一直不對,也可以透過這套軟體看。

EIA-485 (RS-485) 是弱電通訊,200 mV 以上的壓差就會被判別為訊號,最大可能到 12.0 V ,但有時線路接近高壓設備,就會產生雜訊在裡面,所以有時不是程式的問題,而是安裝的問題,或是有地方短路等,透過這邊可以看到原先訊號,可以直接針對訊號做除錯。

論壇上常看到有人問 COM Port (SerialPort) 通訊問題,工欲善其事必先利其器,手上先有這套軟體,才能協助開發者或使用者有效的檢查通訊問題。

用法:

先將 AccessPort 開啟,選擇欲監聽的通訊埠,開始監聽後,在執行自己開發或其他工具軟體進行通訊。

Categories: 電腦和網際網路 | 6 則迴響

[VBNET] 繞路解決 MailMessage 在 Header 亂編碼的 bug


大概是美國人寫的吧~ MailMessage 這個類別預設在 Header 是用 QP 編碼,長度長也就算了,最慘的是會把空白編碼編進去…
比如說讀信回條以標準的 eMail 寫法:開發者 <qvb3377@ms5.hinet.net>
 
如果用到中文會出現:

標頭值中找到無效的字元。

描述: 在執行目前 Web 要求的過程中發生未處理的例外情形。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外詳細資訊: System.FormatException: 標頭值中找到無效的字元。


 
如果用到英文暱稱,空白還會被編進去,變成下圖,且因為空白等被編碼,所以根本無法回傳讀信通知:
 
這在國內外論壇是個難解的狀況,預定在 .Net 4.0 中修復。有些文章說到,用 UTF-8 編碼即可解決,不過 UTF-8 算是語言編碼,傳輸編碼仍然還是 QP 碼,並非是 Base64 ,能處理的最多就是附件改用 Base64 編碼。
 
這部分使用可以先幫 .Net 編碼後再送出,就不會自作孽了~
 
這篇以回條為例:
         ‘ 讀信回條
         If bAskReceipt Then .Headers.Add(“Disposition-Notification-To", rfcMime.EncodeInnerString(strFrom, , False))
 
rfcMime.EncodeInnerString 是我自己寫的類別,程式碼片段如下:

VB2008 – RfcMIMEPackage

Friend Function EncodeInnerString(ByVal strSource As String, Optional ByVal strEncoding As String = Nothing, Optional ByVal bAllEncode As Boolean = True) As String

      Try

           If Not IsNothing(strEncoding) AndAlso strEncoding.Length > 0 Then Encoding = System.Text.Encoding.GetEncoding(strEncoding)

           If Encoding.CodePage <> Encoding.Default.CodePage Then

                 Dim encName As String = Encoding.HeaderName

                 Dim fmtEncode As String = “=?{0}?B?{1}?="

                 Dim strHeaderItem As String = strSource

                 Dim encHeader As New System.Text.StringBuilder

                 Dim ascHeader As String = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(strHeaderItem))

                 Dim strBase64 As String

 

                 If bAllEncode Then

                       strBase64 = System.Convert.ToBase64String(Encoding.GetBytes(strHeaderItem))

                       encHeader.AppendFormat(fmtEncode, encName, strBase64)

                 Else

                       Dim ibl, ubl, sbl, ebl As Integer

                       ubl = strHeaderItem.Length – 1

                       ebl = -1

                       ibl = -1

                       Do

                             ibl += 1

                             If strHeaderItem.Substring(ibl, 1) <> ascHeader.Substring(ibl, 1) Then

                                  sbl = ibl

                                  encHeader.Append(strHeaderItem.Substring(ebl + 1, sbl – ebl – 1))

                                  Do

                                        ibl += 1

                                        If strHeaderItem.Substring(ibl, 1) = ascHeader.Substring(ibl, 1) Then

                                              ebl = ibl – 1

                                              strBase64 = System.Convert.ToBase64String(Encoding.GetBytes(strHeaderItem.Substring(sbl, ebl – sbl + 1)))

                                              encHeader.AppendFormat(fmtEncode, encName, strBase64)

                                              Exit Do

                                        ElseIf ibl = ubl Then

                                              ebl = ibl

                                              strBase64 = System.Convert.ToBase64String(Encoding.GetBytes(strHeaderItem.Substring(sbl, ebl – sbl + 1)))

                                              encHeader.AppendFormat(fmtEncode, encName, strBase64)

                                              Exit Do

                                        End If

                                  Loop Until ibl >= ubl

                             End If

                       Loop Until ibl >= ubl

                       encHeader.Append(strHeaderItem.Substring(ebl + 1))

                 End If

                 Return encHeader.ToString

           Else

                 Return strSource

           End If

      Catch ex As Exception

           Throw ex

      End Try

End Function

 
經過編碼後,可以看見回條變成 開發者
 
所以回條就能正確地丟回給開發者的信箱,確保又能顯示中文,又能回傳。
Categories: 技術分享 | 發表留言

[VBNET] 在 HTML 郵件內加入樣式庫


話說我想把網頁輸出內容直接寄出去,因為用了一些圖片及樣式,懶得把樣式抽出來內嵌,所以我打算把樣式直接加入到郵件內。
註:樣式內嵌在非微軟設計的郵件軟體上可能無法正常支援顯示
程式碼:

VB2008

Dim mailClient As New System.Net.Mail.SmtpClient(“msa.hinet.net", 25)

Dim mailMessage As New System.Net.Mail.MailMessage

Dim atFile As System.Net.Mail.Attachment

 

With mailMessage

    

     .IsBodyHtml = True

     .Body = “<html><head><link href=’cid:list.css’ rel=’STYLESHEET’ type=’text/css’ /></head><body><p>Hello Html Mail</p><p><img src=’cid:fidi.png’ /></p></body></html>"

End With

 

Dim arrBytes() As Byte = StringToBytes(“p {“ & vbNewLine & “color: green;" & vbNewLine & “}", enuStandardCodePages.SCP_big5)

Dim ms As New IO.MemoryStream(arrBytes)

 

atFile = New System.Net.Mail.Attachment(ms, “text/css")

atFile.ContentId = “list.css"

mailMessage.Attachments.Add(atFile)

 

atFile = New System.Net.Mail.Attachment(“d:\Temp\ftdidriver.png", “image/png")

atFile.ContentDisposition.FileName = “fidi.png"

mailMessage.Attachments.Add(atFile)

 

mailClient.Send(mailMessage)

 

收到的信件:

參考文件:http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/c65502fa-955e-4fa1-b409-238bbb677df7

Categories: 技術分享 | 3 則迴響

U485 – USB 轉 485


在新的工作場合常常需要使用到 485 ,工業用設備通常有直接的 485 監控接點,但 NB 或是新的 PC 可能已經沒有 COM 來收發 RS-232 訊息,更不要說 RS-485 了,所以我就設計出這樣的需求,委外製作 100 顆出來。
 
基本要求是要有燈號能表示收發狀態,可快速進行系統維修跟開發,另外我要快速插頭,所以做出來的東西是這樣子:
 
 
尺寸為 55mm x 50mm x 20mm 。
 
接電腦端是 MinUSB 頭,一般讀卡機、行動硬碟、手機都用這個接頭,屬於常用線材,一般人身上多半有個幾條。
接 485 端則是使用 RJ12 ,相容 RJ11 ,一般接電話用這種線,只要使用銅線,就可以遠距離傳輸,規範是 9600 bps 可傳輸 1200 公尺,不過我只用一箱 305 公尺的線去測過,再遠就沒試了。
485 的晶片是用比較高檔的 FTDI 晶片,此晶片還有出 WinCE 4/5/6 及 Windows Mobile 5.x/6.x 的驅動程式,將來還可以在行動裝置上玩,我覺得很贊,不過我在實體的 WinCE 上一直裝不起來,畫面跟 FDDI 晶片的安裝說明不一樣,不知道哪裡操作有問題。
燈號是綠:電源、紅:傳送、黃:接收,本來我希望紅色是電源,用綠黃來分,後來才知道,紅、黃兩色啟動電壓較低,對訊號的影響較少,暫時就先這樣吧。
 
 
RJ12 接頭 (6P6C) 部分,依照片上的腳位由右至左分別為 1, 2, 3, 4, 5, 6,我設定 1/6 為轉出電壓 5V ,可做其他小額供電使用,2, 3, 4, 5 分別為 T+/D+, T-/D-, R+, R- ,純就 RS485 使用時,只用到腳位 2, 3 ,若是用一般電話 RJ11 接頭 (6P4C),就是用到腳位 1, 2 ,可透過指撥開關調整 Jump 為 RS-422 ,使用全雙工來通訊,就用到 RJ11 腳位的 1, 2, 3, 4 (對應到 RJ12 就是 2, 3, 4, 5)。 Jump 照片如下圖。
 
 
第一代的試作品考慮的或許不夠周全,將來有新想法再加入,目前暫時先用這 100 個,用完再改版啦~
 
註:U485 是主管起的名字,此外因為不知道公司會算給客戶多少錢,所以成本不能透露~ 吐舌頭
Categories: 組織 | 2 則迴響

[VBNET]定時整點動作


有時,我們需要每隔幾秒做某件事,但是不論是 VB / VBNET / C# 哪種程式語言,都是呼叫系統的 Timer ,時間久了就會開始誤差,每隔一段時間誤差可能就會累積到一秒以上,造成時間並不能與所需的相符。
 
此例為從 2 秒起每 5 秒執行一次, 也就是 2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57 秒定時執行,經測試,即時誤差小於 +- 15ms ,並可持續執行,另外考慮到當下個中斷時間過近,可能造成較大的誤差,因此當下個時間與目前時間誤差小於 20 ms ,直接跳到下下個時間。
 
考慮到要同時支援 WinForm Timer 跟 System Timer ,因此引數使用 Object 來處理。
 

VB2008 原始碼

Private Sub timerInterval_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerInterval.Tick

     做某些事

     ResetTimerInterval(timerInterval, New TimeSpan(0, 0, 5), New TimeSpan(0, 0, 2))

End Sub

 

Friend Function ResetTimerInterval(ByVal oTimer As Object, ByVal intervalTimeSpan As TimeSpan, ByVal offsetTimeSpan As TimeSpan) As Integer

     Dim nextTime As Date = New Date(-Int(-(DateTime.Now.Ticks – offsetTimeSpan.Ticks) / intervalTimeSpan.Ticks) * intervalTimeSpan.Ticks + offsetTimeSpan.Ticks)

     Dim nowMillisecond As Integer = (nextTime.Ticks – DateTime.Now.Ticks) / TimeSpan.TicksPerMillisecond

     If nowMillisecond <= 20 Then nowMillisecond += intervalTimeSpan.TotalMilliseconds

     oTimer.Interval = nowMillisecond

     Return nowMillisecond

End Function

 

 
 
Categories: 技術分享 | 發表留言

[VBNET] DateTime.ToString 居然是無條件捨去法


以前沒注意到,一直以為 DateTime.ToString 到秒時,會跟 Single.ToString / Double.ToString 一樣自動四捨五入,今天在做誤差 20 ms 以下的整時紀錄時,才發現居然是用無條件捨去法… 下面是一堆範例,大家可以測看看。
 
函數 輸出 備註
CDate("00:00:00.999") #12:00:00 AM#  
CDate("00:00:00.9999999") #12:00:00 AM# 秒以下有效位數用藍色表示
CDate("00:00:00.99999999") #12:00:01 AM# 紅色為超出有效位數,自動四捨五入
CDate("00:00:00.99999995") #12:00:01 AM# 紅色為超出有效位數,自動四捨五入
CDate("00:00:00.99999994") #12:00:00 AM# 紅色為超出有效位數,自動四捨五入
 
從第二列可以看到即使僅差千萬分之一秒,還是用無條件捨去變成 00:00:00,只有超出有效位數才會四捨五入,但是時間誤差常常會發生在 +/- 10 ms ,如果不幸碰上 00:00:59.9999999 ,寫入資料庫時間不會是 00:01:00 ,而是變成 00:00:59 ,只好自己寫進位函數,讓他變成整數 1 分鐘寫入了。
 
Categories: 技術分享 | 發表留言

[SQL] SQL Server 與 Access 不同的怪地方:LEFT JOIN


先說,這篇是為了重現相同的狀況故意產生資料表跟查詢語法,就別跟我說有更好的語法了… 淚奔~
首先拿前面展示範例的這篇作為範本:[Access]資料庫 SQL 語法範例
資料表:

清單為記錄所有學生各科的成績
清單

DBID 姓名 科目 分數
1 小明 國文 95
2 小華 國文 100
3 小英 國文 87
4 小明 英文 99
5 小華 英文 94
7 小明 數學 91
8 小華 數學 96
9 小英 數學 89
在 Access 用這樣的 SQL 語法可以得到下面的結果:
SQL 語法
SELECT 名冊.姓名 As 姓名, 國文表.分數 AS 國文, 英文表.分數 AS 英文, 數學表.分數 AS 數學
FROM (((
清單 AS 名冊
LEFT JOIN 清單 AS 國文表 ON ((名冊.姓名=國文表.姓名) AND (國文表.科目=’國文’) AND (名冊.科目=’國文’)))
LEFT JOIN 清單 AS 英文表 ON ((名冊.姓名=英文表.姓名) AND (英文表.科目=’英文’) AND (名冊.科目=’國文’)))
LEFT JOIN 清單 AS 數學表 ON ((名冊.姓名=數學表.姓名) AND (數學表.科目=’數學’) AND (名冊.科目=’國文’)))
ORDER BY 名冊.姓名 ;
各科成績表

姓名 國文 英文 數學
小明 95 99 91
小英 87 89
小華 100 94 96
可是在 SQL Server 2008 R2 Developer 下,卻會變成:

必須把 SQL Server 語法變化成這樣才可以得到相同的結果,加入的內容底色為淺綠色:
SQL 語法
SELECT 名冊.姓名 As 姓名, 國文表.分數 AS 國文, 英文表.分數 AS 英文, 數學表.分數 AS 數學
FROM ((((
清單 AS 名冊
INNER JOIN 清單 AS 名冊表 ON ((名冊.姓名=名冊表.姓名) AND (名冊表.科目=’國文’) AND (名冊.科目=’國文’)))
LEFT JOIN 清單 AS 國文表 ON ((名冊.姓名=國文表.姓名) AND (國文表.科目=’國文’) AND (名冊.科目=’國文’)))
LEFT JOIN 清單 AS 英文表 ON ((名冊.姓名=英文表.姓名) AND (英文表.科目=’英文’) AND (名冊.科目=’國文’)))
LEFT JOIN 清單 AS 數學表 ON ((名冊.姓名=數學表.姓名) AND (數學表.科目=’數學’) AND (名冊.科目=’國文’)))
ORDER BY 名冊.姓名 ;
在資料庫移植時,也是要考慮到這種窘況啊~ 淚奔~
會造成不同查詢結果來說,這兩種資料庫應該有一個是設計錯誤的吧?到底是哪個啊~
補充:
在 Access 也可以這樣下查詢語法,當學生人數多或科目多的時候,會比上面的查詢語法有效率:
SQL 語法
SELECT 名冊.姓名, 國文成績表.分數 AS 國文, 英文成績表.分數 AS 英文, 數學成績表.分數 AS 數學
FROM (((
(SELECT DISTINCT 姓名 FROM 清單) AS 名冊
LEFT JOIN (SELECT 姓名, 分數 FROM 清單 WHERE  科目=’國文’) AS 國文成績表 ON 名冊.姓名=國文成績表.姓名)
LEFT JOIN (SELECT 姓名, 分數 FROM 清單 WHERE  科目=’英文’) AS 英文成績表 ON 名冊.姓名=英文成績表.姓名)
LEFT JOIN (SELECT 姓名, 分數 FROM 清單 WHERE  科目=’數學’) AS 數學成績表 ON 名冊.姓名=數學成績表.姓名)
ORDER BY 名冊.姓名;
Categories: 資料庫 | 發表留言

真實與虛擬之間的社群


記得早期上論壇的時候,大概是 1992 ~ 1998 左右吧,在學網的論壇中,是把每一個 ID 視為一個獨立的虛擬人格。
保守的人,可以在網路上狂野、裝小女生,都會被尊重,對使用者來說,一個 ID 就如同一本書作者的筆名,每個虛擬人格是每個使用者創造的,彼此之間互相不影響。
 
隨著網路逐漸走入生活,慢慢的與真實混淆後,虛擬人格觀念已很少再用,普遍把網路上的使用者或暱稱與真實社會結合,近年來都可以看見網路發言產生的法律問題。
 
早期撥接網路的論壇或說早期能上網的,一般在資訊程度或是學歷均有一定程度的素養,在論壇上討論的問題都有一定的深度,如同教授們筆戰,高來高去,水準高,專業、用字精準,用的是理論與數據服人,而不是嘴砲服人,這時要取得 eMail 還滿困難的。
到了 1992 ~ 1997 間,隨著學網的開放,一般研究生都能配發到 eMail ,就可在 BBS 這樣的開放性論壇註冊並參與各式各樣的討論,這時的參與者雖然沒有早期的高來高去到讓我看不懂,但也累積了 22 年以上的人生,懂得彼此尊重,基本上都有一定的程度才會參與討論。
1998左右,中華電信配合政府要求,開始大力對民間推廣撥接網路,學校也開始主動為大學生配發 eMail ,隨著論壇參與者年齡的下降,罕見生物也逐漸變成一個新族群,不時可以看見,那就是「小白」。這個年代與現在相比,小白只是偶爾出現,剛開始小白還是罕見生物時,基於保護瀕臨絕種動物,大部分人不會對小白太苛責,能引導就引導,不能引導就讓他在角落自生自滅,很少小白會花錢上網耍白,如果是大學生耍白,通常該校的學長級人物也會自己出來認養,校內好好指導一番。
到了 2002 年左右,開始推廣 ADSL ,網路再向下普及到小學生,這時小白開始升級為天兵,天兵已經變成不可理喻,這時的天兵,才是現在這個年代稱的小白。
 
說實在,論壇是公開自由的環境,不論是發文者還是回文者,都有權利在上面發言,我很喜歡這一句:
「我不同意你的言論,但我誓死捍衛你發言的權利」
 
這邊說的是發言的權利,而不是發言的內容。發言得當,當然就可以跟網友群獲得互動,也有一些很冷僻的內容,雖然沒人能互動,大家也能增廣見聞。
 
當發言的內容違反站規或板規,也就是違反這個社群的規則時,給予對應的處罰,一般在 BBS 上就是給予一定範圍與期限禁權設定,如果是某個版被限權,常被稱為浸水桶。當然情節嚴重的,就是砍帳號,甚至永遠封鎖某個 eMail 的註冊。
當發言涉及人身攻擊或汙辱時,甚至可能發生法律責任。
 
當發言的內容不當,但又不到違反板規或法律問題時,通常這篇文章可能變成小強大家踩。看到小強時,大家都會忍不住伸出一腳來踩。
 
前面說過,網路是一個自由發言的空間,任何人都有權利發表文章,所以不管是踩人的還是被踩的,那也只能說剛剛好而已。
老馬不管做啥,綠營還不是照罵?阿扁做啥,藍營還不是照罵?
所以有相反意見出現,在網路上是在常見也不過的事,根本無須大驚小怪,就剛剛好而已。
 
那麼大家都踩的狀況呢?這不是圍剿,而是該論壇所有參與者所形成的一種潛規則,也是另一種民意的表現。
 
今天如果在白爛版、閒聊版等版面耍白,會不會有人踩?不會,因為這個版本來的目的就是輕鬆的態度,要是有人敢亂踩,反而會引起群體攻之,這就是該論壇所有參與者所形成的一種潛規則。
而一般涉及專業討論的版面也通常會形成一些潛規則,專業討論的版面通常會要求用字精準,描述清楚,不要有模擬兩可的內容,越清楚越精準就越能被接受。
 
當然,或許可以找到一些專業討論的論壇,會喜歡有人進去耍白,閒聊。
 
論壇的風氣形成,是由所有參與該論壇的網友所能接受的最大公約數,難免會有少數人不喜歡該論壇的風氣,但還有更多的論壇可以去,隨著參與者的結構變化,風氣也是會改變的,當然風氣改變後的論壇還能不能形成氣候,那就另當別論了,比如說早期學網的 tw.bbs.comp.language 是全國最大的程式論壇集中區,隨著小白的快速繁衍,基本上現在已經沒啥人在上面好好的討論,一個全國超過 5,000 站轉信的集中區,就這樣的沒落,所以論壇的風氣是會改變的,對論壇是好是壞就另當別論了。
 
論壇是自由的,所以對別人的期待或是要求別人怎樣做,都是沒意義的,唯一能看的,就是有沒有違反版規,有沒有違反站規,當違反的時候,願不願意接受勸告,不願意就依規定處分而已。入境隨俗,每個站、每個版都有他的規矩,去新加坡吃口香糖被抓去關也只是剛剛好,去專業論壇亂貼文被眾人踩也只是剛剛好。
 
上網純粹是找爽的,讓你不爽的論壇,你可以不去,當然,往例也有很多人故意去引戰,作為調解寫程式的苦悶,也有人以踩人為樂趣,網路是自由的,各式各樣的人都有,小白的定義也會變。
 
真實的社會也持續在改變,而虛擬的社群跟真實社會間的混淆與交錯,是我們需要去適應的。
Categories: 嗜好 | 發表留言

在 WordPress.com 建立免費網站或網誌.