39 lines
1.4 KiB
C#
39 lines
1.4 KiB
C#
using System.Runtime.InteropServices;
|
|
|
|
namespace CursorLang.Core.Interop;
|
|
|
|
/// <summary>
|
|
/// Answers whether the application runs from an MSIX package.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The same application runs both installed from the Store and simply unpacked
|
|
/// into a folder. Some Windows features — startup through <c>StartupTask</c>, for
|
|
/// instance — are available only to a package, and reaching for them without a
|
|
/// check is not allowed: outside a package they throw.
|
|
/// </remarks>
|
|
internal static class PackageIdentityNative
|
|
{
|
|
/// <summary>APPMODEL_ERROR_NO_PACKAGE — the process runs outside a package.</summary>
|
|
private const int NoPackage = 15700;
|
|
|
|
/// <summary>
|
|
/// The application runs from an MSIX package.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The value is computed once: it cannot change during the lifetime of
|
|
/// the process.
|
|
/// </remarks>
|
|
internal static bool IsPackaged { get; } = DetectPackage();
|
|
|
|
private static bool DetectPackage()
|
|
{
|
|
// The answer comes from the return code rather than from the name itself, so
|
|
// no buffer is needed: with zero length a package replies complaining about space
|
|
uint length = 0;
|
|
return GetCurrentPackageFullName(ref length, IntPtr.Zero) != NoPackage;
|
|
}
|
|
|
|
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
|
private static extern int GetCurrentPackageFullName(ref uint packageFullNameLength, IntPtr packageFullName);
|
|
}
|