Remote Data Module無法註冊到系統的問題 |
答題得分者是:jow
|
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
我的系統是Win2003 + C++ Builder 2010 / BCB6
我開了一個Remote Data Module的專案之後,執行該專案 如果是winxp時,這個專案會自動在DCOM註冊,但是在Win2003卻無法註冊。 同樣的情況在Delphi 2010也是一樣無法註冊… 不過 網路上有這樣的一個解法 [code delphi] TComponentFactory.Create(ComServer, TXOtecDbRemoteServer, Class_XOtecDbRemoteServer, ciMultiInstance, tmApartment); ComServer.UpdateRegistry(True); [/code] 使用之後的Delphi Remote Data Module就可以順利註冊上DCOM。 不過在C Builder的專案中找不到上述的宣告。 請問這個問題該怎麼解呢? 還是說CB只能用手動註冊的方式來註冊呢? 1.Select Start » Run. 2.Type the following in the dialog box that appears: Where (e.g., C:\TestStand\Bin\REngine.exe /RegServer).
這個方法可以註冊上,但Clent端可以查到Server,卻無法連線到Server 還請各位大大幫忙~~~ |
jow
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
改寫自 tregsvr.exe 的source code
提供你參考...^_^ [code delphi] unit uTheRegisterServer; interface uses SysUtils, Windows, Dialogs, ActiveX, ComObj; function DoRegisterServer(FileName: string): Boolean; function DoUnregisterServer(FileName: string): Boolean; implementation resourcestring SNeedFileExt = 'You must specify a file extension for "%s"'; SRegStr = 'registered'; SUnregStr = 'unregistered'; type TRegType = (rtAxLib, rtTypeLib, rtExeLib); TRegAction = (raReg, raUnreg); TRegProc = function : HResult; stdcall; TUnRegTlbProc = function ( const libID: TGUID; wVerMajor, wVerMinor: Word; lcid: TLCID; syskind: TSysKind): HResult; stdcall; const ProcName: array[TRegAction] of PChar = ('DllRegisterServer', 'DllUnregisterServer'); ExeFlags: array[TRegAction] of string = (' /regserver', ' /unregserver'); var RegType: TRegType = rtAxLib; RegAction: TRegAction = raReg; QuietMode: Boolean = False; FileName: string; RegProc: TRegProc; LibHandle: THandle; OleAutLib: THandle; UnRegTlbProc: TUnRegTlbProc; TheParamStr: array[0..2] of string; TheParamCount: Integer; procedure OutputStr(S: string); begin if not QuietMode then begin CharToOEM(PChar(S), PChar(S)); ShowMessage(S); end; end; function DecodeOptions: Boolean; var i: Integer; FileStart: Boolean; Param, FileExt: string; begin Result := False; if TheParamCount = 0 then Exit; FileName := ''; for i := 0 to TheParamCount-1 do begin Param := TheParamStr[i]; FileStart := not (Param[1] in ['-', '/']); if FileStart then begin if FileName = '' then FileName := Param else FileName := FileName ' ' Param; // strip open and/or close quote if present if (FileName[1] = '"') then begin if (FileName[Length(FileName)] = '"') then FileName := Copy(FileName, 2, Length(FileName) - 2) else if FileName[1] = '"' then Delete(FileName, 1, 1); end; end else begin if Length(Param) < 2 then Exit; case Param[2] of 'U', 'u': RegAction := raUnreg; 'Q', 'q': QuietMode := True; 'T', 't': RegType := rtTypeLib; end; end; end; FileExt := ExtractFileExt(FileName); if FileExt = '' then raise Exception.CreateFmt(SNeedFileExt, [FileName]); if RegType <> rtTypeLib then begin if CompareText(FileExt, '.TLB') = 0 then RegType := rtTypeLib else if CompareText(FileExt, '.EXE') = 0 then RegType := rtExeLib else RegType := rtAxLib; end; Result := True; end; function RegisterAxLib: Boolean; begin Result := False; LibHandle := LoadLibrary(PChar(FileName)); if LibHandle <> 0 then try @RegProc := GetProcAddress(LibHandle,ProcName[RegAction]); Result := (@RegProc <> nil) and (RegProc = 0); finally FreeLibrary(LibHandle); end; end; function RegisterTLB: Boolean; var WFileName, DocName: WideString; TypeLib: ITypeLib; LibAttr: PTLibAttr; DirBuffer: array[0..MAX_PATH] of char; begin Result := False; if ExtractFilePath(FileName) = '' then begin GetCurrentDirectory(SizeOf(DirBuffer), DirBuffer); FileName := '\' FileName; FileName := DirBuffer FileName; end; if not FileExists(FileName) then EXIT; WFileName := FileName; OleCheck(LoadTypeLib(PWideChar(WFileName), TypeLib)); OleCheck(TypeLib.GetLibAttr(LibAttr)); try case RegAction of raReg: begin OleCheck(TypeLib.GetDocumentation(-1, nil, nil, nil, @DocName)); DocName := ExtractFilePath(DocName); OleCheck(RegisterTypeLib(TypeLib, PWideChar(WFileName), PWideChar(DocName))); Result := True; end else begin OleAutLib := GetModuleHandle('OLEAUT32.DLL'); if OleAutLib <> 0 then begin @UnRegTlbProc := GetProcAddress(OleAutLib, 'UnRegisterTypeLib'); if @UnRegTlbProc <> nil then with LibAttr^ do begin OleCheck(UnRegTlbProc(Guid, wMajorVerNum, wMinorVerNum, LCID, SysKind)); Result := True; end; end; end; end; finally TypeLib.ReleaseTLibAttr(LibAttr); end; end; function RegisterEXE: Boolean; var SI: TStartupInfo; PI: TProcessInformation; begin FillChar(SI, SizeOf(SI), 0); SI.cb := SizeOf(SI); Result := SysUtils.Win32Check( CreateProcess(PChar(FileName), PChar(FileName ExeFlags[RegAction]), nil, nil, True, 0, nil, nil, SI, PI)); CloseHandle(PI.hThread); CloseHandle(PI.hProcess); end; function DoRegisterServer(FileName: string): Boolean; begin Result := False; if FileExists(FileName) then try TheParamStr[0] := '-q'; TheParamStr[1] := FileName; TheParamCount := 2; if DecodeOptions then begin case RegType of rtAxLib: Result := RegisterAxLib; rtTypeLib: Result := RegisterTLB; rtExeLib: Result := RegisterEXE; end; end; except on E:Exception do OutputStr(E.Message); end; end; function DoUnregisterServer(FileName: string): Boolean; begin Result := False; if FileExists(FileName) then try TheParamStr[0] := '-q'; TheParamStr[0] := '-u'; TheParamStr[1] := FileName; TheParamCount := 2; if DecodeOptions then begin case RegType of rtAxLib: Result := RegisterAxLib; rtTypeLib: Result := RegisterTLB; rtExeLib: Result := RegisterEXE; end; end; except on E:Exception do OutputStr(E.Message); end; end; end. [/code] |
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
jow
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
|
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
Client端程式註冊到server的方式不是只要利用DCOM/SOCKET/WEBCONNECTION,就可以找到server端裡所註冊好的Remote Data Module嗎?
但現在的情況是Server端裡的Remote Data Module無法註冊到Server內,不知道這個方法是否可以解決這個問題呢? 我剛剛在「TCRemoteDataModule」裡有看到下面的原式 __classmethod virtual void __fastcall UpdateRegistry(bool Register, const System::UnicodeString ClassID, const System::UnicodeString ProgID); 與DELPHI的有些許不同,不過函式裡的參數:ClassID, ProgID我就不知道要如何取得了…… ===================引 用 jow 文 章=================== 我個人的做法是在Client端程式中 functionDoRegisterServer(FileName:string):Boolean;use 這個改寫的 source unit (uTheRegisterServer) 再直接呼叫 functionDoUnregisterServer(FileName:string):Boolean; 另外, 你也可以先在Client端程式中 直接執行外部程式tregsvr.exe 測試看看 個人做法,謹供參考 ![]() |
jow
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
關於 COM/DCOM based program
一般而言,在程式散發(distribute)時,必須在Client 端註冊 server 所宣告(declare)並定義/實作好的(define/implement) 的介面 以下是個人的一些經驗: a. in-process server: 使用tregsvr.exe 或 regsvr32.exe來註冊,相關dll必須存在Client端 b. out-of-process server: 使用tregsvr.exe 或 將server程式執行一次(好像可以加上參數, 只做註冊動作) c. out-of-process server 若為TAppServer, 並使用TSocketConnection連接,則Client端不需要註冊動作 另外,上述註冊的動作,應該也可以只使用*.TLB 來登錄相關的介面資訊(這方面個人尚未測試過) 最後,關於Server程式無法註冊的狀況 個人在Win7中使用時,必須以管理員身分執行 請確認是否由此原因所致 個人一些經驗, 謹供參考 ![]() ===================引 用 GrandRURU 文 章=================== Client端程式註冊到server的方式不是只要利用DCOM/SOCKET/WEBCONNECTION,就可以找到server端裡所註冊好的Remote Data Module嗎? 但現在的情況是Server端裡的Remote Data Module無法註冊到Server內,不知道這個方法是否可以解決這個問題呢? 我剛剛在「TCRemoteDataModule」裡有看到下面的原式 __classmethod virtual void __fastcall UpdateRegistry(bool Register, const System::UnicodeString ClassID, const System::UnicodeString ProgID); 與DELPHI的有些許不同,不過函式裡的參數:ClassID, ProgID我就不知道要如何取得了…… |
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
//------Win2000 Pro + BCB6
我在Win2000 pro時有先用BCB6來try過。 DB, AP在同一台 AP在REMOTE DATA MODULE設定好時有先執行過一次(註冊在DCOM中) Client則有測過: DCOM: 自機編/連線 區網連線 Scoket: 自機編/連線 區網連線 外網連線 WebConnection: 自機編/連線 Client端撰寫時有先把DCOM/SocketConnection連上AP端,會得到ServerName,然後也會得到ServerGUID。 //------Win2003 RAD 2010 Win2003則是以Administrator身份登入(剛安裝好也只有Admin身份) Remote Data Module設定好之後也執行過一次(註冊,但實際上卻沒註冊到server的dcom中) client同樣使用上述三者連線元件,皆找不到ServerName, ServerGUID JOW大的處理方式好像都是針對client做處理 但如果Remote Data Module一直無法順利註冊到DCOM中…… 不知JOW大的方法是否這樣就可以無視這個問題而正常使用呢? 同樣的情況,在delphi中只要以開頭的解法就可以順利解決了唷! 想不透平平是姐妹品,為何會差這麼多…… ===================引 用 jow 文 章=================== 關於 COM/DCOM based program 一般而言,在程式散發(distribute)時,必須在Client 端註冊 server 所宣告(declare)並定義/實作好的(define/implement) 的介面 以下是個人的一些經驗: a. in-process server: 使用tregsvr.exe 或 regsvr32.exe來註冊,相關dll必須存在Client端 b.out-of-process server: 使用tregsvr.exe 或 將server程式執行一次(好像可以加上參數, 只做註冊動作) c. out-of-process server 若為TAppServer, 並使用TSocketConnection連接,則Client端不需要註冊動作 另外,上述註冊的動作,應該也可以只使用*.TLB 來登錄相關的介面資訊(這方面個人尚未測試過) 最後,關於Server程式無法註冊的狀況 個人在Win7中使用時,必須以管理員身分執行 請確認是否由此原因所致 個人一些經驗, 謹供參考 ![]() |
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
shchen
一般會員 ![]() ![]() 發表:12 回覆:27 積分:7 註冊:2003-08-13 發送簡訊給我 |
我也是剛開始改用RAD 2010內的C++ Builder 2010,我也遇到Remote Data Module不會像C++Builder 6 編出的DCOM Server 端程式,執行EXE就會自動注冊,在李維 老師所著的Delphi 4.X 實戰扁1內也是說會自動注冊DCOM Interface.
真奇怪,BCB 6可自動注冊,而BCB 2010卻無法自動注冊,翻遍資料,查到對於進程外的COM 伺服器(EXE or DLL),要使用命令列下的 xxx.EXE /regserver,來注冊,但很像也不是很完整,注冊後在注冊表內的GUID是有了,而DCOMConnection1 的ServerName屬性也出現了注冊的DCOM Server,但我將ClientDataSet1->Activer設為true是就不斷的給我報錯 " ClientDataSet1: Missing data provider or data packet " 氣死我了,卡了4天,還沒解決,還是該維持用BCB6嗎?? 最後發現是自己搞烏龍,Remote Data module 上的TQuity 沒有設SQL String,沒有命令導致的啦. |
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
你有下DataSetProvider物件嗎?
===================引 用 shchen 文 章=================== 我也是剛開始改用RAD 2010內的C Builder 2010,我也遇到Remote Data Module不會像C Builder 6 編出的DCOM Server 端程式,執行EXE就會自動注冊,在李維 老師所著的Delphi 4.X 實戰扁1內也是說會自動注冊DCOM Interface. 真奇怪,BCB 6可自動注冊,而BCB 2010卻無法自動注冊,翻遍資料,查到對於進程外的COM 伺服器(EXE or DLL),要使用命令列下的 xxx.EXE /regserver,來注冊,但很像也不是很完整,注冊後在注冊表內的GUID是有了,而DCOMConnection1 的ServerName屬性也出現了注冊的DCOM Server,但我將ClientDataSet1->Activer設為true是就不斷的給我報錯 " ClientDataSet1: Missing data provider or data packet " 氣死我了,卡了4天,還沒解決,還是該維持用BCB6嗎?? |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |