by Jonathan Pobst
- Run Dotnet Core App
- Run Net Core Forms App On Macbook
- Run Net Core Forms App On Mac Os
- Run Dotnet Core Console App
- Net Core App 3.1
- Net Core Desktop App
The amount of effort required to get an existing Winforms app running on Mono can vary greatly. Although many small apps will run on Mono unmodified, many apps will require some work on the developer’s part to run smoothly on Mono. This guide will attempt to port a non-trivial open source application to document several of the issues a developer may run into while porting their app to Mono.
A RadioButton has to behave exactly like it behaves on Win32 with MS.Net, or else applications written for it may not work properly anymore. And that’s the whole point of Winforms: to allow existing.Net SWF apps to run on Mono. For other uses, there are other choices that may be more appropriate, such as Gtk#. This may be beyond your question, but I want to mentioned another, pretty exotic possibility: I experimented with Mono development on Mac and tried out the following unusual application architecture: I managed to create two separate UI threads, one running System.Windows.Forms.Application, and another one Mac OS X API application. I tried to run winforms in mac OS with.net core 3.0, I am having this error: The target process exited without raising a CoreCLR started event. Best spam filter apps for mac. Ensure that the target process is configured to use.NET Core. This may be expected if the target process did not run on.NET Core. If it is, is there anyway we can run winforms in Mac OS or Linux? // 'Build and Deploy Your ASP.NET Core Application with Apache' is one of our top 5.NET articles of 2017. See the full list here. The Demo Application. I wanted to build a simple demo application that could be run on any operating system and show me some data in an interesting way.
Once installed run the following command. Npm install -g yo bower Just for reference, Yeoman is a template generator and will be used to scaffold our.Net Core app. Creating the Application with Yeoman. Now we need to install the ASP.Net Core template generator. This will be used by Yeoman to generate our application. Npm install -g generator.
The Project
For this guide, the open source application NClass has been chosen. It is a UML compliant class designer that looks very much like the one that ships in Visual Studio 2005. It is licensed under the GPL and LGPL, and has not been written with Mono in mind. We will be using Mono 1.2.4 to port NClass to run on Linux.
- NClass homepage - http://nclass.sourceforge.net/index.html
- NClass download - http://nclass.sourceforge.net/downloads.html (this guide uses the “source” version)
NClass running on .Net with included example file:
Getting Started
For the purpose of this guide, we will make the assumption that the developer is more familiar with Windows and Visual Studio than the Linux counterparts, given that the app is originally a Windows app.
Because we grabbed the source version, first we need to load up NClass.sln in Visual Studio and compile the solution.
Once we have a compiled executable, we can run MoMA on it to give us an idea of what kinds of issues we may run into.
The results from the MoMA scan can be seen here.
MoMA Summary
Methods we are using that are not in Mono 1.2.4:
- void ListView.add_ItemSelectionChanged (ListViewItemSelectionChangedEventHandler)
- void TreeView.set_ShowNodeToolTips (bool)
- void TreeNode.set_ToolTipText (string)
- void PrintDialog.set_UseEXDialog (bool)
Methods that are marked with a [MonoTODO] attribute in Mono.1.2.4:
- void Control.set_AutoSize (bool) - This method currently does nothing
- void ContainerControl.set_AutoScaleMode (AutoScaleMode) - Call scaling method
- void ComboBox.set_AutoCompleteMode (AutoCompleteMode) - AutoCompletion algorithm is currently not implemented.
- void ComboBox.set_AutoCompleteSource (AutoCompleteSource) - AutoCompletion algorithm is currently not implemented.
Looking at the report, we can immediately see several places we will most likely need to make adjustments for our program to work.
The TODOs look pretty harmless, we can infer that if we rely on AutoSize, it’s probably not going to work, and we are not going to have auto completion for our ComboBox. Most of these missing methods won’t be too big of a problem either once we work around them. We can expect that we will not have ToolTips in our TreeView, and we can’t set our PrintDialog to use the Windows XP dialog. The missing event ListView.ItemSelectionChanged however will likely be a problem. Because that event does not exist, it will not get fired, so whatever code we are doing in the event handler will not get called.
Trying It Out
Even though MoMA shows there could be problems running the application, sometimes those problems aren’t hit until certain features of the program are executed. So let’s try to run the application.
Open “Mono-1.2.4 Command Prompt” that was created in the start menu by the Mono installer. Go to the directory that contains the executable “NClass.NClass.exe”, and try running it with Mono using:
Unfortunately, nothing seemed to happen.
What actually happened is that the application ran, but hit an error and quit. To see the error, we need to redirect the error output to a file, so we run:
Looking at the log that was created, we see this error:
This isn’t really unexpected. It is telling us that we tried to set the property PrintDialog.UseEXDialog, which MoMA already told us didn’t exist in Mono. So it’s time to start porting our source code to work around these issues.
Porting Strategies
![Net core app 3.1 Net core app 3.1](/uploads/1/3/4/2/134207525/249703956.jpg)
Run Dotnet Core App
There are several approaches to porting code, depending on your goals.
- The unsupported code can simply be removed or commented out if it is not needed.
- Compiler conditional directives (#if) can be used to create separate executables for .Net and Mono.
- The runtime (.Net or Mono) can be detected and use different code.
- The code can be rewritten to use supported methods in Mono.
Here is the section of code that is setting PrintDialog.UseEXDialog in MainForm.Designer.cs:
Remove / Comment Code
If the code isn’t really needed, the easiest thing to do is to remove it:
or comment it out:
However, there will be plenty of cases when this is not feasible. Sound capture app mac.
Compiler Conditionals
Another strategy is to create different assemblies for .Net and Mono. This can be done by wrapping all code that is not supported by Mono in conditional directives and compiling with and without the directive.
When compiling the version for Mono, we would specify the flag MONO in the Build tab of the GUI project properties.
The downside of this approach is that we must ship separate assemblies for different platforms.
Runtime Conditionals
In order to have only one assembly for all platforms, but run different code on different platforms, we can detect at runtime whether we are using Mono or .Net. First, create a function to detect if the assembly is running on Mono (from the Technical FAQ):
Then use the function to determine which code to run:
Notice that we moved the code into a separate function, as this will prevent the JIT engine from throwing an exception as it JITs the code and determines that the method did not exist. By moving the code into a different method we prevent the JIT engine from hitting it.
Rewriting Code
Sometimes the best option is to simply rewrite the problem code in a way that is supported by Mono. For example, MoMA told us that this application uses the ListView.ItemSelectionChanged event, which is not implemented in Mono. However, the event ListView.SelectedIndexChanged event is implemented, and could be used for the same purpose.
Here is the problem code:
Which can be modified to:
We then modify lstItems_ItemSelectionChanged from:
To:
When possible (which isn’t always the case), this method is the cleanest, as it uses the same code and provides the same functionality on both the Mono and .Net runtime.
Porting NClass
For our NClass application, we will comment out PrintDialog.UseEXDialog, TreeView.ShowNodeToolTips, and TreeNode.ToolTipText. We will rewrite both occurrences of ListView.ItemSelectionChanged.
MainForm.Designer.cs - Line 1196 https://hcwdij.weebly.com/blog/wiki-bot-mac-app.
TreeDialog.Designer.cs - Line 66
TreeDialog.cs - Line 74
MembersDialog.designer.cs - Line 238
Rewriting the listMembers_ItemSelectionChanged method takes a little bit more effort. One way is to change it from:
To:
Also, make the changes to lstItems.ItemSelectionChanged and lstItems_ItemSelectionChanged outlined in the “Rewriting Code” section above.
With these changes made, rebuild the solution in Visual Studio. Then run the NClass.NClass.exe executable again. This time we get much better results:
Loading up the example file:
Class members dialog:
Continuing the Port
Now that the application runs, you have a good starting point to work from. However, it needs to be thoroughly tested for issues that MoMA can’t find. When exercising the application’s code, it is possible that you will run into things that do not function as expected or the application may crash unexpectedly. If these issues are bugs in Mono, please file the bug with a small test case (not your entire application) so we can fix them. See Bugs for details. Other issues may just be poorly written code that can be fixed by rewriting it to be more robust and error-proof.
There are still many issues with the NClass port, but for the sake of brevity, we will not attempt to fix them in this guide.
Running on Linux
Ultimately, the goal is to run the application on Linux, so let’s look at running NClass on Linux. If you already have a Linux installation, you can look for Mono packages in your distro’s package repositories.
If they are not there or are out of date, there are packages for many popular distros on Mono’s Downloads page. If you cannot find pre-made packages, you can also compile from the source code. Instructions are available here.
If you do not have a Linux installation, another option is to run the openSUSE/Mono VMWare image. This is the method we will use, which requires the following:
- Free VMWare Player - http://www.vmware.com/products/player/
- Mono 1.2.4 on openSUSE 10.2 VMWare image - Downloads
After installing the VMWare player and unzipping the VMWare image, start the Mono image. It should bring you to the openSUSE desktop:
Enabling User Shares
To transfer the application to the Mono image, we need to create a NClass directory and turn on directory sharing.
![Net core app 3.1 Net core app 3.1](/uploads/1/3/4/2/134207525/659882635.png)
- Right click the desktop, choose Create Directory, name the directory NClass.
- Click the “Computer” menu in the bottom left, choose Control Center.
- Choose “YaST” at the bottom, the password is “mono”.
- Choose “Network Services”, then “Samba Server”.
- Check “Allow Users to Share Their Directories” on the “Shares” tab.
- Choose “Finish”.
- Back on the desktop, Right click the “NClass” folder you created and choose “Sharing Options”.
- Check “Share this folder” and “Allow other people to write to this folder”.
- Click “Modify Share”.
Now go back to Windows, and access your new share by typing “mononclass” into the Run dialog. Copy your NClass project to the Mono image share.
On the Mono image desktop, double click your NClass folder, and navigate to your compiled NClass.NClass.exe application. Double click it and the application should run.
Linux Platform Differences
There are two classes of issues you may run into during your port. The first class are issues stemming from differences between the .Net and Mono runtime. These can be worked out while still on Windows as shown above. However, there is a second class of issues that you may come across. These are issues stemming from differences between Windows and Linux (or macOS, etc.).
Common OS Porting Issues
- Use of Win32 P/Invokes
- Case sensitivity in file names.
- Use of “” in paths.
As an example, lets say you have a subdirectory in your application called “Sounds” that contains the file “Finished.wav”. To play this sound, you have the following function:
This function exhibits all three mentioned porting issues.
Mono has a special execution mode that will help you get your port moving faster (if you do not want to change the filename casing or path separators, see the IOMap page for details.
Win32 P/Invokes
The PlaySound function is declared in the Win32 API dll “winmm.dll”, which does not exist on Linux. There are two ways around this. One is to find the equivalent function in your target platform’s API, and use runtime detection to determine which API to call. If you are lucky, the easy way is to replace your API call with managed code. In this case, we can use the System.Media.SoundPlayer class to play the sound for us, like this:
Run Net Core Forms App On Macbook
Case Sensitivity
Another difference between Windows and many other operating systems such as Linux is that the file system is case sensitive. That is, in Windows the files “readme.txt” and “README.TXT” are the same, but in Linux those are distinct files. Looking at our example, our file is called “Finished.wav”, but we are referencing it in code as “finished.wav”. Although this will work on Windows, it will generate a FileNotFoundException on Linux. So we must be consistent about the case of our file names:
The Path Separator
Another issue you may run across is the path separator (“”) used in file paths. In many other operating systems, such as Linux, the path separator is a forward slash (“/”) instead of a backwards slash like Windows. In our example, we have hard coded a backwards slash that will cause our file to not be found.
We can correct this using Path.DirectorySeparatorChar:
Run Net Core Forms App On Mac Os
or using Path.Combine:
Either method will ensure that the correct path separator is used on the correct operating system.
For some more issues you might run into and a more detailed look at options for dealing with them, see Guidelines:Application Portability.
Conclusion
Using this guide, we have managed to port a non-trivial winforms app to start up on Mono on Linux in a couple of hours. Although it is not complete, once the application is starting up on Mono, it’s a good beginning to test and see what issues remain.
Advanced Guides
- Guide: Debugging With MWF - Shows how to use the MWF project file from git to debug issues.
Sponsored By
Buckle up friends! Passwords mail app mac. Microsoft is open sourcing WPF, Windows Forms (winforms), and WinUI, so the three major Windows UX technologies are going open source! All this is happening on the same day as .NET Core 3.0 Preview 1 is announced. Madness! ;)
.NET Core 3 is a major update which adds support for building Windows desktop applications using Windows Presentation Foundation (WPF), Windows Forms, and Entity Framework 6 (EF6). Note that .NET Core 3 continues to be open source and runs on Windows, Linux, Mac, in containers, and in the cloud. In the case of WPF/WinForms/etc you'll be able to create apps for Windows that include (if you like) their own copy of .NET Core for a clean side-by-side install and even faster apps at run time. The Windows UI XAML Library (WinUI) is also being open sourced AND you can use these controls in any Windows UI framework.
That means your (or my!) WPF/WinForms/WinUI apps can all use the same controls if you like, using XAML Islands. I could take the now 10 year old BabySmash WPF app and add support for pens, improved touch, or whatever makes me happy!
WPF and Windows Forms projects are run under the .NET Foundation which also announced changes today and the community will guide foundation operations. The .NET Foundation is also changing its governance model by increasing the number of board members to 7, with just 1 appointed by Microsoft. The other board members will be voted on by the community! Anyone who has contributed to a .NET Foundation project can run, similar to how the Gnome Foundation works! Learn more about the .NET Foundation here.
On the runtime and versioning side, here's a really important point from the .NET blog that's worth emphasizing IMHO:
Know that if you have existing .NET Framework apps that there is not pressure to port them to .NET Core. We will be adding features to .NET Framework 4.8 to support new desktop scenarios. While we do recommend that new desktop apps should consider targeting .NET Core, the .NET Framework will keep the high compatibility bar and will provide support for your apps for a very long time to come.
I think of it this way. If you’ve got an existing app that you’re happy with, there is no reason to port this to .NET Core. Microsoft will support the .NET Framework for a very long time, given that it’s a part of Windows. But post .NET Framework 4.8. new features will usually only become available in .NET Core because Microsoft is drastically reducing the risk and thus rate of change for .NET Framework. So if you’re building a new app or you’re actively evolving an existing app you should really start looking at .NET Core. Porting to .NET Core certainly isn’t free, but it offers many benefits, such as better performance, XCOPY deployment for the framework itself, and feature set that is growing fast, thanks to open source. Choose the strategy that makes sense for your project and/or business.
I don't want to hear any of this 'this is dead, only use that' nonsense. We just open sourced WinForms and have already taken Pull Requests. WinForms has been updated for 4k+ displays! WPF is open source, y'all! Think about the .NET Standard and how you can run standard libraries on .NET Framework, .NET Core, and Mono - or any '.NET' that's out there. Mono is enabling running .NET Standard libraries via WebAssembly. To be clear - your browser is now .NET Standard capable! There are open source projects like https://platform.uno/ and Avalonia and Ooui taking .NET in new and interesting places. Blazor makes Web UIs in .NET with (preview/experimental) client support with Web Assembly and server support included in .NET 3.0 with Razor Components. Only good things are coming, my friends!
.NET Core runs on Raspberry Pi and ARM processors! .NET Core supports serial ports, IoT devices, and there's even a System.Device.GPIO (General Purpose I/O) package! Go explore https://github.com/dotnet/iot to really get your head around how much cool stuff is happening in the .NET space.
Run Dotnet Core Console App
I want to encourage you to go check out Matt Warren's extremely well-researched post 'Open Source .NET - 4 years later' to get a real visceral sense of how far we've come as a community. You'll be amazed!
Now, go play!
- Download .NET Core 3 Preview 1 on Windows, Mac and Linux.
- You can see details of the release in the .NET Core 3 Preview 1 release notes
- Visual Studio 2019 will support building .NET Core 3 applications and the VS2019 preview can be installed side by side with existing versions of VS.
Enjoy.
Sponsor: Preview the latest JetBrains Rider with its Assembly Explorer, Git Submodules, SQL language injections, integrated performance profiler and more advanced Unity support.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.