2019年7月30日 星期二

BCB6 擷取作業系統的版本

1. 了解Windows作業系統版本的號碼 : Operating System Version
2. 針對Windows8以上版本,需要使用: Version Helper functions
3. 針對Windows8以下版本,需要使用: GetVersionExA function

以下程式顯示如何取得作業系統的版本


//---------------------------------------------------------------------------
AnsiString GetSystemName()
{
    AnsiString Name=""; //先判斷是否為win8.1或win10
    typedef void(__stdcall*NTPROC)(DWORD*, DWORD*, DWORD*);
    HINSTANCE hinst=LoadLibrary("ntdll.dll");
    DWORD dwMajor, dwMinor, dwBuildNumber;
    NTPROC proc=(NTPROC)GetProcAddress(hinst, "RtlGetNtVersionNumbers");
    proc(&dwMajor, &dwMinor, &dwBuildNumber);
    dwBuildNumber&=0xffff;
    if(dwMajor==6 && dwMinor==3)    //win 8.1
    {
        Name="Microsoft Windows 8.1";
    }
    else if(dwMajor==10 && dwMinor==0)  //win 10
    {
        Name="Microsoft Windows 10";
    }
    else
    {
        //判斷win8.1以下的版本
        SYSTEM_INFO info;       //用SYSTEM_INFO結構判斷64位AMD處理器
        GetSystemInfo(&info);   //呼叫GetSystemInfo函式填充結構
        OSVERSIONINFOEX os;
        os.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);
        #pragma warning(disable:4996)
        if(GetVersionEx((OSVERSIONINFO *)&os))
        {   //下面根據版本資訊判斷作業系統名稱
            switch (os.dwMajorVersion)
            {   //判斷主版本號
                case 4:
                    switch (os.dwMinorVersion)
                    {
                        case 0:
                            if(os.dwPlatformId==VER_PLATFORM_WIN32_NT)
                                Name="Microsoft Windows NT 4.0";
                            else if(os.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
                                Name="Microsoft Windows 95";
                            break;
                        case 10:
                            Name="Microsoft Windows 98";
                            break;
                        case 90:
                            Name="Microsoft Windows Me";
                            break;
                    }
                    break;
                case 5:
                    switch(os.dwMinorVersion)
                    {
                        case 0:
                            Name="Microsoft Windows 2000";
                            break;
                        case 1:
                            Name="Microsoft Windows XP";
                            break;
                        case 2:
                            if(os.wProductType==VER_NT_WORKSTATION && info.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
                                Name="Microsoft Windows XP Professional x64 Edition";
                            else
                                Name="Microsoft Windows Server 2003";
                    }
                    break;
                case 6:
                    switch(os.dwMinorVersion)
                    {
                        case 0:
                            if(os.wProductType==VER_NT_WORKSTATION)
                                Name="Microsoft Windows Vista";
                            else
                                Name="Microsoft Windows Server 2008";
                            break;
                        case 1:
                            if(os.wProductType==VER_NT_WORKSTATION)
                                Name="Microsoft Windows 7";
                            else
                                Name="Microsoft Windows Server 2008 R2";
                            break;
                        case 2:
                            if(os.wProductType==VER_NT_WORKSTATION)
                                Name="Microsoft Windows 8";
                            else
                                Name="Microsoft Windows Server 2012";
                            break;
                    }
                    break;
            }
        }
    }
    return Name;
}
//---------------------------------------------------------------------------

[+/-] 繼續閱讀...

2019年3月28日 星期四

BCB 動態載入DLL


因應Win XP to Win 7 to Win 10的驅動程式可能使用的DLL不同,所以到網路上找了一些方法來解決。

PS. 由於BCB 6.0只支援32bit的Compiler,所以作業系統也只能同時都是32bit

1. 下載工具程式,確認DLL內的Function名稱
               DLL Export Viewer


2. 編寫軟體,目前的寫法是用來判斷是不是64位元作業系統,但是因為BCB不支援64bit,所以就算可以正常載入MN200DLL_64.dll,軟體也沒辦法執行。


#include windows.h
typedef bool(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process;
HINSTANCE hInst;

short __stdcall (*Dll_mn_open_all)(BYTE* pNumLine);

bool IsWow64()  //判斷是不是64位元作業系統
{
    int bIsWow64=0;
    //IsWow64Process is not available on all supported versions
    //of Windows. Use GetModuleHandle to get a handle to the
    //DLL that contains the function and GetProcAddress to get
    //a pointer to the function if available.
    fnIsWow64Process=(LPFN_ISWOW64PROCESS) GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
    if(NULL!=fnIsWow64Process)
    {
        if(!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
        {
            //handle error
        }
    }
    return bIsWow64;
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
    if(IsWow64())  //如果是64位元作業系統
    {
        Button1->Caption="X64";
        hInst=LoadLibrary("MN200DLL_64.dll");
        (FARPROC &)Dll_mn_open_all=GetProcAddress(hInst, "_mn_open_all");
    }
    else
    {
        Button1->Caption="X32";
        hInst=LoadLibrary("MN200DLL.dll");
        (FARPROC &)Dll_mn_open_all=GetProcAddress(hInst, "_mn_open_all@4");  //Function名稱由DLL Export Viewer裡面確認
    }

    int X=GetLastError();  //確認是否有錯誤碼
}

[+/-] 繼續閱讀...

BCB / C++ 時間相關函式




1. time :

精度只到秒,這應是最不準的計時器。

2. clock:

精度為 1/CLOCKS_PER_SEC,大多系統 CLK_TCK 為 1000,故精度為毫秒。


3. GetTickCount:

呼叫此函式時,將傳回從系統開機至當時經過多少毫秒,由於傳回值為DWORD,故最多只能計時 49.7 天

4. timeGetTime: 

此函式與 GetTickCount 解釋並無不同,但有一說 timeGetTime 精度較 GetTickCount 高,也有一說此函式實際精度只到 50ms,待查證。

5. QueryPerformanceCount / QueryPerformanceFrequency:

這應是目前精度最高之函式,精度達微秒,但在 MSDN 上亦註明,此函式若硬體不支援,將只傳回 1000,再用 GetTickCount 代替它 (如果我沒意會錯的話應為如此)。使用此函式時將較耗資源。


6. GetSystemTimeAsFileTime:

這方法較少見。FILETIME 結構體為兩個 32 位元之 unsigned integer,一個是 high , 一個是 low,所代表意義為,從 1601 年 1 月 1 日至現在時間經過了多少個 (100 ns)。精度與準度待查證。



windows平台时间函数性能比较QueryPerformanceCounter,GetTickCount,ftime,time,GetLocalTime,GetSystemTimeAsFileTime


 實際的Code,使用BCB6.0在我的i7電腦上跑出來數據如下:

[+/-] 繼續閱讀...