2012/11/11

【上海】人民公園裡的婚姻角、相親角

在上海人民公園的北面入口處(地鐵九號出口)早上開始會聚集許多人潮來這找尋兒孫的另一伴,沒有寫錯!是替自家兒女或小孫子找尋成家的對象,但我想應該也是會有年輕人自己來這物色對象才是。

這裡的景況應該就像台灣的相親吧!?只是這裡的待選名單都用A4紙張陳列自己的基本資料以及配對條件,等待有緣人來相認...。候選名單都會依據資料特性做分類,在國外工作的一區、碩士學歷的一區、大學學歷的一區、離過婚的一區...。

公園裡還有許多「仲介人員」幫忙做資料登錄與配對篩選,登記配對價錢五十到一百五不等,應該自身條件(高矮胖瘦、有房無房、有車無車...等)會影響費用吧?

這裡的婚介人員一只皮箱即可開業,讓我想到早年的台灣商人也是一只皮箱就到世界各國去招攬生意...XD。

在旁邊一處「散裝」的候選名單似乎是家長拿著自己兒孫的資料在物色媳婦女婿?

2012/11/6

【治具】Audio Loopback Jack

測試Audio Jack一般我們會使用所謂的Audio Loopback線材做迴錄工具,其實就只是把麥克風源跟聲音源的左右聲道給短路在一起而已。但最近有個案子用這樣的治具卻沒辦法回錄到聲音,後來得知在麥克風源與聲音源之間必須加個1uF(5V以上)的電容才可以,接線示意圖如下:
實際接線拍照:

補充雙聲道+麥克風Audio Jack 的結構圖,從最下方開始往上依序為左聲道源、右聲道源、接地與麥克風源:

2012/11/5

【Linux】Bochs模擬器模擬器

Bochs是一套用來模擬IA32架構的模擬器,可以模擬一台完整的PC:CPU, Memory, Disk...等,更棒的是在Debug模式中可以單步執行並隨時觀察CPU暫存器狀態或是記憶體資訊,對於學習PC底層有滿大的幫助,以下記錄下載Source包裝編譯安裝與執行的步驟。
  1. Bochs官網下載Source Code與Disk Image
    目前最新Source Code版本是bochs-20121103.tar.gz
    Disk Image這裡用FreeDos作為範例
  2. 完成下載後先對Source Code解壓縮
    tar zxvf bochs-20121103.tar.gz
  3. 作編譯前的設定:這邊開啟Debug與反組譯功能
    ./configure --enable-debugger --enable-disasm
  4. 編譯與安裝
    make
    sudo make install
  5. 以上步驟完成安裝程序, 接下來把下載好的FreeDos映像檔解壓縮
    tar zxvf freedos-img.tar.gz
  6. 切到解壓縮的目錄裡會看到會看到a.img, b.img, bochsrc, 與c.img這幾個檔案, 用gedit編輯器編輯bochsrc設定檔如下[註]
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    megs: 32
    romimage: file=$BXSHARE/BIOS-bochs-latest
    vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
    vga: extension=vbe
    floppya: 1_44=a.img, status=inserted
    ata0-master: type=disk, path=c.img, cylinders=306, heads=4, spt=17
    boot: floppy
    log: bochsout.txt
    mouse: enabled=0
    cpu: ips=15000000
    vga_update_interval: 150000
    
  7. 接著執行bochs即可, 第一個選擇畫面直接選擇6. Begin simulation即可運行模擬器
  8. 但因為編譯設定時有選擇debug模式, 所以會先trap在一開始, 畫面如下:只要輸入c並按下enter模擬器就會繼續執行
  9. 最後成功進入Dos的畫面截圖如下:
[註] bochs執行時可以用-f參數指定要帶起的模擬器參數設定檔, 若沒指定的話則會在當前目錄下依序找尋以下檔案作為設定檔:
  1. .bochsrc
  2. bochsrc
  3. bochsrc.txt
  4. bochsrc.bxrc (Windows Only)

2012/10/31

【Windows8】取得Auto Rotation狀態

先前同事提了個需求要能用程式判斷當前Auto Rotation狀態,查了一下發現有個GetAutoRotationState()函數可以調用,透過這函數呼叫可以查知目前系統Auto Rotation是否被開啟,直接看程式內容吧!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>

#pragma comment (lib, "User32")

int _tmain(int argc, _TCHAR* argv[])
{
 enum tagAR_STATE state;
 bool blResult = GetAutoRotationState(&state);
 if(blResult)
 {
  if(0 == state)
   printf("Auto Rotation: ON\n");
  else
   printf("Auto Rotation: OFF\n");
 }
 else
  printf("Access rotation status ... fail\n");
 return  0;
}

需要注意的是這函數是Windows8才加入User32.dll的,因此如果拿這程式在Windows7以前版本執行的話會遇到這樣的錯誤:
如果要避免這樣的錯誤,需要用動態載入dll方式進行呼叫。

在Windows8上執行截圖如下:


附註:tagAR_STATE詳細屬性:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public enum tagAR_STATE : uint
{
 AR_ENABLED = 0x0,
 AR_DISABLED = 0x1,
 AR_SUPPRESSED = 0x2,
 AR_REMOTESESSION = 0x4,
 AR_MULTIMON = 0x8,
 AR_NOSENSOR = 0x10,
 AR_NOT_SUPPORTED = 0x20,
 AR_DOCKED = 0x40,
 AR_LAPTOP = 0x80
}

Keyword:Windows API、System Call

2012/10/9

【Windows】Process Explorer

  在Windows系統上一般要查看執行中的處理程序可以開啟Windows工作管理員(可用快截鍵Ctrl + Shift + ESC開啟)來查看,這用來查看系統中哪個處理程序吃掉太多CPU或記憶體資源或是想殺掉某些用不到又吃資源的處理程序很好用,但若要進一步查看程式呼叫了哪些DLL、存取哪些Handle或是動了哪些Registry等詳細訊息就不夠用了!

  要進一步查看Process的相關資訊可以到Sysinternals網站下載Process Explorer,這工具以樹狀關係顯示Process之間的關係,把滑鼠移到某個Process上停著會顯示執行擋完整的路徑名稱,連帶起來的參數資訊都會顯示出來,不同的程序也可用不同顏色顯示(ex. 預設Service會以粉紅色顯示、一般程序則是藍色顯示...等),雙點某個程序則會顯示進一步詳細資訊,像是CPU佔用時間、記憶體資源或是IO資訊等,最厲害的大概就是可以查看Process執行載入了哪些DLL或是開啟了哪些Handle資訊,這些資訊對於開發人員要找問題可是有很大的幫助!


2012/8/29

【C++】縮小命令提示字元視窗

上次寫了如何用C#讓命令提示字元視窗在執行時縮小(參考這篇),今天又有同事提出需求要在另一支用C++完成的工具也要做到一樣效果,有了上次的經驗這次很快就完成了任務需求,一樣用FindWindowShowWindow系統函數來達成,只是這次要多調用一個GetConsoleTitle函數來做輔助,直接看Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>
#include <Windows.h>

#pragma comment(lib, "User32.lib")

int main(int argc, char* argv[])
{
 char cTitle[512];
 GetConsoleTitle(cTitle, 512);
 HWND hWnd = FindWindow(NULL, cTitle);
 ShowWindow(hWnd, SW_SHOWMINIMIZED);
 return 0;
}

  1. 先用GetConsoleTitle函數取得執行程式命令提示字元的顯示標題列內容。
  2. 再用取得的視窗標題找出HWND。
  3. 最後用FindWindow函數控制視窗的呈現。
  • ShowWindow第二個函數用來決定視窗要如何呈現:最大、最小...等。詳細請參考MSDN說明頁面。

2012/8/18

【Windows】關於Windows8的關機與開機

Link:Delivering fast boot times in Windows 8
Windows8很強調快速開機這個使用體驗,從開始接觸Windows8產品設計到現在,開機速度確實是越來越快(雖說快,但也要幾十個秒啦),究竟微軟是讓Windows8吃了什麼神奇藥丸可以飆速開機、又為什麼關機再開機會比重開機來得快呢?就讓我們看下去...

在傳統操作上,電腦長時間不用會選擇關機的理由絕對不是因為捨不得電腦這樣燃燒生命,多半是因為電腦在那邊發呆也是要吃電耶!特別是電價越來越貴...真是讓人捨不得。上面這篇文章則提到:其實很多人都很喜歡睡眠(Sleep)這個功能,用過的人都會發現睡過的電腦開機快很多捏。其實工作原理是讓電腦大部分的元件能關就盡量關掉,留下記憶體在那邊認真工作(記憶體若斷電,記錄的資料都會消失,所以睡眠時記憶體的電量是要持續消耗的,這樣一旦使用者要繼續使用電腦,就不用把資料從龜速的硬碟機慢慢載入了),有看到關鍵點了嗎?就是給電腦睡覺還是會吃一點點的電啦,雖然跟開機比少吃很多電,但是會吃電就是會吃電,結論:好,但還不夠好。
PS. 現在智慧型手機的待命就相當於是睡眠模式。

文章接著介紹休眠(Hibernate)功能:其實我覺得休眠這個翻譯不太好,每次在選睡眠、休眠都讓我想很久,我覺得應該用哈利波特裡面的咒語"整整(Petrificus Totalus)"或是"凍結"、"石化"之類的比較貼切。這工作原理跟睡眠差不多,但是會把當前的工作狀態儲存到硬碟上(因為硬碟是非揮發性儲存裝置,也就是說斷電再開啟資料也不會不見),經過這樣一道手續,電腦就可以放心的去休息啦。這個好處是電腦不會偷吃電、喚醒電腦很快,壞處則是會佔用一些硬碟空間(不過在這個硬碟便宜到隨處可撿的時代,一點都不會心痛呢!)。

在Windows8上,微軟覺得休眠明明就很好用,但是太多使用者都不知道好好利用,那我就改變一下關機原則,幫休眠技術做個微整型,換湯不換藥重新推出,到時在市場上還可以打著快速開機的廣告!

Windows8的關機基本上就是休眠,但是在休眠之前多做了一些程序:清除使用者工作狀態(User Sessions)、但是原先關機接續會清除系統核心資訊(Kernel Sessions)等後續動作則是跳過了,接著就開始做跟休眠一樣的行為,把系統核心狀態資訊通通寫到硬碟去了(別擔心,這個動作很快,因為新出來的產品都會默默幫你搭上象徵極速與高貴的固態硬碟,平板產品就更不用說了,沒人會把傳統硬碟裝在平板上的),完成後就可以關掉電源啦!

當使用者按下電源開關,Windows發現硬碟藏有上次關機儲存的系統狀態,就馬上把他通通讀到記憶體裡,只要再完成一些一定得重新初始的硬體元件即可,搞定後就算是完成開機啦,接著就準備登入使用者之類的程序了,就是你在使用Windows的狀態了,整個差別可以用下面這張圖簡單說明:可以看到系統初始化(System Initialization)是很浪費時間的,特別是你硬體元件什麼都沒有更動,何必這樣浪費時間呢?

 文章一開始有提到關機在開機可能會比直接重開機來得更快,原因在於這句話:"choosing Restart from the UI will do a full shutdown, followed by a cold boot.",應該是基於更新韌體或是安裝新軟體需使用者重新登入之類的理由,重開機選項會讓系統做完整的關機與開機,讓新的韌體或是軟體可以正確工作。

另外,如果你是個有潔癖的人,覺得關機就是要關得乾淨,開機就是要做得完整,一點都不能馬虎,那你也可以選擇使用"shutdown /s /full / t 0"命令讓系統乖乖聽話做完整套的關機流程,不過開機就會慢一點囉!

2012/8/16

【Windows】Free Touchpad Blocker

每台Notebook都會搭一個Touch Pad做為滑鼠的對應工具,這東西在沒有外接滑鼠時是非常好用的裝置,但是有些Notebook的機構配置讓人很容易在打字的時候不小心觸動到,導致敲鍵盤時候被干擾。
今天同事推薦了一套小工具:Touchpad Blocker。試用後覺得效果很好,概念基本上就是偵測到敲鍵盤時會把滑鼠事件給暫停,至於要停多久可以到工具選單做設定(參考下圖)。
不過有一好就有一壞,如果不是單純文字輸入的話,這樣的功能就會變得礙手礙腳,像是用快捷鍵複製(Ctrl + C)或貼上(Ctrl + V)之類的,雖然這軟體會把功能按鍵(Ex. Ctrl、Shift)排除偵測,但因快捷鍵通常會結合一般按鍵,這時候就會覺得滑鼠卡卡的了,此時可以透過(Ctrl + F9)將此工具暫停,就可以避免滑鼠卡卡的,當要大量使用文字輸入時再把功能打開即可。
下載可到官網:http://touchpad-blocker.com/

2012/8/15

【C#】縮小命令提示字元視窗

今天同事提了個奇怪的需求:執行程式時要能把命令提是字元視窗縮小,查了一下網路發現可以利用FindWindow()與ShowWindow()兩個函數達成此需求,直接看以下範例:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace HideConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            IntPtr ParenthWnd = new IntPtr(0);
            
            ParenthWnd = Findindow(null, Console.Title);
            if (ParenthWnd == IntPtr.Zero)
                Console.WriteLine("Find Window ... FAIL");
            else
                ShowWindow(ParenthWnd, SW_SHOWMINIMIZED);
        }

        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr Findindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll", EntryPoint = "ShowWindow")]
        private static extern IntPtr ShowWindow(IntPtr hWnd, int type);
        const int SW_HIDE = 0;
        const int SW_SHOWMINIMIZED = 2;
        const int SW_MAXIMIZE = 3;
    }
}

流程說明:
  1. 用Console.Title找出命令提示字元視窗本身的標題字串,並透過FindWindow找出Handler
  2. 將Handler傳給ShowWindow函數,並傳入參數讓視窗進行改變,範例標了幾個視窗屬性SW_HIDE, SW_SHOWMINIMIZED與SW_MAXIMIZE,完整的參數可以參考MSDN的參考網頁( http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
因使用了DllImport,記得要加入
1
using System.Runtime.InteropServices;

Keyword:How to Minimize Terminal on Windows、C# Programming、Minimize Command Prompt on Windows

2012/8/9

【上海】晾衣文化

這張是上海很常見的晾衣曬被方式:幾根長長的竿子從窗戶伸出來,這樣就成了曬衣服曬被子的架子了,算是這邊的標準曬衣文化。
下面這張則是更高竿的曬衣工夫:電線就直接拿來當做天然的晾衣架了!
在人民公園停車場出口看過更絕的:空間極致利用。八成是停車場管理員沒窗戶可以掛欄杆,又沒現成電線可以利用的最後大決。

2012/8/6

【上海】拍貓真的不簡單...

趁今天不進公司到上海市區晃晃,在復興公園散步時發現了這支可愛的小貓咪,正在睡午覺...

被我吵醒後不理我就到旁邊去吃不知道哪蹦出來的糧食了

哈囉哈囉,借我拍一下。總算回頭一下了!

先幫忙抓癢打好關係...

取得信任感自己靠過來了吧:)

來,練習看鏡頭喔!

來一張,就是這樣!

2012/8/2

【Windows】用命令建立捷徑

在Windows中沒有命令可以直接產生捷徑,但可以透過VBScript協助完成,直接參考批次檔範例:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@ECHO OFF

SET TARGET="%USERPROFILE%\Desktop\Test.lnk"
SET SOURCE="C:\Users\Public\Test.bat"
SET ICON="C:\Users\Public\Test.ico"
SET DESC="Demo how to create shortcut on desktop"
SET HOTKEY="ALT+F"
REM ====== Window Style ======
SET WINDOW_NOR=1
SET WINDOW_MAX=3
SET WINDOW_MIN=7
SET WINDOW_STYLE=%WINDOW_MAX%
REM ==========================

SET SCRIPT="%TEMP%\%RANDOM%.vbs"

ECHO SET oWS = WSCript.CreateObject("WSCript.Shell") >> %SCRIPT%
ECHO sLinkFile = %TARGET% >> %SCRIPT%
ECHO Set oLink = oWS.CreateShortcut(sLinkFile) >> %SCRIPT%
ECHO oLink.TargetPath = %SOURCE% >> %SCRIPT%
ECHO oLink.IconLocation = %ICON% >> %SCRIPT%
ECHO oLink.WindowStyle = %WINDOW_STYLE% >> %SCRIPT%
ECHO oLink.Description = %DESC% >> %SCRIPT%
ECHO oLink.HotKey = %HOTKEY% >> %SCRIPT%
ECHO oLink.Arguments = "" >> %SCRIPT%
ECHO oLink.Save >> %SCRIPT%

CSCRIPT /NoLogo %SCRIPT%
DEL %SCRIPT%

程序概念基本上就是透過ECHO與重導向(Redirection)機制動態產生一個建立捷徑的VBScript並帶起執行產生捷徑,最後再把這個臨時的VBScript刪除。

或是可以直接寫一個VBScript,然後接受參數直接設定,VBScript參考如下(mkshortcut.vbs):
1
2
3
4
5
set WshShell = WScript.CreateObject("WScript.Shell" )
set oShellLink = WshShell.CreateShortcut(Wscript.Arguments.Named("shortcut") & ".lnk")
oShellLink.TargetPath = Wscript.Arguments.Named("target")
oShellLink.WindowStyle = 1
oShellLink.Save

執行
1
Mkshortcut.vbs /Target:"D:\Test.bat" /Shortcut:"Test"
即會在當前目錄下產生一個Test.lnk捷徑指向D:\Test.bat了。

2012/8/1

【Windows】切換網路位置(Network Location)

最近在嘗試WinRM網路位置必須設定為私人網路(Private Network),但先前為了安全把有線的網路位置設定為公用網路(Public Network),想要改回私人網路卻找不到哪裡可以點......。
後來搜尋了一下才知道可以透過本機安全性原則(Local Security Policy)進行修改,設定流程參考如下:
  1. 先用命令列執行control.exe /name Microsoft.NetworkandSharingCenter帶出網路和共用中心(Network and Sharing Center),找出要設定的網路名稱(假設要設定Ethernet網卡,對應網路名稱是Unidentified network)如下圖:
  2. 接著用命令列執行secpol.msc會帶出本機安全性原則(Local Security Policy)設定頁面,選擇左邊樹狀的網路清單管理員原則(Network List Manager Policies),找出對應的網路名稱(依據上一步驟得知是 Unidentified network ),滑鼠雙點該項目開啟屬性視窗,在位置類型(Location type)區域選擇想要的選項即可,參考如下圖:

2012/7/28

【Windows】SET指令的兩個妙用

Windows Command SET是很好用的一個指令, 變數的指定就要靠這支工具!
但他還有兩個我覺得挺實用的功能:
  1. 做數學運算(使用/A參數)
    基本上你想得到的數學運算大概都包了,請參考底下範例:
    1
    2
    3
    4
    5
    6
    7
    @ECHO OFF
    CLS
    
    SET /A A = (50 + 25) / 3 - 20
    ECHO (50 + 25) / 3 - 20 = %A%
    
    PAUSE
  2. 把檔案內容存到環境變數
    常常會有需求要把某檔案的內容經過程式做處理, 但處理的程式只接受參數而不會直接去開檔讀取文件內容做處理, 這時就可以使用SET /P這功能來達成需求,先看看這指令的最初用意:
    在Windows Command中可以透過SET設定環境變數,但有時候情境是需要跟使用者互動的,假設程式會先跟使用者打招呼並問使用者名字,等使用者回答後會依使用者回答的名稱做互動,參考如下範例:
    1
    2
    3
    4
    5
    6
    7
    @ECHO OFF
    CLS
    
    SET /P NAME=Hi Sir, what's your name? 
    ECHO Hello %NAME%, Welcome!
    
    PAUSE
    

    知道SET /P的用法後,此時再運用重導向(Redirect)概念就可以把檔案內的內容指定給變數了,參考如下範例:
    1
    2
    3
    4
    5
    6
    7
    @ECHO OFF
    CLS
    
    SET /P CONTENT=<A.txt
    ECHO %CONTENT%
    
    PAUSE
    

2012/7/25

【批次檔】%CD% 與 %~dp0

%CD%:Current Directory, 當前工作目錄位置
%~dp0:批次檔存在的目錄位置

請試著執行下面例子感受兩者間的差異:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@ECHO OFF
CLS

REM ================
REM == 先比較效果 ==
REM ================
ECHO ===============================================
ECHO == [Step1] 看起來沒什麼不同, 除了結尾的斜線 ...
ECHO ===============================================
ECHO %%CD%% = %CD%
ECHO %%~dp0 = %~dp0


REM ==========================
REM == 切換工作目錄再做比較 ==
REM ==========================
IF NOT EXIST TEMP MKDIR TEMP
CD TEMP
ECHO ===============================================
ECHO == [Step2] 切換工作目錄後, 發生差異了!
ECHO ===============================================
ECHO %%CD%% = %CD%
ECHO %%~dp0 = %~dp0
CD ..

:CLEAN
RMDIR /S /Q TEMP

上面例子可以明確知道:

  1. %~dp0表示批次檔所存在的位置, 是不會因切換工作目錄而改變。
  2. %CD%表示的是當前工作目錄位置, 如果用CD之類的指令切換工作目錄, 則%CD%會改變成對應的目錄。

關於%~dp0其實是%0參數的衍伸用法(可以使用CALL /?查閱詳細說明)
首先執行下面例子先看看結果:
1
2
3
4
5
6
7
8
@ECHO OFF
CLS

ECHO %%0 = %0
ECHO %%~d0 = %~d0
ECHO %%~p0 = %~p0
ECHO %%~n0 = %~n0
ECHO %%~x0 = %~x0

CALL /?的說明頁面中, 得知在參數%n(%0, %1, ... %9)之間加了波浪符號(~)與相關的修飾字詞後, 就會有擴充的支援。

  1. %0:第0個參數, 表示批次檔本身。
  2. %~d0:Dirver, 批次檔存在的磁碟機代號。
  3. %~p0:Path, 批次檔的路徑位置(不包含磁碟機代號)。
  4. %~n0:批次檔的檔案名稱。
  5. %~x0:批次檔的副檔名。
  6. 所有的修飾字詞可以混搭使用, 所以%~dp0即是批次檔所在的完整路徑。
  7. 修飾字詞還有~f, ~a, ...等, 請參考程式說明頁面。