Skip to content

Cross Platform Vision

Alexander Schulz edited this page Mar 3, 2019 · 27 revisions

General

We all want XCP-ng Console running on Linux/Mono/Unix. Here we are collecting problems, solutions and ideas.

Considerations

  • WinForms is tightly integrated into XenAdmin
  • win32 calls are tightly integrated into XenAdmin (and WinForms)

Possible ways:

  • stick with WinForms
    • no beautifull gui under mono
    • reverse enginering/understanding of citrix's gui ideas, as there are no comments about it in the source
      • many controls are custom drawn "by hand"
    • heavy workarounds/abstraction layers needed
    • some native calls can be avoided by different implementation of higer level XenAdmin code
    • is the fastes way to get a linux/mono client running
  • switch to GTK#
    • BIG effort!
      • is a reimplementation from scratch
      • is more like a hard fork
    • base code (communication, etc.) can remain the same as Citrix (r) XenCenter (r)
    • the cleaner crossplatform solution

First Hack

Second Hack

Build environment

build gtk-sharp 2.12

git checkout https://github.com/mono/gtk-sharp
cd gtk-sharp
git checkout gtk-sharp-2-12-branch
./bootstrap-2.12 --prefix=/opt/mono
make
make install

Special Mono Build (sides by side with the installed mono)

Worklog

Splash

  • Not compiling
  • Unload project in Monodevelop

xcp-ng-installer

  • Not compiling
  • Unload project in Monodevelop

System.Configuration not found

ListViewItemCount

Tool /usr/lib/mono/4.5/resgen.exe execution started with arguments: /useSourcePath /compile
"Dialogs/ConfirmVMDeleteDialog.resx,obj/Debug/XenAdmin.Dialogs.ConfirmVMDeleteDialog.resources" 
/usr/lib/mono/xbuild/14.0/bin/Microsoft.Common.targets:
error : Tool exited with code: 1. Output: Error: Exception has been thrown by the target of an invocation.
Inner exception: Member 'ListViewItemCount' was not found.

Workaround

Delete XenAdmin\Dialogs\ConfirmVMDeleteDialog.cs and subfiles from project, comment referencing code

PNG graphics / ResxFileGenerator

  • ResxFileGenerator throws errors like libpng warning: iCCP: known incorrect sRGB profile
  • some *.ressources files under obj/Debug are empty (0 byte)

Workaround

  • Execute find -name "*.png" | xargs -I{} pngcrush -ow -c 6 {} in folder XenAdmin\Images and Branding

*.Designer.cs not found

Because of case sensivity of linux some ofthis files are not found.

Solution

  1. Replace all designer.cs with Designer.cs in XenAdmin\XenAdmin.csproj

  2. rename some files in XenAdmin folder:

     mv ./SettingsPanels/CustomFieldsDisplayPage.designer.cs ./SettingsPanels/CustomFieldsDisplayPage.Designer.cs
     mv ./Controls/SnapshotTreeView.designer.cs ./Controls/SnapshotTreeView.Designer.cs
     mv ./Controls/UpsellPage.designer.cs ./Controls/UpsellPage.Designer.cs
     mv ./Controls/CustomDataGraph/DataPlot.designer.cs ./Controls/CustomDataGraph/DataPlot.Designer.cs
     mv ./Controls/CustomDataGraph/DataPlotNav.designer.cs ./Controls/CustomDataGraph/DataPlotNav.Designer.cs
     mv ./Controls/CustomDataGraph/DataEventList.designer.cs /Controls/CustomDataGraph/DataEventList.Designer.cs
     mv ./Controls/SpinnerIcon.designer.cs ./Controls/SpinnerIcon.Designer.cs
     mv ./TabPages/SnapshotsPage.designer.cs ./TabPages/SnapshotsPage.Designer.cs
     mv ./Wizards/NewSRWizard_Pages/Frontends/LVMoHBA.designer.cs ./Wizards/NewSRWizard_Pages/Frontends/LVMoHBA.Designer.cs
     mv ./Wizards/RollingUpgradeWizard/RollingUpgradeUpgradePage.designer.cs ./Wizards/RollingUpgradeWizard/RollingUpgradeUpgradePage.Designer.cs
     mv ./Wizards/XenWizardBase.designer.cs ./Wizards/XenWizardBase.Designer.cs
     mv ./Wizards/HAWizard_Pages/AssignPriorities.designer.cs ./Wizards/HAWizard_Pages/AssignPriorities.Designer.cs
     mv ./Wizards/PatchingWizard/PatchingWizard_AutomatedUpdatesPage.designer.cs ./Wizards/PatchingWizard/PatchingWizard_AutomatedUpdatesPage.Designer.cs
     mv ./Wizards/PatchingWizard/PatchingWizard_PatchingPage.designer.cs ./Wizards/PatchingWizard/PatchingWizard_PatchingPage.Designer.cs
     mv ./Dialogs/UpsellDialog.designer.cs ./Dialogs/UpsellDialog.Designer.cs
     mv ./Dialogs/Wlb/WlbReportSubscriptionDialog.designer.cs ./Dialogs/Wlb/WlbReportSubscriptionDialog.Designer.cs
     mv ./Dialogs/HealthCheck/HealthCheckSettingsDialog.designer.cs ./Dialogs/HealthCheck/HealthCheckSettingsDialog.Designer.cs
     mv ./Dialogs/PvsPages/PvsCacheConfigurationPage.designer.cs ./Dialogs/PvsPages/PvsCacheConfigurationPage.Designer.cs
     mv ./Dialogs/WarningDialogs/LVMoHBAWarningDialog.designer.cs ./Dialogs/WarningDialogs/LVMoHBAWarningDialog.Designer.cs
     mv ./Dialogs/ConnectingToServerDialog.designer.cs ./Dialogs/ConnectingToServerDialog.Designer.cs
     mv ./Controls/CustomDataGraph/DataEventList.designer.cs ./Controls/CustomDataGraph/DataEventList.Designer.cs
     mv ./Controls/SummaryPanel/IsummaryPanelView.cs ./Controls/SummaryPanel/ISummaryPanelView.cs
     mv ./Commands/ImPortCommand.cs ./Commands/ImportCommand.cs
    

Builderror, copy not found

Remove PostBuildEvent from XenAdmin/XenAdmin.csproj

  <PropertyGroup>
    <PostBuildEvent Condition=" '$(Configuration)' == 'Release' ">mt.exe -nologo -manifest             "$(ProjectDir)$(ProjectName).manifest" -outputresource:"$(TargetDir)..\..\bin\$(Configuration)\$(TargetFileName)";#1</PostBuildEvent>
  </PropertyGroup>
  <PropertyGroup>
    <PostBuildEvent>copy "$(ProjectDir)\ReportViewer\resource_report.rdlc" "$(TargetDir)"

copy "$(ProjectDir)\..\packages\putty.exe" "$(TargetDir)"</PostBuildEvent>
  </PropertyGroup>

Problems 2 (get it starting)

FormFontFixer

Program.cs-> SetDefaultFonts()

Just comment all out and add SetDefaultFonts(DefaultFont); at the bottom.

uxtheme IsAppThemed()

just comment out

ConnectPipe()

seems just to be for remotecontrolling in tests

WebBrowser

https://github.com/xcp-ng/xenadmin/issues/39

Drawing.cs / QuickDraw()

https://github.com/xcp-ng/xenadmin/issues/42

Clip.cs

https://github.com/xcp-ng/xenadmin/issues/41

RegisterApplicationRestart(null, 0);

Win32.cs / GetGuiRessources

Not realy needed, just for logging.

Win32.cs / SetLastError()

win32.cs / GetScrollInfo()

TBD

VNC

  • avoid call loop on activate (XenAdmin/ConsoleView/XSVNCScreen.cs -> CaptureKeyboardAndMouse())
  • avoid native calls for painting and cursor creation
  • time keeping and meassurement with DateTime.Now instead of native calls
  • mouse and keyboard interception without native calls (XenCenterVNC/KeyMap.cs)

Padding in dataGridViewCellStyle prevents painting Text on General Tab

/home/alex/Dokumente/Entwicklung/xenadmin/borzel-xenadmin/XenAdmin/Controls/PDSection.Designer.cs:122

 dataGridViewCellStyle4.Padding = new System.Windows.Forms.Padding(5);
 this.dataGridViewEx1.RowsDefaultCellStyle = dataGridViewCellStyle4;

Other Ideas/Comments

Solution for native call abstraction (by @johnbester)

https://github.com/xcp-ng/xenadmin/issues/40

To get it started, one of the core issues is native calls which area spread out through the program. A simple grep reveals DllImport appearing in 15 files. I suggest that an abstract class be created with abstract implementations of the various native calls (call it NativeCall). Then subclass it with NativeCallWin and override methods with the DllImport implementations. Also subclass it with NativeCallLinux (and NativeCallOSX) with all method stubs basically doing nothing (at fist). The methods that are the most crucial can be implemented first while the rest remain dummy methods until someone has the time to attend to them. A static getInstance() method in NativeCall initialises the correct instance during the first access by checking the underlying OS.

Borzel (01.07.2018) This will not work, because there are no easy replacements in Unix... best is to solve all this in C# directly.

BlackCentipede (02.08.2018) I've tried the gdiplus library as explained here: https://www.mono-project.com/docs/gui/drawing/ The problem is, it doesn't include the API required for DC such as 'CreateCompatibleDC' API and the current implementation for GDI in Mono doesn't support image scaling for drawing. So the best option I can think of at this time is that we create a surface that can be rendered onto with Cairo or any existing renderer library.

So ultimately, we need to use GDI to the very minimum.