顯示具有 windows 標籤的文章。 顯示所有文章
顯示具有 windows 標籤的文章。 顯示所有文章

星期四, 12月 30, 2010

奇怪的skype IE plugin竟然與windows update功能相衝

拿到公司的新電腦後, 想說來執行一下windows update安裝一些patch, 結果竟然究一直卡在windows update首頁畫面不會動. 重開電腦再執行也是一樣, 在網路上找了半天也沒找到答案. 結果問題竟然是出在skype的IE plugin, 只要把它disable就好了. 真是奇怪.

星期二, 3月 17, 2009

Windows Service學習心得

Windows service與一般Windows的應用程式一樣, 也是一個執行檔. 不同的是, Windows service程式是以console application的形式在系統背景中執行. 既然Windows service是以console application的形式存在, 所以在撰寫Windows service時, source code中第一個最重要的地方就是main(), 也是整個service program的進入點.

在main中, 我們必須完成的事情很簡單, 就是將每個service的名稱以及其對應的serivce procedure註冊就好了. 方法很簡單, 就是先將SERVICE_TABLE_ENTRY的內容填好, 然後呼叫StartServiceCtrlDispatcher()就可以了.

#include <windows.h>
#include <stdio.h>

#define SLEEP_TIME 5000
#define LOGFILE "c:\\Temp\\memstatus.txt"

int WriteToLog(char* str)
{
    FILE* log;
    log = fopen(LOGFILE, "a+");
    if(log == NULL)
        return -1;
    fprintf(log, "%s\n", str);
    fclose(log);
    return 0;
}

SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;

void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService();

void main()
{
    SERVICE_TABLE_ENTRY ServiceTable[2];

    ServiceTable[0].lpServiceName = "MemoryStatus";
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
    ServiceTable[1].lpServiceName = NULL;    // 最後一個service entry table欄位必須為NULL
    ServiceTable[1].lpServiceProc = NULL;

    // Start the control dispatcher thread for our service
    StartServiceCtrlDispatcher(ServiceTable);
}

有幾點必須要說明一下, 首先, 一個service program不一定只能包含一種service, 如果有多個service, 則上列的ServiceTable陣列的element則會有多個. 只要記住最後一個element的service name和service procedure都必須為NULL表示陣列結束就可以了. 如此一來, service program就是負責作為SCM (Service Configuration Manager)與service之間溝通的橋樑, 也就是所謂的control dispatcher, 負責將SCM傳送過來的request傳遞給相對應的service, 並且監控service的執行.

另外, SCM啟動service program後, 必須在30秒內呼叫StartServiceCtrlDispatcher(), 否則會回報為啟動錯誤. 所以如果每個service的啟動有一些啟動程序必須執行, 應該寫在service procedure中, 也就是上例中的ServiceMain.

ServiceMain是service的entry point, 也就是我們在service program中為每個service所註冊的service procedure. 每個service的service procedure會由dispatcher產生一個新的thread來執行. 在service procedure中我們首先必須盡快為service註冊control handler, 也就是呼叫RegisterServiceCtrlHandler()來註冊該service名稱所對應的service control handler. 不管service的狀態是否有改變, 在control handler中都要回報service status, 透過呼叫SetServiceStatus()回報service status給SCM.

void ServiceMain(int argc, char** argv)
{
    int error; 

    
    hStatus = RegisterServiceCtrlHandler("MemoryStatus", (LPHANDLER_FUNCTION)ControlHandler);
    if(hStatus == (SERVICE_STATUS_HANDLE)0)
    {
        // Registering Control Handler failed
        return;
    }
   
    ServiceStatus.dwServiceType = SERVICE_WIN32;
    ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    ServiceStatus.dwWin32ExitCode = 0;
    ServiceStatus.dwServiceSpecificExitCode = 0;
    ServiceStatus.dwCheckPoint = 0;
    ServiceStatus.dwWaitHint = 0;
    SetServiceStatus(hStatus, &ServiceStatus);

    // Initialize Service
    error = InitService();
    if(error)
    {
        // Initialization failed
        ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        ServiceStatus.dwWin32ExitCode = -1;
        SetServiceStatus(hStatus, &ServiceStatus);
        return;
    }

    // We report the running status to SCM.
    ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    SetServiceStatus(hStatus, &ServiceStatus);

    MEMORYSTATUS memory;
    // The worker loop of a service
    while(ServiceStatus.dwCurrentState == SERVICE_RUNNING)
    {
        char buffer[16];
        GlobalMemoryStatus(&memory);
        sprintf(buffer, "%d", memory.dwAvailPhys);

        int result = WriteToLog(buffer);
        if(result)
        {
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            ServiceStatus.dwWin32ExitCode = -1;
            SetServiceStatus(hStatus, &ServiceStatus);
            return;
        }

        Sleep(SLEEP_TIME);
    }
    return;
}

// Service initialization
int InitService()
{
    int result;
    result = WriteToLog("Monitoring started.");
    return result;
}

在service control handler中, 會針對SCM所送出的request呼叫相對應的處理程式. 可以接受的request種類則是在ServiceMain註冊service control handler時所設定. 基本上SERVICE_CONTROL_STOP和SERVICE_CONTROL_SHUTDOWN的處理方式一樣, 用來關閉service, 差別在於SERVICE_CONTROL_SHUTDOWN是在系統關機時, 由SCM發送給每個service.

void ControlHandler(DWORD request)
{
    switch(request)
    {
        case SERVICE_CONTROL_STOP:
            WriteToLog("Monitoring stopped.");
            ServiceStatus.dwWin32ExitCode = 0;
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus(hStatus, &ServiceStatus);
            return;
        case SERVICE_CONTROL_SHUTDOWN:
            WriteToLog("Monitoring stopped.");
            ServiceStatus.dwWin32ExitCode = 0;
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus(hStatus, &ServiceStatus);
            return;
        default:
            break;
    }

    // Report current status
    SetServiceStatus(hStatus, &ServiceStatus);
}

要安裝service可以利用系統提供的command line utility, 如下所示. 要注意的是, binpath=後面必須有一個空格.

sc create MemoryStatus binpath= c:\Temp\MemoryStatus.exe

要刪除service也同樣可以使用系統提供工具, 如下所示.

sc delete MemoryStatus

 

參考資料:

在Windows XP上安裝Windows CE模擬器出現錯誤

安裝Microsoft eMbedded Visual C++在Windows XP上時出現了"虛擬 PC / Windows CE 模擬器' 將造成 Windows 變得不穩定。 Windows 已禁止載入這些驅動程式。"這個訊息, 則無法開啟Windows CE模擬器來測試所撰寫的Windows CE程式. 要解決這個問題很簡單, 只要稍微修改一下C:\Boot.ini這個檔案的內容就可以了. 修改步驟如下:

  1. 在桌面上"我的電腦"的圖示上按滑鼠右鍵, 選擇內容開啟"系統內容"
  2. 選擇"進階"頁面
  3. 在視窗下方的"啟動及修復"方塊中按一下"設定"
  4. 在出現的"啟動及修復"視窗中按一下"編輯"
  5. 然後將"/noexecute=optin"刪除, 並加上"/execute"
  6. 存檔後重新開機就大功告成了

參考資料:

星期日, 5月 18, 2008

讓Visual Studio 2005編譯出來的程式可以拿到沒有安裝VS2005的電腦上執行的方法

使用Visual Studio 2005所開啟Win32專案 或是Win32主控台控制專案,如果把所編譯的執行檔拿到沒有安裝.Net framework的電腦上去執行,不管是debug或是release組態的執行檔,都會出現應用程式設定不正確的錯誤訊息:

e1

本來還以為是Visual Studio 2005不支援編譯native code,可是又覺得怪怪的。經過一番研究之後,終於發現其實問題是出在專案的組態設定而已。

在Visual Studo 2005中建立Win32專案或是Win32主控台控制專案,在專案屬性設定視窗中的組態屬性->C/C++->程式碼產生設定頁,有一個設定是設定程式執行時程式庫的連結方式,在Debug組態預設是/MDd,image

而Release組態則預設是/MD。

image

要解決這個問題就是只要將Debug組態的/MDd改成/MTd,Release組態的/MD改成/MT,問題就迎刃而解了。 因為改成/MTd或是/MT的程式碼產生方式,會將程式所需要的MSVCRxx.dll改以static linking的方式編譯,非以dynamic linking的方式,所以程式執行時並不需要去找相關的dll檔案。

不過這樣做,會使執行檔的檔案大小變大一些些喔。

星期六, 5月 17, 2008

一些open source的網站

Microsoft Windows相關的
http://www.codeplex.com/
http://www.codeproject.com/
http://www.codeplex.com/C4FDevKit
http://www.microsoft.com/express/default.aspx

其他
http://www.sourceforge.net/
http://csourcesearch.net/
http://www.koders.com/

CodeGuru

星期二, 4月 22, 2008

安裝wireshark出現npf.sys無法寫入的解決辦法

今天聽同事說他要安裝wireshark可是會出現npf.sys無法寫入的問題,覺得很奇怪,自己電腦上就有裝wireshark阿。所以就把之前安裝的給移除掉再重裝一次。嘿嘿,還真的會出現無法寫入npf.sys的錯誤訊息。
可是npf.sys是用來捉取網路封包必要的驅動程式,不安裝是絕對不行的。習慣當黑手的我本著不服輸的精神,在網路上google了十幾分鐘,就是找不到解決方法。
竟然google不到,那就自己想辦法解決了囉。試了一些方法之後,突然靈機一動,想說如果遇到無法移除檔案時都會進保護模式去移除檔案,那是不是可以如法炮製,進保護模式去安裝winpcap試試看。
嘿嘿!果然,這個方法是行的通的。只要開機時按F8進保護模式後,經過漫長的開機過程後,在進行winpcap的安裝,果然就解決了無法寫入npf.sys的問題了。
這個問題應該是趨勢科技出的office scan覺得這個安裝動作是病毒的行為擋掉的,因為我自己的電腦安裝wireshark沒有出現這樣的問題,雖然也有安裝防毒軟體avast antivirus。

星期四, 4月 17, 2008

讓Office 2003可以讀取Office 2007的檔案

如果要讓Office 2003讀取Office 2007所編輯的Word、Excelc或是Powerpoint檔案,你只要安裝微軟所出的Microsoft Office Word、Excel 及 PowerPoint 2007 檔案格式相容性套件就可以輕鬆解決這個問題了。安裝步驟很簡單:

首先你可以直接以Office 2003開啟該檔案,此時會出現如下的畫面



你只要按下確定按鈕就會連到該套件所在的網頁了,如下圖所示。



如過出現的是英文畫面不需要緊張,只要在紅色圈圈所標示的地方,改選成Chinese(Traditional)就可以切換到中文畫面了,如下圖所示。



按下下載按鈕就可以下載安裝套件了。下載完畢後,執行該檔案安裝成功後就大功告成了。

當然你可以直接到Microsoft Office Word、Excel 及 PowerPoint 2007 檔案格式相容性套件的網頁下載安裝檔回來直接安裝就可以了。

星期二, 4月 01, 2008

Windows Device Driver學習筆記1

咦!? 才剛剛才寫完開疆計, 怎麼馬上就有學習筆記可以寫了!! 根本是在裝肖維!!

呵呵! 其實就趁自己對這個題目還很熱(台語), 趕緊寫下我的第一篇學習筆記囉. 這樣萬一以後又半途而廢了, 總不會什麼成果都沒有留下來. (叩! 不準在半途而廢了!)

好啦! 不多說廢話了, 趕緊開始Windows驅動程式學習的第一步了.

要學習驅動程式設計, 除了找些文件或是相關書籍來看之外, 最重要的就是建立一個可以讓你撰寫驅動程式的環境了. 而要撰寫Windows驅動程式, 當然是直接拿微軟官方所出的驅動程式開發套件 (Driver Development Kit)來用囉. 一般來說, 要進行驅動程式的開發需要用到兩台電腦, 一台是用來進行開發驅動程式以及除錯用的, 另外一台則是用來安裝以及執行所開發的驅動程式. 需要兩台的原因很簡單, 因為新開發的驅動程式還不是很穩定 (應該不會有這麼神的人寫完程式都不會有bug的吧), 再加上驅動程式是與作業系統緊密結合, 所以只要一出錯很容易就會造成系統當機, 如果嚴重一點還有可能會使得整台電腦都無法在開機, 必須重新安裝作業系統. 因此為了避免資料因為開發驅動程式而損毀, 一般還是建議使用兩台電腦來開發比較好.

接下來就是要進行DDK的安裝程序

  1. 在要開發驅動程式的電腦上執行DDK的setup.exe, 相信這個步驟對大部分的Windows使用者應該很簡單吧. 這裡唯一要注意的是, 安裝的目錄名稱不要出現有空白, 不然會有些問題.
  2. 安裝debugger. 在Windows DDK中有一個debuggers的目錄, 在裡面你可以找到debugger的安裝檔案, 裡面有32-bit以及64-bit的版本, 根據你所要開發的作業系統版本來選擇你所要安裝的debugger.
  3. 安裝完畢後, 再進行DDK安裝的驗證, 看看有沒有正確安裝好DDK. 步驟很簡單, 選擇一個build environment, 在所選擇的build environment的命列環境執行build -cZ, 這時候會將步驟一已經安裝的範例驅動程式進行編譯的動作. 如果可以正確編譯, 代表DDK已經有安裝成功了.

好了, 看完以上的介紹, 趕快行動吧!!

星期四, 9月 06, 2007

好用又免費的燒錄軟體 - InfraRecorder

CD或是DVD已經成為我們日常生活中不可或缺的資料備份媒體, 大部分的人也大概都有燒錄器. 一搬來說, 現在買燒錄器時都會附上一套燒錄程式, 而且幾乎都是鼎鼎大名的Nero, 可是我的Sony VAIO SZ 38就是沒有給我隨機附贈Nero, 而我很不想安裝沒有版權的軟體, 所以只好又得google一下, 看看網路上有哪些不錯的免費軟體可以使用囉.

還好, 皇天不負苦心人(當然再加上google的大力幫忙), 終於讓我找到了一個還不錯的燒錄軟體可以用, 那就是InfraRecorder.

這套軟體的使用介面相當簡單好用, 而且又同時支援燒錄CD與DVD, 更讚的是, 還是open source. 真是俗又大碗! 推薦大家可以多多使用.

相關連結:
InfraRecorder
Nero
Sony VAIO SZ 38

星期日, 8月 26, 2007

推薦好用又免費的錄音以及編輯軟體Audicity

曾經使用過許多錄音軟體, 雖然用起來都還不錯, 可是很多錄音軟體
(例如: Windows內建的錄音程式)的錄音格式無法儲存成mp3格式, 所以通常都會佔用很大的硬碟空間. 雖然現在硬碟很便宜, 空間又大, 可是檔案大畢竟就是不容易備份, 而且有些錄音軟體還都有錄音時間限制, 用起來實在是非常不方便. 在這裡跟大家推薦一個好用, 免費又open source的錄音軟體, Audacity.

推薦這套軟體有一個很重要的原因, 因為Audicity是可以同時在Windows以及Linux上執行的軟體, 甚至是MAC OS X(我沒有MAC, 所以沒試過). 這一直是我找尋軟體一個很重要的因素之一, 畢竟大部分都的user是很懶的, 都希望學會一招後就"行騙"天下.

另外, Audicity還可以直接以mp3格式儲存錄音內容, 減少錄音檔案所佔用的硬碟空間. 不過, Audicity預設是沒有這個功能, 要再安裝MP3 encoder才可以有這個功能. 還好這個步驟非常簡單, 只要下載MP3 encoder外掛即可:

  1. 首先先至http://lame.buanzo.com.ar/下載libmp3lame-win-3.97.zip這個檔案.
  2. 將下載的libmp3lame-win-3.97.zip解開
  3. 接著就可以使用Audicity進行錄音的動作
  4. 錄音完畢後, 選擇檔案->匯出為MP3, 將檔案轉存成MP3
  5. 這時候會出現視窗請你告訴Audicity所要使用的LAME MP3 Encorder檔案在哪裡
  6. 選擇Yes, 並找出在步驟2所解開的lame_enc.dll即可

最後, 除了前面所介紹的錄音功能之外, Audicity還可以對錄音檔案進行編輯的動作, 不過這部分小弟不太需要用到, 所以沒有用過, 無法為各位介紹囉, 真是不好意思.
相關連結:

好用又免費的虛擬桌面工具

你是不是常常因為開啟了一大堆程式, 而必須在一大堆視窗中找尋某個你要用的程式呢? 當你的"事業"越作越大, 視窗越開越多時, 這時候虛擬桌面就可以幫助你將你所開啟的視窗分類, 每次只顯示出相關的視窗, 其他與目前工作無關的視窗就可以暫時隱藏起來.

在Linux上虛擬桌面幾乎是每個desktop manager都一定會提供的功能, 可是在Windows上則沒有了. 其實再Windows上也是有一堆好用又免費的虛擬桌面軟體可以用的, 在這裡我跟大家推薦一個我自己覺得用起來還不錯的虛擬桌面軟體dexpot.

dexpot這套虛擬桌面軟體允許你最多有20個虛擬桌面, 相信這對大部分的使用者來說都已經夠用了. 而且每個虛擬桌面可以設定個別的密碼保護, 避免別人偷偷切換你的虛擬桌面, 偷看你在做什麼. 每個虛擬桌面也可以各自設立桌布, 讓你可以在處理不同事情, 根據事情的特性使用不同的桌布. 還有, 還可以設定hot key, 快速切換桌面, 以免做壞事被抓包喔.


相關連結:
dexpot

星期三, 8月 22, 2007

好用又免費的電子字典

在閱讀英文文件時,我們常常需要電子字典來協助我們。想到電子字典軟體,相信大部分的人應該就會直接聯想到Dr. Eye譯點通這套軟體吧。這套軟體的功能非常強大,可以進行多國語言的翻譯、真人發音、整篇文章翻譯等等,實在是一套不可多得的軟體。而且,重點是,Dr. Eye每個月都會有新增的字庫可以加入,真是讓人有物超所值的感覺呢!
可是,De. Eye畢竟是一套商業軟體,是要花錢購買的。對於沒有此預算,可是又有此需求的人,那該怎麼辦?其實,有一套功能很接近Dr. Eye的免費軟體可以供大家使用,就是StarDict

StarDict是一套open source的軟體,而且又同時支援Windows與Linux作業系統,還可以自行新增字典字庫,實在是一套不錯的軟體。當然,除了基本字典查功能之外,StarDict也跟Dr. Eye一樣,支援即時翻譯,也就是滑鼠到哪就自動翻譯滑鼠所指的字。而且,從3.0版開始,更支援了全文翻譯的功能,強力推薦這套軟體。

相關連結:

星期二, 8月 21, 2007

免費產生pdf的工具

在日常生活中,pdf檔案格式出現的機率越來越多,不管在Windows或是Linux上,都已經有不錯的pdf reader讓我們閱讀pdf文件,例如:在Linux上的evince、xpdf以及Linux版的Acorbat reader,在Windows上有Adobe Acrobat reader、Foxit reader等。

可是,如果是要產生出pdf格式的文件,在Linux當然也有許多免費好用的工具可以使用。但是,在Windows上,以往大家可能都是使用Adobe Acrobat。可是這是一套商業軟體,要錢的,如果沒錢買的話,其實可以使用一些免費的軟體,也都不錯喔。

在這裡推薦一下CutePDF Writer。這是一套商業軟體,不過重點是,它是免費的,所以大家可以安心使用。而且不會在所產生的pdf檔案上,留下任何的watermark,是一套相當不錯的pdf產生工具。

相關連結:

檔案比較工具

當我們需要比對兩個檔案的內容時,在Linux上,常常第一個想到的就是diff這個文字模式的工具。這個雖然牌子老、信用好,但是缺乏了圖形化介面總是比較不那麼方便。其實,我們可以有許多其他的選擇,例如:tkdiff、fldiff。


tkdiff是diff的圖形化front-end,其本質上仍然是使用diff進行檔案比比對的動作,只是幫diff包了一個漂亮的圖形外觀。除此之外,tkdiff還可以進行檔案merge的動作。還有一點值得特別強調一下,就是tkdiff不只可以對一般檔案進行比比對,也可以對source control system中的檔案進行比對動作。
tkdiff的使用方法很簡單,可以只輸入tkdif進入interactive模式,直接選取要比對的檔案,或是在命令列直接輸入要比較即可。

fldiff也是一個圖形化的檔案比對工具,其基本功能跟tkdiff差不多,都是可以比較一般的檔案以及source control system中的檔案。不過fldiff比tkdiff多了一個目錄內容比對功能,就是可以指定兩個目錄,然後針對目錄中相同名稱的檔案進行內容比對的功能。

tkdiff有已經編譯好的Windows版本,fldiff需要自己編譯。


相關連結:

星期二, 8月 07, 2007

trace samba source code 心得筆記 4

用windows client在測試與samba server連線時,發現windows會將之前的資訊cache起來,所以如果是DFS referral則不會再重新發TRANSACT2_GET_DFS_REFERRAL請求,跟samba server要檔案真正所在位置的資訊,而是直接利用其cache的資訊對檔案真正所在的samba server發出request。