我有一個需要通過遠程桌面服務運行的Delphi程序。我應該注意什麼會阻止它正常運行?爲了「支持」遠程桌面服務,應用程序需要做些什麼?
回答
除了上述問題的答案,也看到我的回答這個問題:Does anyone know about issues between Citrix and Delphi 2007 applications? (And perhaps other development languages?)
編輯:在我的博客,我對應用程序兼容性問題caterogy,它們是表現不好的應用程序的真實故事在RDS /思傑。可能是有用的檢查出來:http://www.remkoweijnen.nl/blog/topics/application-compatibility/
其他類,可能是令人感興趣的是http://www.remkoweijnen.nl/blog/topics/citrix/和http://www.remkoweijnen.nl/blog/topics/terminalserver/雖然不是所有的,可以申請你的問題。
2日編輯:您可以使用來自微軟的標準用戶分析器工具來檢查,如果您的應用程序適用於由一個普通用戶的身份運行(MS側重於UAC,但在一個典型的RDS或Citrix服務器只有低特權用戶)。 http://technet.microsoft.com/en-us/library/cc765948(WS.10).aspx
Double buffering就是這樣一種東西。
通常雙緩衝是一件好事,我一直都在使用它。請參閱我的組件(1),(2)和(3)。它們都是雙緩衝的,因此完全沒有閃爍(並且易於實現),但是如果遠程運行它,則必須發送位圖而不是GDI命令,所以它可能相當慢(並且不經濟)。
安德烈亞斯在指針式雙緩衝中是正確的。這是我意識到的最重要的考慮因素。
作爲一個溫和的反面,我不喜歡雙緩衝,因爲它很難讓它正確。許多組件不成功。我正在考慮VCL下拉列表框,這些列表框在Windows Basic下不能正確繪製。還有其他人!
但是有些控件確實需要雙緩衝來避免閃爍,所以你會怎麼做?當用戶本地連接時,您希望獲得雙緩衝的好處,但您不希望在遠程時使用網絡帶寬徵稅。
所以,這裏是我做的:
procedure WMWTSSessionChange(var Message: TMessage); message WM_WTSSESSION_CHANGE;
procedure TBaseForm.WMWTSSessionChange(var Message: TMessage);
begin
case Message.WParam of
WTS_CONSOLE_DISCONNECT,WTS_REMOTE_DISCONNECT,
WTS_SESSION_LOCK,WTS_SESSION_LOGOFF:
SessionDisconnected;
WTS_CONSOLE_CONNECT,WTS_REMOTE_CONNECT,
WTS_SESSION_UNLOCK,WTS_SESSION_LOGON:
SessionConnected;
end;
inherited;
end;
function WTSRegisterSessionNotification(hWnd: HWND; dwFlags: DWORD): BOOL; stdcall; external 'Wtsapi32.dll';
function WTSUnRegisterSessionNotification(hWnd: HWND): BOOL; stdcall; external 'Wtsapi32.dll';
const
NOTIFY_FOR_THIS_SESSION = 0;
NOTIFY_FOR_ALL_SESSIONS = 1;
procedure TBaseForm.CreateWnd;
begin
inherited;
WTSRegisterSessionNotification(WindowHandle, NOTIFY_FOR_THIS_SESSION);
end;
procedure TBaseForm.DestroyWnd;
begin
WTSUnRegisterSessionNotification(WindowHandle);
inherited;
end;
在我的應用形式從TBaseForm
下降,因此繼承了這種行爲。 SessionConnected
和SessionDisconnected
方法是virtual
,因此各個表單可以採取特定的操作。
特別是,我所有的形式呼籲UpdateDoubleBuffered
:
function InRemoteSession: Boolean;
begin
Result := Windows.GetSystemMetrics(SM_REMOTESESSION)<>0;
end;
class procedure TBaseForm.UpdateDoubleBuffered(Control: TWinControl);
var
DoubleBuffered: Boolean;
begin
if InRemoteSession then begin
//see The Old New Thing, Taxes: Remote Desktop Connection and painting
DoubleBuffered := False;
end else begin
DoubleBuffered := (Control is TCustomListView)
or (Control is TCustomStatusBar);
//TCustomListView flickers when updating without double buffering
//TCustomStatusBar has drawing infidelities without double buffering in my app
end;
Control.DoubleBuffered := DoubleBuffered;
end;
procedure TBaseForm.UpdateDoubleBuffered;
var
Control: TControl;
begin
for Control in ControlEnumerator(TWinControl) do begin
UpdateDoubleBuffered(TWinControl(Control));
end;
end;
ControlEnumerator
是行走部件的孩子一個枚舉。
舊的新事物的參考是一篇名爲Taxes: Remote Desktop Connection and painting的文章,這是我對這段代碼大部分的啓發。
我確定還有其他與遠程桌面相關的問題,但雙緩衝肯定是其中一個更重要的問題。
+1這個詳細的答案。 – 2011-01-31 19:55:04
虛擬方法的使用者應該檢查會話消息是否適用於消費者的會話。他們如何做到這一點,而不知道SessionId(你沒有通過它)? – Remko 2011-02-01 12:50:02
@Remko我錯過了我的代碼中的一個重要部分,現在我已將其作爲編輯添加到答案中。當我註冊通知時,我使用`NOTIFY_FOR_THIS_SESSION`。我忘記了代碼的那部分內容,當然,在你要求通知之前收聽你不會收到的消息是沒有意義的!感謝您發現這一點。 – 2011-02-01 13:01:45
Alpha透明表單不能很好地支持IME(由客戶端或服務器根據其版本)。
如果你有一個乾淨的現代用戶界面,你也可能需要把它變成「醜陋」的模式,以便所有的東西都可以使用,你也必須擔心顏色,大多數遠程桌面以16位顏色或甚至256色進行操作。保證可讀。
本着同樣的精神,提防消除鋸齒的文本,這是任何現代UI必須的,但可能會導致低色RDP不可讀模糊的字符。
有可與通知氣泡和其他基於shell的影響等問題,所以你可能會想自己處理他們,在定期的形式,而不是依賴於Windows API的功能。從圖形上講,雙緩衝可以是一把雙刃劍,在某些情況下(低調圖形),關閉它可能是有益的,但如果您有更高級的渲染(漸變,透明位圖,縮放位圖,花哨字體,消除鋸齒線等),您可以通過雙緩衝獲得更好的外觀和速度,因爲稍微的延遲可能比閃爍的交互式繪圖更好。
此外,一些位圖可以比其他位圖快得多,RDP中常用的快速壓縮有利於水平梯度f.i上的垂直梯度。
如果您的應用程序永遠不需要在普通用戶帳戶下運行,則還會有另一個問題與文件權限有關。特殊文件夾(如temp)和註冊表鍵可以有不同的(動態)位置和限制。但是,如果您的應用程序已經在受限用戶帳戶下運行,則應該已經涵蓋了所有內容。
如果這是一個由數百或數千用戶運行的企業級應用程序或Web應用程序,請特別注意顏色深度,漸變和惡意動畫。特別是最後一個。一個16x16的旋轉「同步」圖標不會吃太多的帶寬,但更大的東西可能會產生大量的流量。 當顏色水平下降時,漸變看起來很糟糕,並且壓縮不好。 當網絡/系統管理員需要擠出更多網絡時,顏色級別下降。您可能無法控制它。 這些問題也適用於Citrix應用程序,這些應用程序通常在沒有完整桌面的情況下運行。 有一個額外的考慮是,用戶不會看到系統托盤通知區域。
隨着思傑,我們遇到了打印機問題。有時,連接將使用客戶機在其計算機上定義的打印機,有時打印機來自其他用戶的會話,而有時默認打印機位於我們用戶無法訪問的完全不同的位置。
我遇到很多問題,閃爍的東西太多以至於無法通過遠程桌面使用。這是因爲我每秒鐘多次更新諸如Captions或Status面板之類的東西。我改變了我的所有更新UI代碼來檢查,如果標題實際上已經改變了:
if Str<>WeirdControl.Property1 then
WeirdControl.Property1 := Str; // minimize number of invalidates in case the control doesn't have it.
隨着在其他的答案中提到的其他事情,這讓我的應用程序在遠程桌面的情況下再使用。
- 1. 需要遠程桌面服務?
- 2. 遠程桌面服務器應用
- 3. WindowsAzure:遠程桌面,我能做什麼?
- 4. 下一步要做什麼來構建桌面應用程序?
- 5. 桌面應用程序需要服務器端調試
- 6. 構建桌面應用程序時需要使用什麼?
- 7. WIndows服務在遠程桌面運行桌面程序
- 8. 爲什麼Java應用程序需要應用程序服務器來託管?
- 9. 爲什麼Android Market應用程序需要C2DM服務?
- 10. 需要遠程登錄編程的一些支持
- 11. 爲什麼使用JavaFX時,Java桌面應用程序需要特別部署?
- 12. .NET桌面應用程序(服務)3層應用程序
- 13. 爲了能夠發佈修改後的GPL程序,我需要做些什麼?
- 14. 爲什麼在遠程桌面呼叫中使用NOLOCK時需要WITH?
- 15. 將應用程序轉換爲支持時需要考慮什麼?
- 16. 知道什麼應用程序調用我的遠程服務
- 17. 應用程序到底做了什麼?
- 18. 我需要什麼樣的網絡服務器應用程序?
- 19. 什麼webserver支持android應用程序?
- 20. 什麼AMF服務器支持遠程共享對象?
- 21. 如何使用遠程服務器(CAKEPHP)驗證桌面FLEX/AIR應用程序?
- 22. Windows 7遠程桌面服務
- 23. 遠程桌面服務中的Azure中
- 24. 遠程桌面Azure雲服務經典
- 25. 爲什麼應用程序服務器需要存根才能執行遠程調用?
- 26. 將桌面應用程序轉換爲服務器+瀏覽器應用程序
- 27. 桌面應用程序和服務應用程序之間的不同行爲
- 28. 將桌面應用程序分離爲客戶機 - 服務器應用程序
- 29. 通過遠程桌面服務器贏得安裝程序2003
- 30. C#設置桌面應用程序來查詢遠程服務器的策略
需要多長時間才能將整個自定義組件作爲SO答案進行挑選?我剛剛提出了所有這三項 - 很好的工作! – 2011-02-01 00:05:20
@大衛M:一般不到一個小時。我做了很多次。謝謝! – 2011-02-01 00:06:26