公告

國明的網路筆記

2016年5月29日 星期日

透過BCB備份MSSQL資料庫

首先到MSSQL的資料庫(master)中建立一個「預存程序(stored procedure)」:
CREATE PROCEDURE backupdb
  @dbName varchar(10),
  @directory varchar(100)
AS
  backup database @dbName
  to disk=@directory


然後到BCB中建立一個新的專案(Project1),使用三個元件(Button1, ADOConnection1, ADOStoredProc1),請先設定ADOConnection1中的ConnectionString的屬性,使之與MSSQL連結。
其餘程式碼如下:
String __fastcall TForm1::GetSqlServerPath() // 抓取MSSQL路徑
{
  String result,tmp;

  TADOQuery *Query = new TADOQuery(this);
  Query->Connection = ADOConnection1;
  Query->Close();
  Query->SQL->Clear();
  Query->SQL->Add("select filename from sysdatabases where name='master'"); // 單引號中的master改為要備份的資料庫名稱
  Query->Open();
  tmp = Query->FieldByName("filename")->AsString;
  result = tmp.SubString(1, tmp.Length() - 15); // 取得資料庫路徑
  Query->Free();
  return result;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   String daStr = FormatDateTime("yyyy-mm-dd hh-mm-ss",Now());
  try{
     String path = Form1->GetSqlServerPath() + "backup";
     ADOStoredProc1->Close();
     ADOStoredProc1->Connection=ADOConnection1;
     ADOStoredProc1->Prepared = true;
     ADOStoredProc1->ProcedureName = "backupdb;1";
     ADOStoredProc1->Parameters->ParamByName("@dbName")->Value = "master"; // 為要備份的資料庫名稱
     ADOStoredProc1->Parameters->ParamByName("@directory")->Value = path+" \\ master" + daStr; // 此處請注意因Blog關係,請將雙引號中的空格刪除,原程式中沒有空格,若不刪除空格可能造成備份檔案路徑不正確。
     ADOStoredProc1->ExecProc();
     Application->MessageBox("備份完成", "提示", MB_OK + MB_ICONINFORMATION);
     this->Close();
   }
   catch(...){
     Application->MessageBox("備份出錯,請重新再來", "警告", MB_OK + MB_ICONWARNING);
     return;
   }
}
//---------------------------------------------------------------------------

怎樣在C++ Builder中創建使用DLL


怎樣在  C++ Builder 中使用  DLL

使用 C++ Builder 呼叫 DLL 檔有兩個方法,將 DLL 檔透過 implib.exe 這個檔案將 DLL 檔輸出成 LIB 檔,然後將 LIB 檔加入到 C++ Builder 的專案(project)中。
將 LIB 檔加入到 C++ Builder 專案後,要再做一個 H檔。有些提供 DLL 檔的廠商會一併提供 H檔,如果沒有的話,就要自己慢慢敲囉!其他的使用方法就跟 include 其他 H 檔或是 Form 類似。
或許有人會覺得這樣轉來轉去不是很麻煩嗎?但這是我個人的習慣,習慣是一種很可怕的東西,很多東西習慣了,就不想改囉!
implib.exe 可以在 C++ Builder 的安裝路徑底下找到。
使用 implib.exe 轉檔的方法:
  implib xxx.lib xxx.dll

一、創建
   使用  File|NEW 建立一個新的  DLL 工程,並保存好檔C++ Builder 會生成一個  DLL 的程式框架。
  1DllEntryPoint 函數為一個入口方法,如果使用者在  DLL 被系統初始化或者登出時被調用,用來寫入對 DLL 的初始化程式和卸載程式;參數:hinst 用來指示  DLL 的基底位址;reason 用來指示 DLL 的調用方式,用於區別多執行緒單執行緒對  DLL 的調用、創建、卸載  DLL
  2.在程式中加入自己所要創建的  DLL 過程、函數; 
  3.用  dllimport 描述出口;
  例程式如下: 
   #include 
   #pragma hdrstop 

  extern "C" __declspec(dllexport) int test(); 

  int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason,void *) 
  {
   return 1; 
  

  int test() 
  
    return 3; 
  }

 注意:動態連結程式庫中調用過程、函數時有不同的CALL方式 __cdecl__pascal, __fastcall__stdcallBCB中預設的方式為__cdecl(可不寫),如果考慮相容性可用時__stdcall聲明方法為: 
  extern "C" __declspec(dllexport) int __stdcall test();
  對於其中過程、函數也改為: 
  int __stdcall test() 

二、使用DLL 
BCB中使用DLL有兩種方法:
  1.用靜態調用法 
  首先需要在  C++ Builder 的專案中加入輸入介面庫(import library),打開工程項目,使用BCB View|Project Manager打開專案列表,向專案中加入介面庫(*.lib) 
其次在標頭檔中加入介面聲明。 
例程式如下: 
例一:
  // define in include file 
   extern "C" __declspec(dllimport) int __cdecl test(); 
  // use function in main program 
  int I 
  I=test();

例二:
  // BCB中的宣告 *.dll
  extern "C" __declspec(dllexport) __stdcall int Myfunction_Add(int x,int y)
  {
     int z = x + y;
     return z;
  }

注意:
  (1)動態連結程式庫調用過程、函數時  CALL 方式 與創建時方式一樣不寫為__cdecl,其它需要聲明。 
  (2)C++ Builder 創建的DLL有對應的輸入介面庫(import library),如只有DLL而無庫時,可用BCBimplib工具產生:implib xxx.lib xxx.dll;另外可用:tlibxxx.lib,xxx.lst 產生DLL的內建函式列表,許多Windows的未公開技術就是用這種方法發現的。 

2.動態調用法 
 動態調用法要用Windows API 中的LoadLibrary()GetProcAddress()來調入DLL庫,指出庫中函數位置,這種方法較常見。
例程式如下: 
例一:
   HINSTANCE dd; 
   int _stdcall (*ddd)(void); 
   dd=LoadLibrary("xxx.dll");
   ddd=GetProcAddress(dd,"test"); 
   Caption=IntToStr(ddd()); 
   FreeLibrary(dd);

例二:
   int (*Myfunction_Add)(int,int);
   HINSTANCE hInst=LoadLibrary("my.dll");
   if (hInst == NULL)
   {
     ShowMessage("Null");
   }
  (FARPROC &) Myfunction_Add = GetProcAddress(hInst, "Myfunction_Add");
   int c = Myfunction_Add(10,20);
   ShowMessage(c);
   FreeLibrary(hInst);

例三:C# 引用
   //載入 + 宣告
   [DllImport("d:\\my.dll")]
   public static extern int Myfunction_Add(int x,int y);
   // 使用
   int c = Myfunction_Add(10,20);
   MessageBox.Show(c.ToString());

三、注意: 
  創建DLL時編譯連結時注意設置Project Options 
  Packages標籤:去除Builder with runtime packages檢查框。 
  Linker標籤:去除Use dynamic RTL檢查框。 
  否則創建的DLL需要Runtime packages or Runtime library

調用DLL函數時出現stack overflow問題的解決辦法

調用DLL函數時出現stack overflow問題的解決辦法

為了讓BCB使用其他C++編譯器產生的DLL檔案,首先使用靜態調度DLL的方式,方法為產生BCB需要的Lib檔案(使用implib MyDLL.lib MyDLL.dll 來產生)

計畫檔加入 *.lib 後,在檔案開頭用
extern "C" __declspec(dllimport) int  SearchSolution(char* info);

宣告...

結果:當我們執行迴圈:while(SearchSolution(info)){....}  時候,且執行的東西夠大,立刻就會產生Overflow!該怎麼解決呢?

這個問題,在網路終於在一個解答,有趣的是,對方是問另一個完全不相干的問題,我就在想,該不會這有影響吧!一試下去!果然解決!!

答案....使用動態調用DLL大法!!!!

改宣告

HANDLE hdDll;

int ( *Dll_SearchSolution)(char* info);

hdDll=LoadLibrary("MainAlgorithm.dll");//使用WinAPI

Dll_SearchSolution =  (int( *)(char* info))GetProcAddress(hdDll,"SearchSolution");

接下來改使用 Dll_SearchSolution 取代原先的函數!解決!

2016年5月26日 星期四

C++ Builder 使用 DLL

DLL(Dynamic Link Library),照字面解釋為動態連結程式庫,在C++ Builder可以依使用者的需求,可將DLL用動態連結或靜態連結來使用。

靜態連結:
利用連結器把所有開發完成的應用程式模組結合起來,產生執行檔,且可直接執行這個執行檔,這種把應用程式連結成執行檔的過程就叫靜態連結,所產生的執行檔會隨程式功能的增加而越來越大,執行所佔記憶體空間也會加大,若許多不同的應用程式連結同一堆相同的程式,又會多佔了許多記憶體空間。

動態連結:
把一些經常會共用的程式碼,製作成DLL檔,執行時,若呼叫到DLL檔內包含的函數時,系統才會把DLL載入記憶體,若有許多不同的應用程式,都使用到共同的程式庫,系統只會保留一份程式碼在記憶體上。

CB開發DLL檔方法:
1.直接選[File]->[New],點選[New]頁次的DLL圖示,在選OK。
2.接著會彈出一個DLL Wizard對話盒,可選擇產生以C或C++為語法的DLL樣版程式,以及選要以BCB的VCL或Microsoft Visual C++為基礎架構。
3.按OK後,就會產生一個程式樣版。
4.再來,就是開始把要用的程式寫進去。
5.好了後,先存檔[File]->[Save],記得自己建一個自己放程式的目錄。
6.再來就是開始編輯成DLL檔啦:
  [Project]->[Build All Project]。
7.完成後,在剛存檔的目錄下,就會產生.dll檔,及.lib檔。

BCB對dll之使用方法:
方式一:(靜態連結)
1.開啟BCB並新增一個Application專案
2.選擇「File/Save Project As」將此專案更名為自己的專案名稱,並將檔案儲存到自定的目錄之下。
3.BCB有提供一個小工具,可將DLL檔轉成LIB檔。請在C:\Program\Files\Borland\Cbuilder6\Bin目錄下,可找到一個叫 IMPLIB.EXE的工具程式。
4.在命令提式字元模式(dos模式)下,用此工具程式去轉換,會產生一個副檔名為LIB的檔。
 命令格式如下:

   IMPLIB 檔名.LIB 檔名.DLL

5.轉好後,將LIB檔及DLL檔放到自定的專案儲存目錄下(若有.h檔,一起放入)
6. a.開啟 View->Project Manager
 b.選取要呼叫DLL的專案,按右鍵->Add…
 c.將剛轉好的LIB檔加入。

7.在程式前(Head)宣告要呼叫DLL檔內的哪一隻函數。
    例如:

     extern “C” __declspec(dllimport) bool __stdcall CheckString(char *pData, int iLen);

8.這樣就完成,可直接去呼叫DLL檔的函數。
    例如:

    bool ok=CheckString(input,len);

方式二:(動態連結)

不使用IMPLIB工具去轉LIB,直接去呼叫DLL檔。

1.開啟BCB並新增一個Application專案。
2.選擇「File/Save Project As」將此專案更名為自己的專案名稱,並將 檔案儲存到自定的目錄之下。
3.將DLL檔放到自定的專案儲存目錄下。
4.在程式前(Head)宣告要呼叫DLL檔內的哪一隻函數。
    例如:

   extern “C” __declspec(dllimport) void __fastcall CustomerForm(char *st);

以下為呼叫方式:

5.宣告 DLL檔內函數的指標

    void (*CustomerForm) (char *);

6.將DLL檔載入,並取得handle

    HINSTANCE hInst=LoadLibrary(“pDelphiDLL.dll”);

7.取得此DLL檔函數的位址

    (farROC &) CustomerForm=GetProcAddress(hInst,”CustomerForm”);

8.呼叫DLL檔的函數

    CustomerForm (Edit1->Test.c_str());

9.釋放DLL檔

    FreeLibrary(hInst);

2016年5月16日 星期一

各家筆電系統還原

各家筆電 系統還原快速鍵
大部份一鍵還原(硬碟還原)都是於廠商logo的畫面下按還原快速鍵
ASUS : [F9]
Acer : [Alt]+[F10]
BENQ:[F10]
HP: [F3] or [F11]
IBM(
聯想): [ThihnkVantage](前身AccessIBM)/[F11]
SONY: [F10]
TOSHIBA:
按電源鍵後出現進入BIOS選項時,按 0 開始硬碟還原
內建系統還原鍵
IBM
[F11]還原 [F6]選擇開機 [F1]BIOS 筆記型 左上角 藍色按鍵
HP/COMPAQ
[F10]還原 新機種[F2]
BENQ
[F10]
聯強
[F2]
華碩
[F9] 4種選項 一般來說都使用 2.還原到第一磁區
技嘉
[F9] ,  BIOS 畫面中  CTRL + F1 進入進階 BIOS
建達
[ALT+F12]
宏碁
[ALT+F10]
倫飛
[F4] , 按左方功能表 保護/復原 ,
Phoenix FirstWare Recover Pro,系統會重新開機 ,
Phoenix FirstWare Recover Pro Quick Start   選取備份點
Recover Pro 預設值是 原廠復原點
如果還原鍵,不可以還原你只有重新手動 安裝系統了
主要品牌筆記型電腦 NB 進入 BIOS 的方式
1. ASUS F2-BIOS, ESC-選擇開機
2. Acer, HP, SONY, Dell, Fujitsu
(啟動/重新啟動按F2
3. Toshiba
(冷開機按ESC然後按F1
4. Compaq
(開機到右上角出現閃光時按F10,或者開機時按F10
5. IBM,Thinkpad
(冷開機按F1,部分新型號可以在重新啟動時按F1
6.
絕大多數品牌(啟動/重新啟動按F2
東芝筆記本進BIOS先打開電腦電源開關,按住「ESC」,注意一定要在『In Touch with Tomorrow』出現之前,聽到「嘀」一聲,然後按F1鍵,即可進入BIOS。如果按C鍵,將顯示選擇引導途徑菜單,可以選擇從光驅、硬盤、網絡、軟盤 來引導操作系統。此方法適用於東芝TecraSatellite ProPortegeSatellite系列多數機型。