Are your Windows Forms and WPF applications ready for .NET Core 3.0?

Olia Gavrysh

Download Download Portability Analyzer (2.37 MB)

At Build 2018 we announced that we are enabling Windows desktop applications (Windows Forms and Windows Presentation Framework (WPF)) with .NET Core 3.0. You will be able to run new and existing Windows desktop applications on .NET Core and enjoy all the benefits that .NET Core has to offer, such as application-local deployment and improved performance.

We want to make sure that .NET Core 3.0 includes all the APIs that your applications depend on. So, in order to learn about which APIs are being used, we are releasing Portability Analyzer that will report the set of APIs referenced in your apps that are not yet available in NET Core 3.0. This API list will be sent to Microsoft and will help us prioritize which APIs we should incorporate to the product before it ships.

Please download and run the tool (PortabilityAnalyzer.exe) on your Windows Forms and WPF apps to see how ready your apps are for .NET Core 3.0 and to help us shape the .NET Core 3.0 API set.

The Portability Analyzer

The Portability Analyzer is an open source tool that simplifies your porting experience by identifying APIs that are not portable among the various .NET Platforms. This tool has existed for a few years as a console application and a Visual Studio extension. We recently updated it with a Windows Forms UI, which you can find here. You can see what it looks like in the following image.

Running the tool will do two things:

  1. Generate an Excel spreadsheet that will report the level of compatibility that your project has with .NET Core 3.0, including the specific APIs that are currently unsupported.
  2. Send this same data to the .NET team at Microsoft so that we can determine which APIs are needed by the most people.

The data we are collecting is the same as what is in the spreadsheet. None of your source code or binaries will be sent from your machine to Microsoft.

In order for us to know which APIs our users need, we are asking you to run the tool which will help us to provide the best possible experience in porting your apps. You, at the same time, will see how portable your apps are right now since the tool generates a list of APIs referenced in your assemblies, that might not be supported in .NET Core 3.0.

We will prioritize adding new APIs in .NET Core 3.0 based on information we collect. Please help us help you by making sure your application’s API requirements are represented in the data that we use for prioritization. Please run the Portability Analyzer to ensure that your application is counted.

Using Portability Analyzer

Use the following instructions to run Portability Analyzer.

  1. Extract archive anywhere on your local disk.
  2. Run PortabilityAnalyzer.exe
  3. In the Path to application text box enter the directory path to your Windows Forms or WPF app (either by inserting a path string or clicking on Browse button and navigating to the folder).
  4. Click Analyze button.
  5. After the analysis is complete, a report of how portable your app is right now to .NET Core 3.0 will be saved to your disc. You can open it in Excel by clicking Open Report button.

Below is an example of the report you’re getting after running the tool for the popular Paint.NET application:

Note: In your report you might have a tab “Missing Assemblies”. It means that the analyzer could not find the source assemblies that are referenced in your application. Make sure to find those assemblies and add them to the folder you’re analyzing. Otherwise you won’t get the full picture of your application.


Currently Portability Analyzer cannot analyze resource assemblies (*..resources.dll). This results in the error message:

Unable to analyze. Details: Detecting assembly references [Failed]

Cannot locate assembly information for System.Object. Microsoft assemblies found are:

We are working on providing a fix. To unblock analysis until the fix is available, you can remove resource files from the folder you are analyzing.

Using the console-based version

If you would like to run the analysis for many applications, you can either run them one by one as described above or you can use the console version of the Portability Analyzer.

Note: You will get one report per invocation of the ApiPort.exe tool. If you prefer to get one report per application, you can automate the invocation either using for in Batch or the ForEach mechanism in PowerShell.

To run the console app:

  1. Download and unzip Console Portability Analyzer.
  2. From the command prompt run the following command specifying multiple directories, dlls, or executables: For example:

You can find the portability report saved as an Excel file (.xlsx) in your current directory.


Please download and use Portability Analyzer on your desktop applications. It will help you determine how compatible your apps are with .NET Core 3.0. This information will help us plan the 3.0 release with the goal of making it easy for you to adopt .NET Core 3.0 for desktop apps.

Download Download Portability Analyzer (2.37 MB)

Thank you in advance for your help!


Discussion is closed. Login to edit/delete existing comments.

  • Michael Aitania 0

    Your Windows Forms UI of Portability Analyzer doesn’t work.

  • Cuneyt Parlayan 0

    It crashes directly after choosing the directory and hitting analyze. “Unhandled exception”.
    I am running Windows 10 version 1804 32 bits. Details are as follows:
    See the end of this message for details on invoking 
    just-in-time (JIT) debugging instead of this dialog box.
    ************** Exception Text **************
    System.ComponentModel.Win32Exception (0x80004005): The specified executable is not a valid application for this OS platform.
       at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
       at System.Diagnostics.Process.Start()
       at PortabilityAnalyzer.MainForm.RunButton_Click(Object sender, EventArgs e)
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    ************** Loaded Assemblies **************
        Assembly Version:
        Win32 Version: 4.7.3324.0 built by: NET472REL1LAST_C
        CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
        Assembly Version:
        Win32 Version:
        CodeBase: file:///C:/Projects/porting/PortabilityAnalyzer/PortabilityAnalyzer.exe

  • Terry Rasmussen 0

    Unable to analyze.Details:Detecting assembly references                      [Failed]
    Eight months after launch and the utility still hasn’t been updated?

  • Payton Byrd 0

    Is there an update?  I’m sure a lot of work has happened since March 5!

  • Lynn Lahman 0

    It’s now November 6, 2019 — many months after the comments below this UI version still does not work and blows up everytime you select a folder and click on Anaylze saying it “can’t find the file specified”.

    This is a perfect example of why I have not made the leap to Core yet…misinformation and incomplete feature sets. If this were for .Net Core version .9 or even 1.0 I might understand. But this is representative of exactly why I will not even attempt the move to Core yet. When is this race to raise developer costs (i.e. – labor content for things that don’t work) going to stop?

  • John Groft 0

    Some people here are able to open the application and get an error later. I’m not even getting that far. It crashes as soon as I try to run it. I find the following errors in the Windows application log:

    – <Event xmlns=””>
    – <System>
    <Provider Name=”.NET Runtime” />
    <EventID Qualifiers=”0″>1026</EventID>
    <TimeCreated SystemTime=”2019-12-04T20:53:23.376193900Z” />
    <Security />
    – <EventData>
    <Data>Application: FlowTray.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.TypeLoadException at FlowTray.MainWindow..ctor() Exception Info: System.Windows.Markup.XamlParseException at System.Windows.Markup.XamlReader.RewrapException(System.Exception, System.Xaml.IXamlLineInfo, System.Uri) at System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader, System.Xaml.IXamlObjectWriterFactory, Boolean, System.Object, System.Xaml.XamlObjectWriterSettings, System.Uri) at System.Windows.Markup.WpfXamlLoader.LoadBaml(System.Xaml.XamlReader, Boolean, System.Object, System.Xaml.Permissions.XamlAccessLevel, System.Uri) at System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream, System.Windows.Markup.ParserContext, System.Object, Boolean) at System.Windows.Application.LoadBamlStreamWithSyncInfo(System.IO.Stream, System.Windows.Markup.ParserContext) at System.Windows.Application.DoStartup() at System.Windows.Application.<.ctor>b__1_0(System.Object) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) at MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object) at System.Windows.Threading.DispatcherOperation.Invoke() at System.Windows.Threading.Dispatcher.ProcessQueue() at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr) at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef) at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame) at System.Windows.Application.RunDispatcher(System.Object) at System.Windows.Application.RunInternal(System.Windows.Window) at FlowTray.App.Main()</Data>

    – <Event xmlns=””>
    – <System>
    <Provider Name=”Application Error” />
    <EventID Qualifiers=”0″>1000</EventID>
    <TimeCreated SystemTime=”2019-12-04T20:53:23.427167300Z” />
    <Security />
    – <EventData>
    <Data>C:\Program Files\CONEXANT\Flow\FlowTray.exe</Data>
    <Data />
    <Data />

  • Dave Doknjas 0

    Get this stuff actually working and more developers will try it out. Also, some advice about .NET Core in general – simplify!

Feedback usabilla icon