0

I have a libary which needs to behave differently for console applications, desktop application (e.g. WPF), and for UWP apps.

How can I determine at run-time into which application type my libary is loaded?

Determining if it is a console application seems easy: How to tell if there is a console

For UWP, I can probably determine if WinRT is loaded. But how?

What distinguishing attributes do desktop applications have?

Jack Miller
  • 6,843
  • 3
  • 48
  • 66
  • Only as note. The first description does not tell you always (correctly), that you have a console application. *(e.g. when you use input/output redirection)* For details see: https://stackoverflow.com/a/48237650/2826535 And the second description can be used to detect operating system, or installed components, not active environment. I wonder what type of library needs different behaviour for different environment. I can not think of any reason for that. Therefore this seems to me, IMHO, like a bad design or approach. – Julo May 12 '18 at 07:27
  • It is a Bluetooth library. Actually it is only supported for UWP. But with some tweaks it also works for desktop applications. For console, it gets even more complicated because there is no UI thread for async contexts. – Jack Miller May 12 '18 at 07:36
  • This explains the reasons. Try to see (and test) https://stackoverflow.com/a/8711036/2826535 and another answers from this question. This can probably help you to determine some application states. But nothing is perfect. There is always in/out redirection. I'm sure I was able to start message processing in console application in console application *(testing purposes for 'Tray icon only' application)*, but the code is old and in my company. Another option is to test existing libraries (e.g. `!(Type.GetType("Mono.Runtime") is null)`), but I'm not so sure if this will work (and it is not safe). – Julo May 12 '18 at 07:55

2 Answers2

0

I ended up defining following enum:

public enum ExecutionMode
{
    Console,
    Desktop,
    UniversalWindowsPlatform
}

which is passed to the constructor of the main class of my libary. Not a new idea, but very reliable (if used correctly).

Jack Miller
  • 6,843
  • 3
  • 48
  • 66
0

Create a CustomAttribute in an assembly that is available to all of the applications like so

using System;

namespace MyNamespace.Reflection {
    [System.AttributeUsage(AttributeTargets.Assembly)]
    public class ApplicationTypeAttribute : Attribute {
        public enum ApplicationTypes {
            Console,
            Desktop,
            UWP,
            ClassLibrary
        }

        public ApplicationTypeAttribute(ApplicationTypes appType) {
            ApplicationType = appType;
        }

        public ApplicationTypes ApplicationType { get; private set; } = ApplicationTypes.Console;

    }
}

Then add this attribute to your AssemblyInfo.cs file for a console application

using MyNamespace.Reflection;

[assembly: ApplicationType(ApplicationTypeAttribute.ApplicationTypes.Console)]

or a Desktop application

[assembly: ApplicationType(ApplicationTypeAttribute.ApplicationTypes.Desktop)]

etc.

Then wherever you want to check the calling type of the application that was started, use this

using MyNamespace.Reflection;

var assy = System.Relection.Assembly.GetEntryAssembly();
var typeAttribute = assy.GetCustomAttribute(typeof(ApplicationTypeAttribute));
if (typeAttribute != null) {
    var appType = ((ApplicationTypeAttribute)typeAttribute).ApplicationType;
}

There is one caveat to this method. .NET Core apps have a different project structure and the AssemblyInfo.cs file is auto-generated at build time by default. You can override this behavior by specifying the following in the .csproj file in the Project node.

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

To match the old project file structure, you can create a Properties directory in the project directtory and then you can add an AssemblyInfo.cs file to that directory. Otherwise you can place the Custom Attribute definition in any file (after the usings and before the namespace declaration).

Greg
  • 19
  • 4