在 Windows 環境下,應用程式可直接呼叫 RAS API(RasDial)建立撥號連線,無需彈出系統撥號介面。本文詳細說明 RasDial 函數原型、關鍵結構體、同步/非同步模式與完整 Delphi 實作範例(C++ Builder 同樣適用)。
RasDial 函數原型
DWORD RasDial(
LPRASDIALEXTENSIONS pRasDialExtensions, // Win9x 無用,設 NULL
LPCSTR lpszPhonebook, // 電話簿路徑,Win9x 可空
LPRASDIALPARAMS lpRasDialParams, // 撥號參數結構
DWORD dwNotifierType, // 通知類型
LPVOID handle, // 回呼函數/視窗句柄
LPDWORD lphRasConn // 輸出:連線句柄
);
關鍵參數詳解
RASDIALPARAMS 結構
dwSize:結構大小 sizeof(RASDIALPARAMS)
szEntryName:撥號連線名稱(如 "163")
szUserName / szPassword / szDomain:認證資訊
szCallbackNumber / szPhoneNumber:回撥/覆蓋電話號碼
dwNotifierType 與 handle 組合
| dwNotifierType | handle 類型 | 行為 |
| 0xFFFFFFFF | HWND | 訊息發送至視窗 WM_RASDIALEVENT |
| 0 | TRasDialFunc* | 回呼函數 void CALLBACK Func(HRASCONN, UINT, DWORD, DWORD, DWORD) |
| 1 | TRasDialFunc1* | 擴展回呼 void CALLBACK Func1(HRASCONN, UINT, DWORD, DWORD, DWORD, DWORD) |
| 0 + handle=NULL | 同步模式 | 阻塞直到撥號成功/失敗返回 |
同步撥號完整範例
RASDIALPARAMS params = {0};
params.dwSize = sizeof(RASDIALPARAMS);
strcpy(params.szEntryName, "163");
strcpy(params.szUserName, "MyName");
strcpy(params.szPassword, "MyPassword");
strcpy(params.szDomain, "MyDomain");
params.szCallbackNumber[0] = '\0';
params.szPhoneNumber[0] = '\0';
DWORD dwResult, hRasConn;
dwResult = RasDial(NULL, "", ¶ms, 0, NULL, &hRasConn);
if (dwResult != 0) {
ShowMessage("撥號失敗: " + GetRasError(dwResult));
} else {
ShowMessage("撥號成功! 連線句柄: " + IntToStr(hRasConn));
// 使用 RasHangUp(hRasConn) 斷開
}
非同步模式要點
- 設定
dwNotifierType = 0,handle = RasDialFunc 回呼指標
RasDial 立即返回,撥號在背景進行
- 回呼函數接收
WM_RASDIALEVENT 類型訊息:RASCS_Connected、RASCS_Disconnected、錯誤代碼等
- 需妥善管理連線句柄生命週期,避免資源洩漏
常見錯誤代碼
| 代碼 | 含義 |
| 623 | 找不到電話簿項目 |
| 691 | 認證失敗(帳號/密碼錯誤) |
| 680 | 無撥號音/線路忙 |
| 630 | 硬體故障(Modem 未響應) |
工程應用建議
- 撥號參數建議從配置檔/註冊表讀取,避免硬編碼
- 生產環境優先使用同步模式簡化錯誤處理;需並發多線路時採用非同步
- 配合
RasEnumEntries 列舉可用連線項目,RasGetEntryDialParams 讀取預存密碼
- Windows NT/2000/XP 需適當權限;Vista+ 需 UAC 提升
掌握 RasAPI 可構建自動化備份、遠端監控、離線數據同步等無人值守網路應用。
- 上一篇文章: 進程未結束即自我刪除:Windows 經典黑科技原理解析
- 下一篇文章: 基於位操作的緩衝區類 CBitBuffer:高效二進制數據讀寫實作
Copyright ©
程式碼之家 All Rights Reserved