diff --git a/XenAdmin/ConsoleView/VNCTabView.cs b/XenAdmin/ConsoleView/VNCTabView.cs index 948bc0e80..0ec35c295 100644 --- a/XenAdmin/ConsoleView/VNCTabView.cs +++ b/XenAdmin/ConsoleView/VNCTabView.cs @@ -40,13 +40,15 @@ using XenAdmin.Core; using XenAdmin.Network; using XenAPI; using XenAdmin.Commands; - +using XenAdmin.Dialogs; +using System.Collections.Generic; namespace XenAdmin.ConsoleView { public partial class VNCTabView : UserControl { private static readonly string UseRDP = Messages.VNC_RDESKTOP; + private static readonly string enableRDP = Messages.VNC_RDESKTOP_TRUN_ON; // public only for the automated tests. public static readonly string UseVNC = Messages.VNC_VIRTUAL_CONSOLE; public static readonly string UseXVNC = Messages.VNC_X_CONSOLE; @@ -78,6 +80,8 @@ namespace XenAdmin.ConsoleView private bool hasRDP { get { return source != null ? source.HasRDP : false; } } + private bool RDPEnabled { get { return source != null ? source.RDPEnabled : false; } } + public VNCTabView(VNCView parent, VM source, string elevatedUsername, string elevatedPassword) { Program.AssertOnEventThread(); @@ -97,6 +101,9 @@ namespace XenAdmin.ConsoleView this.parentVNCView = parent; this.scaleCheckBox.Checked = false; this.source = source; + this.guestMetrics = source.Connection.Resolve(source.guest_metrics); + if (this.guestMetrics != null) + guestMetrics.PropertyChanged += guestMetrics_PropertyChanged; log.DebugFormat("'{0}' console: Register Server_PropertyChanged event listener on {0}", this.source.Name); this.source.PropertyChanged += Server_PropertyChanged; Host_CollectionChangedWithInvoke = Program.ProgramInvokeHandler(Host_CollectionChanged); @@ -502,6 +509,7 @@ namespace XenAdmin.ConsoleView if (e.PropertyName == "other") { EnableRDPIfCapable(); + UpdateButtons(); } } @@ -519,7 +527,10 @@ namespace XenAdmin.ConsoleView { log.DebugFormat("'{0}' console: Starting RDP polling. (RDP polling is enabled in settings.)", source); toggleConsoleButton.Visible = true; - toggleConsoleButton.Enabled = false; + if(Helpers.CreedenceOrGreater(targetHost)) + toggleConsoleButton.Enabled = true; + else + toggleConsoleButton.Enabled = false; ThreadPool.QueueUserWorkItem(TryToConnectRDP); } else @@ -768,7 +779,7 @@ namespace XenAdmin.ConsoleView if (osString != null) { if (osString.Contains("Microsoft")) - label = UseRDP; + label = (Helpers.CreedenceOrGreater(targetHost) && !RDPEnabled) ? enableRDP : UseRDP; else label = UseXVNC; } @@ -1064,6 +1075,12 @@ namespace XenAdmin.ConsoleView toggleConsoleButton.Enabled = false; } + public void EnableToggleVNCButton() + { + Program.AssertOnEventThread(); + toggleConsoleButton.Enabled = true; + } + private void OnDetectRDP() { Program.Invoke(this, OnDetectRDP_); @@ -1075,8 +1092,11 @@ namespace XenAdmin.ConsoleView { log.DebugFormat("RDP detected for VM '{0}'", source == null ? "unknown/null" : source.name_label); this.toggleToXVNCorRDP = RDP; - if (vncScreen.UseVNC) - this.toggleConsoleButton.Text = UseRDP; + if (vncScreen.UseVNC) + if(Helpers.CreedenceOrGreater(targetHost) && !RDPEnabled) + this.toggleConsoleButton.Text = enableRDP; + else + this.toggleConsoleButton.Text = UseRDP; this.toggleConsoleButton.Enabled = true; tip.SetToolTip(this.toggleConsoleButton, null); if (!vncScreen.UserWantsToSwitchProtocol&& Properties.Settings.Default.AutoSwitchToRDP) @@ -1133,7 +1153,25 @@ namespace XenAdmin.ConsoleView vncScreen.UseVNC = !vncScreen.UseVNC; vncScreen.UserWantsToSwitchProtocol = true; - + + if (Helpers.CreedenceOrGreater(targetHost)) + { + if (!RDPEnabled) + { + ThreeButtonDialog d = new ThreeButtonDialog( + new ThreeButtonDialog.Details(System.Drawing.SystemIcons.Warning, Messages.FORCE_ENABLE_RDP), + "EnableRDPonVM", + new ThreeButtonDialog.TBDButton(Messages.YES, DialogResult.Yes), + new ThreeButtonDialog.TBDButton(Messages.NO, DialogResult.No)); + if (d.ShowDialog(Program.MainWindow) == DialogResult.Yes) + { + Session session = source.Connection.DuplicateSession(); + Dictionary _arguments = new Dictionary(); + XenAPI.VM.call_plugin(session, source.opaque_ref, "guest-agent-operation", "request-rdp-on", _arguments); + } + } + } + if (vncScreen.rdpIP == null && vncScreen.UseVNC && Properties.Settings.Default.EnableRDPPolling) { toggleConsoleButton.Enabled = false; @@ -1143,15 +1181,13 @@ namespace XenAdmin.ConsoleView if (vncScreen.rdpIP == null) // disable toggleConsoleButton; it will be re-enabled in TryToConnectRDP() when rdp port polling is complete (CA-102755) toggleConsoleButton.Enabled = false; ThreadPool.QueueUserWorkItem(TryToConnectRDP); - } - } else { oldScaleValue = scaleCheckBox.Checked; vncScreen.UseSource = !vncScreen.UseSource; - + if (vncScreen.vncIP == null && vncScreen.UseSource && Properties.Settings.Default.EnableRDPPolling) { toggleConsoleButton.Enabled = false; @@ -1171,7 +1207,7 @@ namespace XenAdmin.ConsoleView { bool rdp = (toggleToXVNCorRDP == RDP); if (rdp) - toggleConsoleButton.Text = vncScreen.UseVNC ? UseRDP : UseStandardDesktop; + toggleConsoleButton.Text = vncScreen.UseVNC ? ((Helpers.CreedenceOrGreater(targetHost) && !RDPEnabled) ? enableRDP : UseRDP) : UseStandardDesktop; else toggleConsoleButton.Text = vncScreen.UseSource ? UseXVNC : UseVNC; scaleCheckBox.Visible = !rdp || vncScreen.UseVNC; diff --git a/XenAdmin/ConsoleView/XSVNCScreen.cs b/XenAdmin/ConsoleView/XSVNCScreen.cs index e5c8ed60e..7f8c441d2 100644 --- a/XenAdmin/ConsoleView/XSVNCScreen.cs +++ b/XenAdmin/ConsoleView/XSVNCScreen.cs @@ -686,10 +686,15 @@ namespace XenAdmin.ConsoleView private void startPolling() { //Disable the button first, but only if in text/default console (to allow user to return to the text console - ref. CA-70314) - if (InDefaultConsole()) - { + if (Helpers.CreedenceOrGreater(Source.Connection)) + { + parentVNCTabView.EnableToggleVNCButton(); + } + else if (InDefaultConsole()) + { parentVNCTabView.DisableToggleVNCButton(); } + //Start the polling again if (Source != null && !Source.is_control_domain) diff --git a/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.Designer.cs b/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.Designer.cs index 4795f13e7..00618e246 100644 --- a/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.Designer.cs +++ b/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.Designer.cs @@ -88,7 +88,6 @@ namespace XenAdmin.Dialogs.OptionsPages resources.ApplyResources(this.checkBoxDisableRDPPolling, "checkBoxDisableRDPPolling"); this.checkBoxDisableRDPPolling.Name = "checkBoxDisableRDPPolling"; this.checkBoxDisableRDPPolling.UseVisualStyleBackColor = true; - this.checkBoxDisableRDPPolling.CheckedChanged += new System.EventHandler(this.checkBoxDisableRDPPolling_CheckedChanged); // // WindowsKeyCheckBox // diff --git a/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.cs b/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.cs index 81aec530e..7653e5e2b 100644 --- a/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.cs +++ b/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.cs @@ -75,11 +75,6 @@ namespace XenAdmin.Dialogs.OptionsPages PreserveUndockedScaleCheckBox.Checked = Properties.Settings.Default.PreserveScaleWhenUndocked; PreserveVNCConsoleScalingCheckBox.Checked = Properties.Settings.Default.PreserveScaleWhenSwitchBackToVNC; checkBoxDisableRDPPolling.Checked = Properties.Settings.Default.EnableRDPPolling; - if (!checkBoxDisableRDPPolling.Checked) - { - AutoSwitchCheckBox.Checked = false; - AutoSwitchCheckBox.Enabled = false; - } } private void buildKeyCodeListBox() @@ -203,17 +198,5 @@ namespace XenAdmin.Dialogs.OptionsPages #endregion - private void checkBoxDisableRDPPolling_CheckedChanged(object sender, EventArgs e) - { - if (checkBoxDisableRDPPolling.Checked) - { - AutoSwitchCheckBox.Enabled = true; - } - else - { - AutoSwitchCheckBox.Enabled = false; - AutoSwitchCheckBox.Checked = false; - } - } } } diff --git a/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.resx b/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.resx index 2d767b1df..0f4322f46 100644 --- a/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.resx +++ b/XenAdmin/Dialogs/OptionsPages/ConsolesOptionsPage.resx @@ -190,7 +190,7 @@ 4 - E&nable Remote Desktop console scanning + E&nable Remote Desktop console scanning (XenServer 6.5 and earlier) checkBoxDisableRDPPolling diff --git a/XenAdmin/TestResources/api-version.xml b/XenAdmin/TestResources/api-version.xml index 330f71083..4c9b9dbd4 100644 --- a/XenAdmin/TestResources/api-version.xml +++ b/XenAdmin/TestResources/api-version.xml @@ -160,5 +160,6 @@ + \ No newline at end of file diff --git a/XenAdminTests/TestResources/callVersions.csv b/XenAdminTests/TestResources/callVersions.csv index c080e0f9c..e5b1468b5 100644 --- a/XenAdminTests/TestResources/callVersions.csv +++ b/XenAdminTests/TestResources/callVersions.csv @@ -262,6 +262,7 @@ vm_appliance_assert_can_be_recovered,boston async_vm_appliance_assert_can_be_recovered,boston vm_appliance_recover,boston async_vm_appliance_recover,boston +vm_call_plugin,creedence dr_task_create,boston async_dr_task_create,boston dr_task_destroy,boston diff --git a/XenModel/Messages.Designer.cs b/XenModel/Messages.Designer.cs index e91e289b2..0c84facda 100644 --- a/XenModel/Messages.Designer.cs +++ b/XenModel/Messages.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34209 +// Runtime Version:4.0.30319.18444 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -13789,6 +13789,15 @@ namespace XenAdmin { } } + /// + /// Looks up a localized string similar to Would you like to turn on Remote Desktop in this VM, and then connect to it over Remote Desktop?. + /// + public static string FORCE_ENABLE_RDP { + get { + return ResourceManager.GetString("FORCE_ENABLE_RDP", resourceCulture); + } + } + /// /// Looks up a localized string similar to Force Reboot. /// @@ -32960,6 +32969,15 @@ namespace XenAdmin { } } + /// + /// Looks up a localized string similar to Turn &on Remote Desktop. + /// + public static string VNC_RDESKTOP_TRUN_ON { + get { + return ResourceManager.GetString("VNC_RDESKTOP_TRUN_ON", resourceCulture); + } + } + /// /// Looks up a localized string similar to &Redock. /// diff --git a/XenModel/Messages.ja.resx b/XenModel/Messages.ja.resx index 259025e4f..10ba6af24 100644 --- a/XenModel/Messages.ja.resx +++ b/XenModel/Messages.ja.resx @@ -4836,6 +4836,9 @@ CD をイジェクトしてから再試行してください。 プラグイン {0} がキャンセル要求に応答していません。プロセスを強制終了するか、バックグラウンドでの続行を許可するかを選択してください。 + + Would you like to turn on Remote Desktop in this VM, and then connect to it over Remote Desktop? + 強制再起動 @@ -11403,6 +11406,9 @@ StorageLink Gateway を使用する VM の XenServer 6.0 へのアップグレ リモート デスクトップに切り替える(&I) + + Turn &on Remote Desktop + 元に戻す(&R) diff --git a/XenModel/Messages.resx b/XenModel/Messages.resx index 107819ef8..2a46d8982 100644 --- a/XenModel/Messages.resx +++ b/XenModel/Messages.resx @@ -4836,6 +4836,9 @@ Would you like to eject these ISOs before continuing? Plugin {0} has not yet responded to your cancel request. Would you like to force close the process or allow it to continue to run in the background? + + Would you like to turn on Remote Desktop in this VM, and then connect to it over Remote Desktop? + Force Reboot @@ -11406,6 +11409,9 @@ To learn more about the XenServer Dynamic Workload Balancing feature or to start Sw&itch to Remote Desktop + + Turn &on Remote Desktop + &Redock diff --git a/XenModel/Messages.zh-CN.resx b/XenModel/Messages.zh-CN.resx index 43b2d1763..247fe8632 100644 --- a/XenModel/Messages.zh-CN.resx +++ b/XenModel/Messages.zh-CN.resx @@ -4835,6 +4835,9 @@ XenServer 可以重新启动服务器并将服务器的 CPU 级别降至池中 插件 {0} 尚未对您的取消请求作出响应。是强制关闭进程还是允许其继续在后台运行? + + Would you like to turn on Remote Desktop in this VM, and then connect to it over Remote Desktop? + 强制重启 @@ -11405,6 +11408,9 @@ XenServer 可以重新启动服务器并将其 CPU 降至主服务器的级别 切换到远程桌面(&I) + + 启用远程桌面(&o) + 重新停靠(&R) diff --git a/XenModel/XenAPI-Extensions/VM.cs b/XenModel/XenAPI-Extensions/VM.cs index e8a0d8e5d..5e425d922 100644 --- a/XenModel/XenAPI-Extensions/VM.cs +++ b/XenModel/XenAPI-Extensions/VM.cs @@ -431,6 +431,18 @@ namespace XenAPI } } + public bool RDPEnabled + { + get + { + var metrics = Connection.Resolve(this.guest_metrics); + if (metrics == null) + return false; + + return 0 != IntKey(metrics.other, "data-ts", 0); + } + } + /// Returns true if /// 1) the guest is HVM and /// 2a) the allow-gpu-passthrough restriction is absent or diff --git a/XenModel/XenAPI/Proxy.cs b/XenModel/XenAPI/Proxy.cs index 9a7ce2402..646c78e18 100644 --- a/XenModel/XenAPI/Proxy.cs +++ b/XenModel/XenAPI/Proxy.cs @@ -2556,6 +2556,10 @@ namespace XenAPI Response vm_appliance_get_all_records(string session); + [XmlRpcMethod("VM.call_plugin")] + Response + vm_call_plugin(string session, string _vm, string _plugin, string _fn, Object _args); + [XmlRpcMethod("DR_task.get_record")] Response dr_task_get_record(string session, string _dr_task); diff --git a/XenModel/XenAPI/VM.cs b/XenModel/XenAPI/VM.cs index f7491dd57..627a683e5 100644 --- a/XenModel/XenAPI/VM.cs +++ b/XenModel/XenAPI/VM.cs @@ -3797,6 +3797,20 @@ namespace XenAPI } private vm_power_state _power_state; + /// + /// Call a XenAPI plugin on this vm + /// First published in XenServer 6.6. + /// + /// The session + /// The opaque_ref of the given vm + /// The name of the plugin + /// The name of the function within the plugin + /// Arguments for the function + public static string call_plugin(Session session, string _vm, string _plugin, string _fn, Dictionary _args) + { + return (string)session.proxy.vm_call_plugin(session.uuid, (_vm != null) ? _vm : "", (_plugin != null) ? _plugin : "", (_fn != null) ? _fn : "", Maps.convert_to_proxy_string_string(_args)).parse(); + } + /// /// a human-readable name ///