@nativescript/windows-quickjs 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/framework/__PROJECT_NAME__/App.xaml +13 -0
- package/framework/__PROJECT_NAME__/App.xaml.cs +240 -0
- package/framework/__PROJECT_NAME__/Assets/SplashScreen.png +0 -0
- package/framework/__PROJECT_NAME__/Assets/Square150x150Logo.png +0 -0
- package/framework/__PROJECT_NAME__/Assets/Square44x44Logo.png +0 -0
- package/framework/__PROJECT_NAME__/Assets/StoreLogo.png +0 -0
- package/framework/__PROJECT_NAME__/Assets/Wide310x150Logo.png +0 -0
- package/framework/__PROJECT_NAME__/CrashDiagnostics.cs +281 -0
- package/framework/__PROJECT_NAME__/Directory.Build.props +15 -0
- package/framework/__PROJECT_NAME__/Directory.Build.targets +106 -0
- package/framework/__PROJECT_NAME__/Package.appxmanifest +35 -0
- package/framework/__PROJECT_NAME__/Program.cs +34 -0
- package/framework/__PROJECT_NAME__/Properties/Default.rd.xml +9 -0
- package/framework/__PROJECT_NAME__/RuntimeHost.cs +359 -0
- package/framework/__PROJECT_NAME__/__PROJECT_NAME__.csproj +263 -0
- package/framework/dotnet-bridge/BinaryProtocol.cs +161 -0
- package/framework/dotnet-bridge/Bridge.BinaryDispatch.cs +373 -0
- package/framework/dotnet-bridge/Bridge.Dispatch.cs +597 -0
- package/framework/dotnet-bridge/Bridge.JsDelegate.cs +244 -0
- package/framework/dotnet-bridge/Bridge.Proxy.cs +573 -0
- package/framework/dotnet-bridge/Bridge.TaskHelper.cs +207 -0
- package/framework/dotnet-bridge/Bridge.cs +724 -0
- package/framework/dotnet-bridge/DispatchTypes.cs +333 -0
- package/framework/dotnet-bridge/DotNetBridge.csproj +30 -0
- package/framework/dotnet-bridge/publish_build/DotNetBridge.deps.json +23 -0
- package/framework/dotnet-bridge/publish_build/DotNetBridge.dll +0 -0
- package/framework/dotnet-bridge/publish_build/DotNetBridge.pdb +0 -0
- package/framework/dotnet-bridge/publish_build/DotNetBridge.runtimeconfig.json +14 -0
- package/framework/libs/x64/nativescript.dll +0 -0
- package/framework/tools/ManifestMerger/ManifestMerger.deps.json +24 -0
- package/framework/tools/ManifestMerger/ManifestMerger.dll +0 -0
- package/framework/tools/ManifestMerger/ManifestMerger.pdb +0 -0
- package/framework/tools/dotnet-tool-arm64.exe +0 -0
- package/framework/tools/dotnet-tool-x64.exe +0 -0
- package/framework/tools/dotnet-tool.exe +0 -0
- package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.deps.json +23 -0
- package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.dll +0 -0
- package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.exe +0 -0
- package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.pdb +0 -0
- package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.runtimeconfig.json +13 -0
- package/framework/tools/sbg-arm64.exe +0 -0
- package/framework/tools/sbg-x64.exe +0 -0
- package/framework/tools/sbg.exe +0 -0
- package/framework/tools/typings-generator-arm64.exe +0 -0
- package/framework/tools/typings-generator-x64.exe +0 -0
- package/framework/tools/typings-generator.exe +0 -0
- package/package.json +43 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
2
|
+
<!-- Directory.Build.targets for the Windows project template.
|
|
3
|
+
This file applies manifest overrides at build time using XmlPoke.
|
|
4
|
+
Place in the template root so generated projects inherit it. -->
|
|
5
|
+
<!-- Default properties are provided in Directory.Build.props so they can be
|
|
6
|
+
easily overridden per-app or via MSBuild /p: properties. -->
|
|
7
|
+
|
|
8
|
+
<PropertyGroup>
|
|
9
|
+
<ManifestMergerAssembly Condition="'$(ManifestMergerAssembly)' == ''">$(MSBuildThisFileDirectory)..\tools\ManifestMerger\ManifestMerger.dll</ManifestMergerAssembly>
|
|
10
|
+
<ValidateMergedManifest Condition="'$(ValidateMergedManifest)' == ''">false</ValidateMergedManifest>
|
|
11
|
+
<TreatManifestValidationErrorsAsWarnings Condition="'$(TreatManifestValidationErrorsAsWarnings)' == ''">false</TreatManifestValidationErrorsAsWarnings>
|
|
12
|
+
<LogManifestMergeDiagnosticsAsWarnings Condition="'$(LogManifestMergeDiagnosticsAsWarnings)' == ''">false</LogManifestMergeDiagnosticsAsWarnings>
|
|
13
|
+
</PropertyGroup>
|
|
14
|
+
|
|
15
|
+
<UsingTask TaskName="MergeAppxManifest" AssemblyFile="$(ManifestMergerAssembly)" Condition="Exists('$(ManifestMergerAssembly)')" />
|
|
16
|
+
|
|
17
|
+
<Target Name="MergeAppResourcesManifest" AfterTargets="ApplyManifestOverrides" Condition="Exists('$(MSBuildProjectDirectory)\Package.appxmanifest')">
|
|
18
|
+
<PropertyGroup>
|
|
19
|
+
<_AppResourcesManifest>$(MSBuildProjectDirectory)\App_Resources\Windows\Package.appxmanifest</_AppResourcesManifest>
|
|
20
|
+
<!-- Allow CLI or callers to override the source manifest via MSBuild property 'AppResourcesManifestPath' -->
|
|
21
|
+
<_AppResourcesManifest Condition="'$(AppResourcesManifestPath)' != ''">$(AppResourcesManifestPath)</_AppResourcesManifest>
|
|
22
|
+
<!-- Fallback template manifest name (no '.partial' suffix) -->
|
|
23
|
+
<_PartialManifest>$(MSBuildProjectDirectory)\Package.appxmanifest</_PartialManifest>
|
|
24
|
+
<_ManifestToMerge>$(_PartialManifest)</_ManifestToMerge>
|
|
25
|
+
<_ManifestToMerge Condition="Exists('$(_AppResourcesManifest)')">$(_AppResourcesManifest)</_ManifestToMerge>
|
|
26
|
+
</PropertyGroup>
|
|
27
|
+
<ItemGroup>
|
|
28
|
+
<_ManifestMergerSchemaFiles Include="$(ManifestMergerSchemaFiles)" Condition="'$(ManifestMergerSchemaFiles)' != ''" />
|
|
29
|
+
</ItemGroup>
|
|
30
|
+
<Message Text="Merging app manifest (if present) into generated Package.appxmanifest (app wins)" Importance="Low" />
|
|
31
|
+
<MergeAppxManifest SourceManifest="$(_ManifestToMerge)"
|
|
32
|
+
TargetManifest="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
33
|
+
ValidateMergedManifest="$(ValidateMergedManifest)"
|
|
34
|
+
TreatValidationErrorsAsWarnings="$(TreatManifestValidationErrorsAsWarnings)"
|
|
35
|
+
LogMergeDiagnosticsAsWarnings="$(LogManifestMergeDiagnosticsAsWarnings)"
|
|
36
|
+
SchemaFiles="@(_ManifestMergerSchemaFiles)"
|
|
37
|
+
Condition="Exists('$(ManifestMergerAssembly)') and Exists('$(_ManifestToMerge)')" />
|
|
38
|
+
</Target>
|
|
39
|
+
|
|
40
|
+
<Target Name="WarnMissingManifestMerger"
|
|
41
|
+
BeforeTargets="MergeAppResourcesManifest"
|
|
42
|
+
Condition="Exists('$(MSBuildProjectDirectory)\Package.appxmanifest') and !Exists('$(ManifestMergerAssembly)')">
|
|
43
|
+
<Warning Text="ManifestMerger task assembly was not found at '$(ManifestMergerAssembly)'; app manifest resources will not be merged." />
|
|
44
|
+
</Target>
|
|
45
|
+
|
|
46
|
+
<Target Name="ApplyManifestOverrides" BeforeTargets="BeforeBuild" Condition="Exists('$(MSBuildProjectDirectory)\Package.appxmanifest')">
|
|
47
|
+
<Message Text="Applying manifest overrides (VisualElements, logos, splash) via XmlPoke..." Importance="High" />
|
|
48
|
+
|
|
49
|
+
<!-- DisplayName (app tile / taskbar / Start / alt-tab) -->
|
|
50
|
+
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
51
|
+
Query="/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']/@DisplayName"
|
|
52
|
+
Value="$(AppDisplayName)"
|
|
53
|
+
Condition="'$(AppDisplayName)' != ''" />
|
|
54
|
+
|
|
55
|
+
<!-- Package DisplayName (Properties) — keep it in sync with the app name instead of leaving the
|
|
56
|
+
raw project name. The XmlPoke above only touches the per-app VisualElements name. -->
|
|
57
|
+
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
58
|
+
Query="/*[local-name()='Package']/*[local-name()='Properties']/*[local-name()='DisplayName']"
|
|
59
|
+
Value="$(AppDisplayName)"
|
|
60
|
+
Condition="'$(AppDisplayName)' != ''" />
|
|
61
|
+
|
|
62
|
+
<!-- Description -->
|
|
63
|
+
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
64
|
+
Query="/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']/@Description"
|
|
65
|
+
Value="$(AppDescription)"
|
|
66
|
+
Condition="'$(AppDescription)' != ''" />
|
|
67
|
+
|
|
68
|
+
<!-- Logos -->
|
|
69
|
+
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
70
|
+
Query="/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']/@Square150x150Logo"
|
|
71
|
+
Value="$(Square150x150Logo)"
|
|
72
|
+
Condition="'$(Square150x150Logo)' != ''" />
|
|
73
|
+
|
|
74
|
+
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
75
|
+
Query="/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']/@Square44x44Logo"
|
|
76
|
+
Value="$(Square44x44Logo)"
|
|
77
|
+
Condition="'$(Square44x44Logo)' != ''" />
|
|
78
|
+
|
|
79
|
+
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
80
|
+
Query="/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']/*[local-name()='DefaultTile']/@Wide310x150Logo"
|
|
81
|
+
Value="$(Wide310x150Logo)"
|
|
82
|
+
Condition="'$(Wide310x150Logo)' != ''" />
|
|
83
|
+
|
|
84
|
+
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
85
|
+
Query="/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']/@StoreLogo"
|
|
86
|
+
Value="$(StoreLogo)"
|
|
87
|
+
Condition="'$(StoreLogo)' != ''" />
|
|
88
|
+
|
|
89
|
+
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
90
|
+
Query="/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']/@LockScreenLogo"
|
|
91
|
+
Value="$(LockScreenLogo)"
|
|
92
|
+
Condition="'$(LockScreenLogo)' != ''" />
|
|
93
|
+
|
|
94
|
+
<!-- BackgroundColor and SplashScreen image -->
|
|
95
|
+
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
96
|
+
Query="/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']/@BackgroundColor"
|
|
97
|
+
Value="$(SplashBackgroundColor)"
|
|
98
|
+
Condition="'$(SplashBackgroundColor)' != ''" />
|
|
99
|
+
|
|
100
|
+
<XmlPoke XmlInputPath="$(MSBuildProjectDirectory)\Package.appxmanifest"
|
|
101
|
+
Query="/*[local-name()='Package']/*[local-name()='Applications']/*[local-name()='Application']/*[local-name()='VisualElements']/*[local-name()='SplashScreen']/@Image"
|
|
102
|
+
Value="$(SplashImage)"
|
|
103
|
+
Condition="'$(SplashImage)' != ''" />
|
|
104
|
+
|
|
105
|
+
</Target>
|
|
106
|
+
</Project>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<Package
|
|
3
|
+
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
|
4
|
+
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
|
5
|
+
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
|
6
|
+
IgnorableNamespaces="uap rescap">
|
|
7
|
+
<Identity Name="__APP_IDENTIFIER__" Publisher="CN=__PROJECT_NAME__" Version="1.0.0.0" />
|
|
8
|
+
<Properties>
|
|
9
|
+
<DisplayName>__PROJECT_NAME__</DisplayName>
|
|
10
|
+
<PublisherDisplayName>__PROJECT_NAME__</PublisherDisplayName>
|
|
11
|
+
<Logo>Assets\StoreLogo.png</Logo>
|
|
12
|
+
</Properties>
|
|
13
|
+
<Dependencies>
|
|
14
|
+
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.26100.0" />
|
|
15
|
+
<!-- WinUI3 / Windows App SDK 1.6 framework package (framework-dependent). Required so the
|
|
16
|
+
registered app can activate Microsoft.UI.Xaml.* (else REGDB_E_CLASSNOTREG at startup). -->
|
|
17
|
+
<PackageDependency Name="Microsoft.WindowsAppRuntime.1.6" MinVersion="6000.0.0.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
|
18
|
+
</Dependencies>
|
|
19
|
+
<Resources>
|
|
20
|
+
<Resource Language="en-US" />
|
|
21
|
+
</Resources>
|
|
22
|
+
<Applications>
|
|
23
|
+
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="Windows.FullTrustApplication">
|
|
24
|
+
<uap:VisualElements DisplayName="__PROJECT_NAME__" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="A NativeScript Windows application" BackgroundColor="#65ADF1">
|
|
25
|
+
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
|
|
26
|
+
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
|
27
|
+
</uap:VisualElements>
|
|
28
|
+
</Application>
|
|
29
|
+
</Applications>
|
|
30
|
+
<Capabilities>
|
|
31
|
+
<rescap:Capability Name="runFullTrust" />
|
|
32
|
+
<Capability Name="internetClient" />
|
|
33
|
+
<Capability Name="privateNetworkClientServer" />
|
|
34
|
+
</Capabilities>
|
|
35
|
+
</Package>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Threading;
|
|
3
|
+
using Microsoft.UI.Dispatching;
|
|
4
|
+
using Microsoft.UI.Xaml;
|
|
5
|
+
using WinRT;
|
|
6
|
+
|
|
7
|
+
// Windows-only WinUI desktop app. The custom entry point (DISABLE_XAML_GENERATED_MAIN)
|
|
8
|
+
// has no platform attribute, so CA1416 treats every Windows API call site as "reachable
|
|
9
|
+
// on all platforms." Declaring the assembly's supported platform once tells the analyzer
|
|
10
|
+
// the whole assembly only runs on Windows >= 17763, silencing those false positives.
|
|
11
|
+
[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.17763.0")]
|
|
12
|
+
|
|
13
|
+
namespace __PROJECT_NAME__
|
|
14
|
+
{
|
|
15
|
+
public static class Program
|
|
16
|
+
{
|
|
17
|
+
[System.STAThread]
|
|
18
|
+
public static void Main(string[] args)
|
|
19
|
+
{
|
|
20
|
+
ComWrappersSupport.InitializeComWrappers();
|
|
21
|
+
|
|
22
|
+
Application.Start((_callbackParams) =>
|
|
23
|
+
{
|
|
24
|
+
var dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
|
25
|
+
if (dispatcherQueue != null)
|
|
26
|
+
{
|
|
27
|
+
SynchronizationContext.SetSynchronizationContext(new DispatcherQueueSynchronizationContext(dispatcherQueue));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
new App();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Runtime Directives for .NET Native.
|
|
3
|
+
See https://go.microsoft.com/fwlink/?LinkID=391919
|
|
4
|
+
-->
|
|
5
|
+
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
|
6
|
+
<Application>
|
|
7
|
+
<Assembly Name="*Application*" Dynamic="Required All" />
|
|
8
|
+
</Application>
|
|
9
|
+
</Directives>
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.IO;
|
|
4
|
+
using System.Linq;
|
|
5
|
+
using System.Reflection;
|
|
6
|
+
using System.Runtime.InteropServices;
|
|
7
|
+
using System.Text.Json;
|
|
8
|
+
|
|
9
|
+
namespace __PROJECT_NAME__
|
|
10
|
+
{
|
|
11
|
+
internal sealed class RuntimeHost : IDisposable
|
|
12
|
+
{
|
|
13
|
+
private const string NativeScriptLibrary = "nativescript";
|
|
14
|
+
|
|
15
|
+
[DllImport("kernel32.dll")]
|
|
16
|
+
private static extern bool AttachConsole(int dwProcessId);
|
|
17
|
+
|
|
18
|
+
private const int ATTACH_PARENT_PROCESS = -1;
|
|
19
|
+
|
|
20
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_init))]
|
|
21
|
+
private static extern long runtime_init([MarshalAs(UnmanagedType.LPUTF8Str)] string appRoot);
|
|
22
|
+
|
|
23
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_deinit))]
|
|
24
|
+
private static extern void runtime_deinit(long runtime);
|
|
25
|
+
|
|
26
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_runscript))]
|
|
27
|
+
private static extern void runtime_runscript(long runtime, [MarshalAs(UnmanagedType.LPUTF8Str)] string script, [MarshalAs(UnmanagedType.LPUTF8Str)] string filename);
|
|
28
|
+
|
|
29
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_install_ctrlc_handler))]
|
|
30
|
+
private static extern void runtime_install_ctrlc_handler(int exitCode);
|
|
31
|
+
|
|
32
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_set_local_folder))]
|
|
33
|
+
private static extern void runtime_set_local_folder([MarshalAs(UnmanagedType.LPUTF8Str)] string localFolder);
|
|
34
|
+
|
|
35
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_get_last_js_error))]
|
|
36
|
+
private static extern IntPtr runtime_get_last_js_error();
|
|
37
|
+
|
|
38
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_free_js_error))]
|
|
39
|
+
private static extern void runtime_free_js_error(IntPtr ptr);
|
|
40
|
+
|
|
41
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_has_devtools))]
|
|
42
|
+
private static extern bool runtime_has_devtools();
|
|
43
|
+
|
|
44
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_pump_timers))]
|
|
45
|
+
private static extern void runtime_pump_timers();
|
|
46
|
+
|
|
47
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_notify_app_event))]
|
|
48
|
+
private static extern void runtime_notify_app_event(long runtime, int kind, [MarshalAs(UnmanagedType.LPUTF8Str)] string message);
|
|
49
|
+
|
|
50
|
+
public void NotifyAppEvent(int kind, string message = null)
|
|
51
|
+
{
|
|
52
|
+
if (!_initialized) return;
|
|
53
|
+
try { runtime_notify_app_event(_runtime, kind, message); }
|
|
54
|
+
catch { }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#if DEBUG
|
|
58
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(ns_set_log_to_console))]
|
|
59
|
+
private static extern int ns_set_log_to_console(int enabled);
|
|
60
|
+
|
|
61
|
+
public static bool TrySetLogToConsole(bool enabled)
|
|
62
|
+
{
|
|
63
|
+
try { return ns_set_log_to_console(enabled ? 1 : 0) == 1; }
|
|
64
|
+
catch { return false; }
|
|
65
|
+
}
|
|
66
|
+
#else
|
|
67
|
+
public static bool TrySetLogToConsole(bool enabled) => false;
|
|
68
|
+
#endif
|
|
69
|
+
|
|
70
|
+
public void PumpTimers()
|
|
71
|
+
{
|
|
72
|
+
if (!_initialized) return;
|
|
73
|
+
try { runtime_pump_timers(); }
|
|
74
|
+
catch { }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
#if DEBUG
|
|
78
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_devtools_start))]
|
|
79
|
+
private static extern IntPtr runtime_devtools_start(long runtime, ushort port);
|
|
80
|
+
|
|
81
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_devtools_pump))]
|
|
82
|
+
private static extern void runtime_devtools_pump(long runtime);
|
|
83
|
+
|
|
84
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_free_string))]
|
|
85
|
+
private static extern void runtime_free_string(IntPtr ptr);
|
|
86
|
+
|
|
87
|
+
public string DevtoolsFrontendUrl { get; private set; }
|
|
88
|
+
|
|
89
|
+
private bool _devtoolsAvailable;
|
|
90
|
+
|
|
91
|
+
public void PumpDevtools()
|
|
92
|
+
{
|
|
93
|
+
if (!_initialized || !_devtoolsAvailable) return;
|
|
94
|
+
try { runtime_devtools_pump(_runtime); }
|
|
95
|
+
catch (Exception ex)
|
|
96
|
+
{
|
|
97
|
+
System.Diagnostics.Debug.WriteLine($"[NativeScript DevTools] Pump failed: {ex.Message}");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private void StartDevtoolsSafely()
|
|
102
|
+
{
|
|
103
|
+
if (!runtime_has_devtools()) return;
|
|
104
|
+
IntPtr urlPtr = IntPtr.Zero;
|
|
105
|
+
try
|
|
106
|
+
{
|
|
107
|
+
urlPtr = runtime_devtools_start(_runtime, 42000);
|
|
108
|
+
if (urlPtr == IntPtr.Zero) return;
|
|
109
|
+
var wsUrl = Marshal.PtrToStringUTF8(urlPtr);
|
|
110
|
+
DevtoolsFrontendUrl = wsUrl != null
|
|
111
|
+
? $"devtools://devtools/bundled/inspector.html?ws={wsUrl.Replace("ws://", "")}"
|
|
112
|
+
: null;
|
|
113
|
+
if (DevtoolsFrontendUrl != null)
|
|
114
|
+
{
|
|
115
|
+
_devtoolsAvailable = true;
|
|
116
|
+
System.Diagnostics.Debug.WriteLine($"[NativeScript DevTools] {DevtoolsFrontendUrl}");
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (Exception ex)
|
|
120
|
+
{
|
|
121
|
+
DevtoolsFrontendUrl = null;
|
|
122
|
+
System.Diagnostics.Debug.WriteLine($"[NativeScript DevTools] Start failed: {ex.Message}");
|
|
123
|
+
}
|
|
124
|
+
finally
|
|
125
|
+
{
|
|
126
|
+
if (urlPtr != IntPtr.Zero) runtime_free_string(urlPtr);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
#endif
|
|
130
|
+
|
|
131
|
+
private long _runtime;
|
|
132
|
+
private bool _initialized;
|
|
133
|
+
|
|
134
|
+
public void Initialize()
|
|
135
|
+
{
|
|
136
|
+
if (_initialized) return;
|
|
137
|
+
bool attached = false;
|
|
138
|
+
try { attached = AttachConsole(ATTACH_PARENT_PROCESS); } catch { }
|
|
139
|
+
runtime_install_ctrlc_handler(0);
|
|
140
|
+
runtime_set_local_folder(Windows.Storage.ApplicationData.Current.LocalFolder.Path);
|
|
141
|
+
_runtime = runtime_init(AppContext.BaseDirectory);
|
|
142
|
+
#if DEBUG
|
|
143
|
+
var trySet = TrySetLogToConsole(true);
|
|
144
|
+
System.Diagnostics.Debug.WriteLine($"[NativeScript] TrySetLogToConsole returned={trySet}");
|
|
145
|
+
|
|
146
|
+
// Also notify the managed bridge (if present) so managed-side
|
|
147
|
+
// diagnostics follow the runtime toggle. Use reflection to avoid a
|
|
148
|
+
// hard compile-time dependency on the bridge assembly.
|
|
149
|
+
try
|
|
150
|
+
{
|
|
151
|
+
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
|
152
|
+
{
|
|
153
|
+
try
|
|
154
|
+
{
|
|
155
|
+
var t = asm.GetType("NativeScriptBridge.Bridge");
|
|
156
|
+
if (t is null) continue;
|
|
157
|
+
var m = t.GetMethod("SetLogToConsole", BindingFlags.Public | BindingFlags.Static);
|
|
158
|
+
if (m is null) continue;
|
|
159
|
+
m.Invoke(null, new object[] { true });
|
|
160
|
+
System.Diagnostics.Debug.WriteLine($"[NativeScript] Invoked Bridge.SetLogToConsole on {asm.GetName().Name}");
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
catch { }
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch { }
|
|
167
|
+
if (ConsumeDebugBreakMarker())
|
|
168
|
+
StartDevtoolsSafely();
|
|
169
|
+
#endif
|
|
170
|
+
_initialized = true;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
#if DEBUG
|
|
174
|
+
/// <summary>
|
|
175
|
+
/// Returns true and deletes the marker if the CLI wrote ns-debugbreak to LocalFolder,
|
|
176
|
+
/// matching the Android sentinel-file pattern used by the NativeScript CLI.
|
|
177
|
+
/// </summary>
|
|
178
|
+
private static bool ConsumeDebugBreakMarker()
|
|
179
|
+
{
|
|
180
|
+
try
|
|
181
|
+
{
|
|
182
|
+
var markerPath = System.IO.Path.Combine(
|
|
183
|
+
Windows.Storage.ApplicationData.Current.LocalFolder.Path,
|
|
184
|
+
"ns-debugbreak");
|
|
185
|
+
if (!System.IO.File.Exists(markerPath))
|
|
186
|
+
return false;
|
|
187
|
+
System.IO.File.Delete(markerPath);
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
catch { return false; }
|
|
191
|
+
}
|
|
192
|
+
#endif
|
|
193
|
+
|
|
194
|
+
public void RunMainScript()
|
|
195
|
+
{
|
|
196
|
+
if (!_initialized)
|
|
197
|
+
throw new InvalidOperationException("Runtime must be initialized before running scripts.");
|
|
198
|
+
|
|
199
|
+
var entryPath = ResolveEntryScriptPath();
|
|
200
|
+
if (entryPath == null)
|
|
201
|
+
{
|
|
202
|
+
System.Diagnostics.Debug.WriteLine("[NativeScript Runtime] No entry script found — bundle missing from app directory.");
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
var dir = Path.GetDirectoryName(Path.GetFullPath(entryPath));
|
|
207
|
+
var chunks = new List<string>();
|
|
208
|
+
foreach (var chunkName in new[] { "runtime.js", "vendor.js" })
|
|
209
|
+
{
|
|
210
|
+
var chunkPath = Path.Combine(dir, chunkName);
|
|
211
|
+
if (File.Exists(chunkPath) &&
|
|
212
|
+
!string.Equals(chunkPath, Path.GetFullPath(entryPath), StringComparison.OrdinalIgnoreCase))
|
|
213
|
+
{
|
|
214
|
+
chunks.Add(chunkPath);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
chunks.Add(entryPath);
|
|
218
|
+
|
|
219
|
+
foreach (var scriptPath in chunks)
|
|
220
|
+
{
|
|
221
|
+
var script = File.ReadAllText(Path.GetFullPath(scriptPath));
|
|
222
|
+
try
|
|
223
|
+
{
|
|
224
|
+
runtime_runscript(_runtime, script, Path.GetFileName(scriptPath));
|
|
225
|
+
}
|
|
226
|
+
catch (Exception ex)
|
|
227
|
+
{
|
|
228
|
+
CrashDiagnostics.WriteExceptionReport("RuntimeHost.RunMainScript", ex, "Script=" + scriptPath);
|
|
229
|
+
System.Diagnostics.Debug.WriteLine($"[NativeScript Runtime] Script execution failed ({scriptPath}): {ex}");
|
|
230
|
+
throw;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
private sealed class RuntimePackageConfig
|
|
236
|
+
{
|
|
237
|
+
public string Main { get; set; } = string.Empty;
|
|
238
|
+
public string WindowsMain { get; set; } = string.Empty;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private static string ResolveEntryScriptPath()
|
|
242
|
+
{
|
|
243
|
+
var baseDir = AppContext.BaseDirectory;
|
|
244
|
+
// EXE lives in <project>/bin/; webpack bundle lives in <project>/app/.
|
|
245
|
+
var parentDir = Path.GetDirectoryName(
|
|
246
|
+
baseDir.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))
|
|
247
|
+
?? baseDir;
|
|
248
|
+
|
|
249
|
+
// Candidate app directories: sibling of bin/ first, then directly under baseDir.
|
|
250
|
+
var appDirCandidates = new[]
|
|
251
|
+
{
|
|
252
|
+
Path.Combine(parentDir, "app"),
|
|
253
|
+
Path.Combine(parentDir, "App"),
|
|
254
|
+
Path.Combine(baseDir, "app"),
|
|
255
|
+
Path.Combine(baseDir, "App"),
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
string packageJsonPath = null;
|
|
259
|
+
string resolvedBaseDir = null;
|
|
260
|
+
foreach (var dir in appDirCandidates)
|
|
261
|
+
{
|
|
262
|
+
var candidate = Path.Combine(dir, "package.json");
|
|
263
|
+
if (File.Exists(candidate))
|
|
264
|
+
{
|
|
265
|
+
packageJsonPath = candidate;
|
|
266
|
+
resolvedBaseDir = dir;
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Also accept package.json at the project root (parent of bin/).
|
|
272
|
+
if (packageJsonPath == null && File.Exists(Path.Combine(parentDir, "package.json")))
|
|
273
|
+
{
|
|
274
|
+
packageJsonPath = Path.Combine(parentDir, "package.json");
|
|
275
|
+
resolvedBaseDir = parentDir;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
string Fallback() =>
|
|
279
|
+
appDirCandidates
|
|
280
|
+
.SelectMany(d => new[] { Path.Combine(d, "bundle.js"), Path.Combine(d, "bundle.mjs") })
|
|
281
|
+
.FirstOrDefault(File.Exists);
|
|
282
|
+
|
|
283
|
+
if (packageJsonPath == null)
|
|
284
|
+
return Fallback();
|
|
285
|
+
|
|
286
|
+
try
|
|
287
|
+
{
|
|
288
|
+
var config = ParsePackageConfig(packageJsonPath);
|
|
289
|
+
if (!string.IsNullOrWhiteSpace(config.WindowsMain))
|
|
290
|
+
{
|
|
291
|
+
var p = ResolveScriptPath(resolvedBaseDir, config.WindowsMain);
|
|
292
|
+
if (p != null) return p;
|
|
293
|
+
}
|
|
294
|
+
if (!string.IsNullOrWhiteSpace(config.Main))
|
|
295
|
+
{
|
|
296
|
+
var p = ResolveScriptPath(resolvedBaseDir, config.Main);
|
|
297
|
+
if (p != null) return p;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch { }
|
|
301
|
+
|
|
302
|
+
return Fallback();
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
private static RuntimePackageConfig ParsePackageConfig(string packageJsonPath)
|
|
306
|
+
{
|
|
307
|
+
using var doc = JsonDocument.Parse(File.ReadAllText(packageJsonPath));
|
|
308
|
+
var config = new RuntimePackageConfig();
|
|
309
|
+
if (doc.RootElement.TryGetProperty("main", out var main) && main.ValueKind == JsonValueKind.String)
|
|
310
|
+
config.Main = main.GetString();
|
|
311
|
+
if (doc.RootElement.TryGetProperty("windows", out var win) && win.ValueKind == JsonValueKind.Object &&
|
|
312
|
+
win.TryGetProperty("main", out var winMain) && winMain.ValueKind == JsonValueKind.String)
|
|
313
|
+
config.WindowsMain = winMain.GetString();
|
|
314
|
+
return config;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
private static string ResolveScriptPath(string baseDir, string scriptPath)
|
|
318
|
+
{
|
|
319
|
+
if (string.IsNullOrWhiteSpace(scriptPath)) return null;
|
|
320
|
+
var normalized = scriptPath.Replace('/', Path.DirectorySeparatorChar);
|
|
321
|
+
foreach (var candidate in new[] { normalized, normalized + ".js", normalized + ".mjs" })
|
|
322
|
+
{
|
|
323
|
+
var direct = Path.IsPathRooted(candidate) ? candidate : Path.Combine(baseDir, candidate);
|
|
324
|
+
if (File.Exists(direct)) return direct;
|
|
325
|
+
var appLower = Path.Combine(baseDir, "app", candidate);
|
|
326
|
+
if (File.Exists(appLower)) return appLower;
|
|
327
|
+
var appUpper = Path.Combine(baseDir, "App", candidate);
|
|
328
|
+
if (File.Exists(appUpper)) return appUpper;
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/// Returns the last JavaScript error (message + stack trace) captured during
|
|
334
|
+
/// script execution, or null if no error was recorded since the last call.
|
|
335
|
+
public string GetLastJsError()
|
|
336
|
+
{
|
|
337
|
+
if (!_initialized) return null;
|
|
338
|
+
IntPtr ptr = IntPtr.Zero;
|
|
339
|
+
try
|
|
340
|
+
{
|
|
341
|
+
ptr = runtime_get_last_js_error();
|
|
342
|
+
return ptr == IntPtr.Zero ? null : Marshal.PtrToStringUTF8(ptr);
|
|
343
|
+
}
|
|
344
|
+
catch { return null; }
|
|
345
|
+
finally
|
|
346
|
+
{
|
|
347
|
+
if (ptr != IntPtr.Zero) runtime_free_js_error(ptr);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
public void Dispose()
|
|
352
|
+
{
|
|
353
|
+
if (!_initialized) return;
|
|
354
|
+
runtime_deinit(_runtime);
|
|
355
|
+
_runtime = 0;
|
|
356
|
+
_initialized = false;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|