@nativescript/windows 0.1.0-alpha.2 → 0.1.0-alpha.21
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/framework/__PROJECT_NAME__/App.xaml.cs +39 -2
- 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 +132 -0
- package/framework/__PROJECT_NAME__/Package.appxmanifest +2 -5
- package/framework/__PROJECT_NAME__/RuntimeHost.cs +122 -18
- package/framework/__PROJECT_NAME__/__PROJECT_NAME__.csproj +70 -18
- package/framework/dotnet-bridge/BinaryProtocol.cs +124 -0
- package/framework/dotnet-bridge/Bridge.BinaryDispatch.cs +177 -0
- package/framework/dotnet-bridge/Bridge.Dispatch.cs +348 -0
- package/framework/dotnet-bridge/Bridge.JsDelegate.cs +100 -0
- package/framework/dotnet-bridge/Bridge.cs +44 -320
- package/framework/dotnet-bridge/DispatchTypes.cs +281 -0
- package/framework/libs/arm64/nativescript.dll +0 -0
- package/framework/libs/devtools/arm64/nativescript.dll +0 -0
- package/framework/libs/devtools/x64/nativescript.dll +0 -0
- package/framework/libs/x64/nativescript.dll +0 -0
- package/package.json +1 -1
- package/framework/__PROJECT_NAME__/App/main.js +0 -12
|
@@ -19,16 +19,46 @@ namespace __PROJECT_NAME__
|
|
|
19
19
|
this.UnhandledException += OnUnhandledException;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
|
22
|
+
protected override async void OnLaunched(LaunchActivatedEventArgs e)
|
|
23
23
|
{
|
|
24
24
|
_runtimeHost.Initialize();
|
|
25
|
+
|
|
26
|
+
// Show crash report from the previous run if one exists.
|
|
27
|
+
try
|
|
28
|
+
{
|
|
29
|
+
var panicLogPath = System.IO.Path.Combine(
|
|
30
|
+
ApplicationData.Current.LocalFolder.Path, "nativescript-panic.log");
|
|
31
|
+
if (System.IO.File.Exists(panicLogPath))
|
|
32
|
+
{
|
|
33
|
+
var content = System.IO.File.ReadAllText(panicLogPath);
|
|
34
|
+
System.IO.File.Delete(panicLogPath);
|
|
35
|
+
if (!string.IsNullOrWhiteSpace(content))
|
|
36
|
+
await CrashDiagnostics.ShowCrashDialogAsync("Crash from previous run", content);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch { }
|
|
40
|
+
|
|
41
|
+
string jsError = null;
|
|
25
42
|
try
|
|
26
43
|
{
|
|
27
44
|
_runtimeHost.RunMainScript();
|
|
45
|
+
jsError = _runtimeHost.GetLastJsError();
|
|
46
|
+
if (!string.IsNullOrEmpty(jsError))
|
|
47
|
+
{
|
|
48
|
+
CrashDiagnostics.WriteMessage("JS Error", jsError);
|
|
49
|
+
var report = CrashDiagnostics.BuildErrorReport(null, jsError);
|
|
50
|
+
CrashDiagnostics.WriteToTraceLog(report);
|
|
51
|
+
await CrashDiagnostics.ShowCrashDialogAsync("JavaScript Error", report);
|
|
52
|
+
}
|
|
28
53
|
}
|
|
29
54
|
catch (Exception scriptEx)
|
|
30
55
|
{
|
|
56
|
+
jsError = _runtimeHost.GetLastJsError();
|
|
31
57
|
System.Diagnostics.Debug.WriteLine($"[NativeScript] Script exception: {scriptEx.Message}");
|
|
58
|
+
CrashDiagnostics.WriteExceptionReport("RunMainScript", scriptEx, null);
|
|
59
|
+
var report = CrashDiagnostics.BuildErrorReport(scriptEx, jsError);
|
|
60
|
+
CrashDiagnostics.WriteToTraceLog(report);
|
|
61
|
+
await CrashDiagnostics.ShowCrashDialogAsync("Script Execution Error", report);
|
|
32
62
|
}
|
|
33
63
|
|
|
34
64
|
#if DEBUG
|
|
@@ -66,10 +96,17 @@ namespace __PROJECT_NAME__
|
|
|
66
96
|
|
|
67
97
|
private void OnUnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
|
|
68
98
|
{
|
|
99
|
+
e.Handled = true;
|
|
100
|
+
var jsError = _runtimeHost.GetLastJsError();
|
|
69
101
|
CrashDiagnostics.WriteExceptionReport(
|
|
70
102
|
"Xaml.UnhandledException",
|
|
71
103
|
e.Exception,
|
|
72
|
-
"
|
|
104
|
+
"JsError=" + (jsError ?? "<none>"));
|
|
105
|
+
|
|
106
|
+
var report = CrashDiagnostics.BuildErrorReport(e.Exception, jsError);
|
|
107
|
+
CrashDiagnostics.WriteToTraceLog(report);
|
|
108
|
+
var _ = CrashDiagnostics.ShowCrashDialogAsync(
|
|
109
|
+
e.Message ?? "Unhandled exception", report);
|
|
73
110
|
}
|
|
74
111
|
|
|
75
112
|
#if DEBUG
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -2,7 +2,10 @@ using System;
|
|
|
2
2
|
using System.IO;
|
|
3
3
|
using System.Text;
|
|
4
4
|
using System.Threading.Tasks;
|
|
5
|
+
using Windows.ApplicationModel.Core;
|
|
6
|
+
using Windows.ApplicationModel.DataTransfer;
|
|
5
7
|
using Windows.Storage;
|
|
8
|
+
using Windows.UI.Popups;
|
|
6
9
|
|
|
7
10
|
namespace __PROJECT_NAME__
|
|
8
11
|
{
|
|
@@ -53,6 +56,135 @@ namespace __PROJECT_NAME__
|
|
|
53
56
|
AppendToLog(sb.ToString());
|
|
54
57
|
}
|
|
55
58
|
|
|
59
|
+
public static string BuildErrorReport(Exception ex, string jsError = null, string extraDetails = null)
|
|
60
|
+
{
|
|
61
|
+
var sb = new StringBuilder();
|
|
62
|
+
|
|
63
|
+
if (!string.IsNullOrWhiteSpace(jsError))
|
|
64
|
+
{
|
|
65
|
+
sb.AppendLine("── JavaScript Error ──────────────────────────────────────");
|
|
66
|
+
sb.AppendLine(jsError.Trim());
|
|
67
|
+
sb.AppendLine();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (ex != null)
|
|
71
|
+
{
|
|
72
|
+
sb.AppendLine("── Native Exception ──────────────────────────────────────");
|
|
73
|
+
sb.AppendLine(ex.GetType().Name + ": " + ex.Message);
|
|
74
|
+
if (ex.StackTrace != null) sb.AppendLine(ex.StackTrace);
|
|
75
|
+
var inner = ex.InnerException;
|
|
76
|
+
while (inner != null)
|
|
77
|
+
{
|
|
78
|
+
sb.AppendLine("Caused by: " + inner.GetType().Name + ": " + inner.Message);
|
|
79
|
+
if (inner.StackTrace != null) sb.AppendLine(inner.StackTrace);
|
|
80
|
+
inner = inner.InnerException;
|
|
81
|
+
}
|
|
82
|
+
sb.AppendLine();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Include panic log from previous or current run
|
|
86
|
+
try
|
|
87
|
+
{
|
|
88
|
+
var panicLog = Path.Combine(ApplicationData.Current.LocalFolder.Path, "nativescript-panic.log");
|
|
89
|
+
if (File.Exists(panicLog))
|
|
90
|
+
{
|
|
91
|
+
var content = File.ReadAllText(panicLog, Encoding.UTF8).Trim();
|
|
92
|
+
if (!string.IsNullOrEmpty(content))
|
|
93
|
+
{
|
|
94
|
+
sb.AppendLine("── Rust Panic Log ────────────────────────────────────────");
|
|
95
|
+
sb.AppendLine(content);
|
|
96
|
+
sb.AppendLine();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch { }
|
|
101
|
+
|
|
102
|
+
if (!string.IsNullOrWhiteSpace(extraDetails))
|
|
103
|
+
{
|
|
104
|
+
sb.AppendLine("── Additional Info ───────────────────────────────────────");
|
|
105
|
+
sb.AppendLine(extraDetails);
|
|
106
|
+
sb.AppendLine();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
sb.AppendLine("──────────────────────────────────────────────────────────");
|
|
110
|
+
sb.AppendLine("Timestamp: " + DateTimeOffset.UtcNow.ToString("o"));
|
|
111
|
+
|
|
112
|
+
return sb.ToString();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public static string CrashLogPath()
|
|
116
|
+
{
|
|
117
|
+
try { return Path.Combine(ApplicationData.Current.LocalFolder.Path, "nativescript-crash.log"); }
|
|
118
|
+
catch { return null; }
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public static async Task ShowCrashDialogAsync(string heading, string errorReport)
|
|
122
|
+
{
|
|
123
|
+
try
|
|
124
|
+
{
|
|
125
|
+
// Write full details to log so developer can access them even if the
|
|
126
|
+
// dialog summary is truncated.
|
|
127
|
+
var logPath = CrashLogPath();
|
|
128
|
+
if (logPath != null)
|
|
129
|
+
File.WriteAllText(logPath, errorReport, Encoding.UTF8);
|
|
130
|
+
|
|
131
|
+
// Truncate for the dialog (MessageDialog has practical limits).
|
|
132
|
+
const int MaxLen = 800;
|
|
133
|
+
var summary = errorReport.Length > MaxLen
|
|
134
|
+
? errorReport.Substring(0, MaxLen) + "\n\n[truncated — see log for full details]"
|
|
135
|
+
: errorReport;
|
|
136
|
+
|
|
137
|
+
if (logPath != null)
|
|
138
|
+
summary += "\n\nFull log: " + logPath;
|
|
139
|
+
|
|
140
|
+
var dialog = new MessageDialog(summary, "NativeScript Runtime Error");
|
|
141
|
+
|
|
142
|
+
dialog.Commands.Add(new UICommand("Copy Details", _ =>
|
|
143
|
+
{
|
|
144
|
+
try
|
|
145
|
+
{
|
|
146
|
+
var dp = new DataPackage();
|
|
147
|
+
dp.SetText(errorReport);
|
|
148
|
+
Clipboard.SetContent(dp);
|
|
149
|
+
}
|
|
150
|
+
catch { }
|
|
151
|
+
}));
|
|
152
|
+
|
|
153
|
+
dialog.Commands.Add(new UICommand("Restart App", async _ =>
|
|
154
|
+
{
|
|
155
|
+
try { await CoreApplication.RequestRestartAsync("crash-restart"); }
|
|
156
|
+
catch { }
|
|
157
|
+
}));
|
|
158
|
+
|
|
159
|
+
dialog.Commands.Add(new UICommand("Dismiss"));
|
|
160
|
+
dialog.DefaultCommandIndex = 0;
|
|
161
|
+
dialog.CancelCommandIndex = 2;
|
|
162
|
+
|
|
163
|
+
await dialog.ShowAsync();
|
|
164
|
+
}
|
|
165
|
+
catch (Exception ex)
|
|
166
|
+
{
|
|
167
|
+
System.Diagnostics.Debug.WriteLine("[NativeScript] Failed to show crash dialog: " + ex.Message);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/// <summary>
|
|
172
|
+
/// Appends <paramref name="message"/> to ns_trace.log using the Win32 temp path.
|
|
173
|
+
/// Inside UWP, GetTempPath() virtualises to AC\Temp — the same folder Rust's
|
|
174
|
+
/// std::env::temp_dir() uses — so this write appears in the CLI's log stream.
|
|
175
|
+
/// </summary>
|
|
176
|
+
public static void WriteToTraceLog(string message)
|
|
177
|
+
{
|
|
178
|
+
try
|
|
179
|
+
{
|
|
180
|
+
// System.IO.Path.GetTempPath() calls Win32 GetTempPathW() which inside a
|
|
181
|
+
// UWP process returns the container's AC\Temp folder, matching Rust.
|
|
182
|
+
var tracePath = Path.Combine(System.IO.Path.GetTempPath(), "ns_trace.log");
|
|
183
|
+
File.AppendAllText(tracePath, message, Encoding.UTF8);
|
|
184
|
+
}
|
|
185
|
+
catch { }
|
|
186
|
+
}
|
|
187
|
+
|
|
56
188
|
private static void AppendToLog(string content)
|
|
57
189
|
{
|
|
58
190
|
try
|
|
@@ -2,17 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<Package
|
|
4
4
|
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
|
5
|
-
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
|
6
5
|
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
|
7
|
-
IgnorableNamespaces="uap
|
|
6
|
+
IgnorableNamespaces="uap">
|
|
8
7
|
|
|
9
8
|
<Identity
|
|
10
9
|
Name="__APP_IDENTIFIER__"
|
|
11
10
|
Publisher="CN=__PROJECT_NAME__"
|
|
12
11
|
Version="1.0.0.0" />
|
|
13
12
|
|
|
14
|
-
<mp:PhoneIdentity PhoneProductId="__APP_IDENTIFIER__" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
|
15
|
-
|
|
16
13
|
<Properties>
|
|
17
14
|
<DisplayName>__PROJECT_NAME__</DisplayName>
|
|
18
15
|
<PublisherDisplayName>__PROJECT_NAME__</PublisherDisplayName>
|
|
@@ -24,7 +21,7 @@
|
|
|
24
21
|
</Dependencies>
|
|
25
22
|
|
|
26
23
|
<Resources>
|
|
27
|
-
<Resource Language="
|
|
24
|
+
<Resource Language="en-US"/>
|
|
28
25
|
</Resources>
|
|
29
26
|
|
|
30
27
|
<Applications>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
2
3
|
using System.IO;
|
|
4
|
+
using System.Linq;
|
|
3
5
|
using System.Runtime.InteropServices;
|
|
4
6
|
using System.Text.Json;
|
|
5
7
|
|
|
@@ -26,6 +28,18 @@ namespace __PROJECT_NAME__
|
|
|
26
28
|
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_install_ctrlc_handler))]
|
|
27
29
|
private static extern void runtime_install_ctrlc_handler(int exitCode);
|
|
28
30
|
|
|
31
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_set_local_folder))]
|
|
32
|
+
private static extern void runtime_set_local_folder([MarshalAs(UnmanagedType.LPUTF8Str)] string localFolder);
|
|
33
|
+
|
|
34
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_get_last_js_error))]
|
|
35
|
+
private static extern IntPtr runtime_get_last_js_error();
|
|
36
|
+
|
|
37
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_free_js_error))]
|
|
38
|
+
private static extern void runtime_free_js_error(IntPtr ptr);
|
|
39
|
+
|
|
40
|
+
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_has_devtools))]
|
|
41
|
+
private static extern bool runtime_has_devtools();
|
|
42
|
+
|
|
29
43
|
#if DEBUG
|
|
30
44
|
[DllImport(NativeScriptLibrary, EntryPoint = nameof(runtime_devtools_start))]
|
|
31
45
|
private static extern IntPtr runtime_devtools_start(long runtime, ushort port);
|
|
@@ -38,9 +52,11 @@ namespace __PROJECT_NAME__
|
|
|
38
52
|
|
|
39
53
|
public string DevtoolsFrontendUrl { get; private set; }
|
|
40
54
|
|
|
55
|
+
private bool _devtoolsAvailable;
|
|
56
|
+
|
|
41
57
|
public void PumpDevtools()
|
|
42
58
|
{
|
|
43
|
-
if (!_initialized) return;
|
|
59
|
+
if (!_initialized || !_devtoolsAvailable) return;
|
|
44
60
|
try { runtime_devtools_pump(_runtime); }
|
|
45
61
|
catch (Exception ex)
|
|
46
62
|
{
|
|
@@ -50,6 +66,7 @@ namespace __PROJECT_NAME__
|
|
|
50
66
|
|
|
51
67
|
private void StartDevtoolsSafely()
|
|
52
68
|
{
|
|
69
|
+
if (!runtime_has_devtools()) return;
|
|
53
70
|
IntPtr urlPtr = IntPtr.Zero;
|
|
54
71
|
try
|
|
55
72
|
{
|
|
@@ -60,7 +77,10 @@ namespace __PROJECT_NAME__
|
|
|
60
77
|
? $"devtools://devtools/bundled/inspector.html?ws={wsUrl.Replace("ws://", "")}"
|
|
61
78
|
: null;
|
|
62
79
|
if (DevtoolsFrontendUrl != null)
|
|
80
|
+
{
|
|
81
|
+
_devtoolsAvailable = true;
|
|
63
82
|
System.Diagnostics.Debug.WriteLine($"[NativeScript DevTools] {DevtoolsFrontendUrl}");
|
|
83
|
+
}
|
|
64
84
|
}
|
|
65
85
|
catch (Exception ex)
|
|
66
86
|
{
|
|
@@ -82,6 +102,7 @@ namespace __PROJECT_NAME__
|
|
|
82
102
|
if (_initialized) return;
|
|
83
103
|
AttachConsole(ATTACH_PARENT_PROCESS);
|
|
84
104
|
runtime_install_ctrlc_handler(0);
|
|
105
|
+
runtime_set_local_folder(Windows.Storage.ApplicationData.Current.LocalFolder.Path);
|
|
85
106
|
_runtime = runtime_init(AppContext.BaseDirectory);
|
|
86
107
|
#if DEBUG
|
|
87
108
|
if (ConsumeDebugBreakMarker())
|
|
@@ -117,16 +138,38 @@ namespace __PROJECT_NAME__
|
|
|
117
138
|
throw new InvalidOperationException("Runtime must be initialized before running scripts.");
|
|
118
139
|
|
|
119
140
|
var entryPath = ResolveEntryScriptPath();
|
|
120
|
-
|
|
121
|
-
try
|
|
141
|
+
if (entryPath == null)
|
|
122
142
|
{
|
|
123
|
-
|
|
143
|
+
System.Diagnostics.Debug.WriteLine("[NativeScript Runtime] No entry script found — bundle missing from app directory.");
|
|
144
|
+
return;
|
|
124
145
|
}
|
|
125
|
-
|
|
146
|
+
|
|
147
|
+
var dir = Path.GetDirectoryName(Path.GetFullPath(entryPath));
|
|
148
|
+
var chunks = new List<string>();
|
|
149
|
+
foreach (var chunkName in new[] { "runtime.js", "vendor.js" })
|
|
126
150
|
{
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
151
|
+
var chunkPath = Path.Combine(dir, chunkName);
|
|
152
|
+
if (File.Exists(chunkPath) &&
|
|
153
|
+
!string.Equals(chunkPath, Path.GetFullPath(entryPath), StringComparison.OrdinalIgnoreCase))
|
|
154
|
+
{
|
|
155
|
+
chunks.Add(chunkPath);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
chunks.Add(entryPath);
|
|
159
|
+
|
|
160
|
+
foreach (var scriptPath in chunks)
|
|
161
|
+
{
|
|
162
|
+
var script = File.ReadAllText(Path.GetFullPath(scriptPath));
|
|
163
|
+
try
|
|
164
|
+
{
|
|
165
|
+
runtime_runscript(_runtime, script, Path.GetFileName(scriptPath));
|
|
166
|
+
}
|
|
167
|
+
catch (Exception ex)
|
|
168
|
+
{
|
|
169
|
+
CrashDiagnostics.WriteExceptionReport("RuntimeHost.RunMainScript", ex, "Script=" + scriptPath);
|
|
170
|
+
System.Diagnostics.Debug.WriteLine($"[NativeScript Runtime] Script execution failed ({scriptPath}): {ex}");
|
|
171
|
+
throw;
|
|
172
|
+
}
|
|
130
173
|
}
|
|
131
174
|
}
|
|
132
175
|
|
|
@@ -139,28 +182,65 @@ namespace __PROJECT_NAME__
|
|
|
139
182
|
private static string ResolveEntryScriptPath()
|
|
140
183
|
{
|
|
141
184
|
var baseDir = AppContext.BaseDirectory;
|
|
142
|
-
|
|
143
|
-
var
|
|
185
|
+
// EXE lives in <project>/bin/; webpack bundle lives in <project>/app/.
|
|
186
|
+
var parentDir = Path.GetDirectoryName(
|
|
187
|
+
baseDir.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))
|
|
188
|
+
?? baseDir;
|
|
189
|
+
|
|
190
|
+
// Candidate app directories: sibling of bin/ first, then directly under baseDir.
|
|
191
|
+
var appDirCandidates = new[]
|
|
192
|
+
{
|
|
193
|
+
Path.Combine(parentDir, "app"),
|
|
194
|
+
Path.Combine(parentDir, "App"),
|
|
195
|
+
Path.Combine(baseDir, "app"),
|
|
196
|
+
Path.Combine(baseDir, "App"),
|
|
197
|
+
};
|
|
144
198
|
|
|
145
|
-
|
|
199
|
+
string packageJsonPath = null;
|
|
200
|
+
string resolvedBaseDir = null;
|
|
201
|
+
foreach (var dir in appDirCandidates)
|
|
202
|
+
{
|
|
203
|
+
var candidate = Path.Combine(dir, "package.json");
|
|
204
|
+
if (File.Exists(candidate))
|
|
205
|
+
{
|
|
206
|
+
packageJsonPath = candidate;
|
|
207
|
+
resolvedBaseDir = dir;
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Also accept package.json at the project root (parent of bin/).
|
|
213
|
+
if (packageJsonPath == null && File.Exists(Path.Combine(parentDir, "package.json")))
|
|
214
|
+
{
|
|
215
|
+
packageJsonPath = Path.Combine(parentDir, "package.json");
|
|
216
|
+
resolvedBaseDir = parentDir;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
string Fallback() =>
|
|
220
|
+
appDirCandidates
|
|
221
|
+
.SelectMany(d => new[] { Path.Combine(d, "bundle.js"), Path.Combine(d, "bundle.mjs") })
|
|
222
|
+
.FirstOrDefault(File.Exists);
|
|
223
|
+
|
|
224
|
+
if (packageJsonPath == null)
|
|
225
|
+
return Fallback();
|
|
146
226
|
|
|
147
227
|
try
|
|
148
228
|
{
|
|
149
229
|
var config = ParsePackageConfig(packageJsonPath);
|
|
150
230
|
if (!string.IsNullOrWhiteSpace(config.WindowsMain))
|
|
151
231
|
{
|
|
152
|
-
var p = ResolveScriptPath(
|
|
232
|
+
var p = ResolveScriptPath(resolvedBaseDir, config.WindowsMain);
|
|
153
233
|
if (p != null) return p;
|
|
154
234
|
}
|
|
155
235
|
if (!string.IsNullOrWhiteSpace(config.Main))
|
|
156
236
|
{
|
|
157
|
-
var p = ResolveScriptPath(
|
|
237
|
+
var p = ResolveScriptPath(resolvedBaseDir, config.Main);
|
|
158
238
|
if (p != null) return p;
|
|
159
239
|
}
|
|
160
240
|
}
|
|
161
241
|
catch { }
|
|
162
242
|
|
|
163
|
-
return
|
|
243
|
+
return Fallback();
|
|
164
244
|
}
|
|
165
245
|
|
|
166
246
|
private static RuntimePackageConfig ParsePackageConfig(string packageJsonPath)
|
|
@@ -179,10 +259,34 @@ namespace __PROJECT_NAME__
|
|
|
179
259
|
{
|
|
180
260
|
if (string.IsNullOrWhiteSpace(scriptPath)) return null;
|
|
181
261
|
var normalized = scriptPath.Replace('/', Path.DirectorySeparatorChar);
|
|
182
|
-
var
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
262
|
+
foreach (var candidate in new[] { normalized, normalized + ".js", normalized + ".mjs" })
|
|
263
|
+
{
|
|
264
|
+
var direct = Path.IsPathRooted(candidate) ? candidate : Path.Combine(baseDir, candidate);
|
|
265
|
+
if (File.Exists(direct)) return direct;
|
|
266
|
+
var appLower = Path.Combine(baseDir, "app", candidate);
|
|
267
|
+
if (File.Exists(appLower)) return appLower;
|
|
268
|
+
var appUpper = Path.Combine(baseDir, "App", candidate);
|
|
269
|
+
if (File.Exists(appUpper)) return appUpper;
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/// Returns the last JavaScript error (message + stack trace) captured during
|
|
275
|
+
/// script execution, or null if no error was recorded since the last call.
|
|
276
|
+
public string GetLastJsError()
|
|
277
|
+
{
|
|
278
|
+
if (!_initialized) return null;
|
|
279
|
+
IntPtr ptr = IntPtr.Zero;
|
|
280
|
+
try
|
|
281
|
+
{
|
|
282
|
+
ptr = runtime_get_last_js_error();
|
|
283
|
+
return ptr == IntPtr.Zero ? null : Marshal.PtrToStringUTF8(ptr);
|
|
284
|
+
}
|
|
285
|
+
catch { return null; }
|
|
286
|
+
finally
|
|
287
|
+
{
|
|
288
|
+
if (ptr != IntPtr.Zero) runtime_free_js_error(ptr);
|
|
289
|
+
}
|
|
186
290
|
}
|
|
187
291
|
|
|
188
292
|
public void Dispose()
|
|
@@ -19,12 +19,24 @@
|
|
|
19
19
|
<NSWindowsRoot>$(MSBuildProjectDirectory)\..</NSWindowsRoot>
|
|
20
20
|
</PropertyGroup>
|
|
21
21
|
|
|
22
|
+
<PropertyGroup>
|
|
23
|
+
<!-- Derived library platform for selecting prebuilt native libs.
|
|
24
|
+
Prefer $(Platform); fall back to trimming 'win-' from $(RuntimeIdentifier); default to x64. -->
|
|
25
|
+
<NSLibPlatform Condition="'$(Platform)' != ''">$(Platform)</NSLibPlatform>
|
|
26
|
+
<NSLibPlatform Condition="'$(NSLibPlatform)' == '' and '$(RuntimeIdentifier)' != ''">$([System.Text.RegularExpressions.Regex]::Replace('$(RuntimeIdentifier)','^win-',''))</NSLibPlatform>
|
|
27
|
+
<NSLibPlatform Condition="'$(NSLibPlatform)' == ''">x64</NSLibPlatform>
|
|
28
|
+
<!-- Windows SDK .NET runtime pack location (resolved from NuGet cache) -->
|
|
29
|
+
<_WinSdkNetRefPkg>$(NuGetPackageRoot)microsoft.windows.sdk.net.ref</_WinSdkNetRefPkg>
|
|
30
|
+
<_WinSdkNetRefVer Condition="Exists('$(_WinSdkNetRefPkg)\10.0.26100.57')">10.0.26100.57</_WinSdkNetRefVer>
|
|
31
|
+
<_WinSdkNetRefLib Condition="'$(_WinSdkNetRefVer)' != ''">$(_WinSdkNetRefPkg)\$(_WinSdkNetRefVer)\lib\net8.0</_WinSdkNetRefLib>
|
|
32
|
+
</PropertyGroup>
|
|
33
|
+
|
|
22
34
|
<ItemGroup>
|
|
23
35
|
<AppxManifest Include="Package.appxmanifest" />
|
|
24
36
|
<Content Include="Properties\Default.rd.xml" />
|
|
25
37
|
|
|
26
38
|
<!-- App JS/resource files — copied to the output directory on every build -->
|
|
27
|
-
<Content Include="
|
|
39
|
+
<Content Include="app\**\*">
|
|
28
40
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
29
41
|
</Content>
|
|
30
42
|
|
|
@@ -33,35 +45,49 @@
|
|
|
33
45
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
34
46
|
</Content>
|
|
35
47
|
|
|
36
|
-
<!--
|
|
37
|
-
<Content Include="
|
|
38
|
-
|
|
39
|
-
|
|
48
|
+
<!-- UWP logo/splash assets required for Add-AppxPackage -Register -->
|
|
49
|
+
<Content Include="Assets\**\*" Condition="Exists('Assets')">
|
|
50
|
+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
51
|
+
</Content>
|
|
52
|
+
|
|
53
|
+
<!-- Windows SDK .NET runtime pack assemblies — required when the dotnet workload
|
|
54
|
+
is not installed; copied from the NuGet package cache. -->
|
|
55
|
+
<Content Include="$(_WinSdkNetRefLib)\Microsoft.Windows.UI.Xaml.dll"
|
|
56
|
+
Condition="'$(_WinSdkNetRefLib)' != '' and Exists('$(_WinSdkNetRefLib)\Microsoft.Windows.UI.Xaml.dll')">
|
|
57
|
+
<Link>Microsoft.Windows.UI.Xaml.dll</Link>
|
|
58
|
+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
59
|
+
</Content>
|
|
60
|
+
<Content Include="$(_WinSdkNetRefLib)\WinRT.Runtime.dll"
|
|
61
|
+
Condition="'$(_WinSdkNetRefLib)' != '' and Exists('$(_WinSdkNetRefLib)\WinRT.Runtime.dll')">
|
|
62
|
+
<Link>WinRT.Runtime.dll</Link>
|
|
63
|
+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
64
|
+
</Content>
|
|
65
|
+
<Content Include="$(_WinSdkNetRefLib)\Microsoft.Windows.SDK.NET.dll"
|
|
66
|
+
Condition="'$(_WinSdkNetRefLib)' != '' and Exists('$(_WinSdkNetRefLib)\Microsoft.Windows.SDK.NET.dll')">
|
|
67
|
+
<Link>Microsoft.Windows.SDK.NET.dll</Link>
|
|
40
68
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
41
69
|
</Content>
|
|
42
70
|
|
|
43
|
-
<!--
|
|
44
|
-
<Content Include="$(NSWindowsRoot)\libs\$(
|
|
45
|
-
Condition="'$(Configuration)'
|
|
71
|
+
<!-- Debug: devtools-enabled runtime DLL (platform fallback via NSLibPlatform) -->
|
|
72
|
+
<Content Include="$(NSWindowsRoot)\libs\devtools\$(NSLibPlatform)\nativescript.dll"
|
|
73
|
+
Condition="'$(Configuration)' == 'Debug' and Exists('$(NSWindowsRoot)\libs\devtools\$(NSLibPlatform)\nativescript.dll')">
|
|
46
74
|
<Link>nativescript.dll</Link>
|
|
47
75
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
48
76
|
</Content>
|
|
49
77
|
|
|
50
|
-
<!--
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<Content Include="$(NSWindowsRoot)\dotnet-bridge\publish\**\*"
|
|
55
|
-
Condition="Exists('$(NSWindowsRoot)\dotnet-bridge\publish')">
|
|
56
|
-
<Link>dotnet-bridge\publish\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
|
78
|
+
<!-- Release: production runtime DLL (platform fallback via NSLibPlatform) -->
|
|
79
|
+
<Content Include="$(NSWindowsRoot)\libs\$(NSLibPlatform)\nativescript.dll"
|
|
80
|
+
Condition="'$(Configuration)' != 'Debug' and Exists('$(NSWindowsRoot)\libs\$(NSLibPlatform)\nativescript.dll')">
|
|
81
|
+
<Link>nativescript.dll</Link>
|
|
57
82
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
58
83
|
</Content>
|
|
84
|
+
|
|
59
85
|
</ItemGroup>
|
|
60
86
|
|
|
61
87
|
<!--
|
|
62
|
-
Publishes DotNetBridge.dll before the app build
|
|
63
|
-
|
|
64
|
-
|
|
88
|
+
Publishes DotNetBridge.dll before the app build.
|
|
89
|
+
Inputs/Outputs make this incremental: MSBuild skips the Exec when DotNetBridge.dll
|
|
90
|
+
is already newer than both source files.
|
|
65
91
|
-->
|
|
66
92
|
<Target Name="PublishDotNetBridge"
|
|
67
93
|
BeforeTargets="Build"
|
|
@@ -72,4 +98,30 @@
|
|
|
72
98
|
<Message Text="[NativeScript] Publishing DotNetBridge..." Importance="high" />
|
|
73
99
|
<Exec Command="dotnet publish "$(NSWindowsRoot)\dotnet-bridge\DotNetBridge.csproj" -c Release -o "$(NSWindowsRoot)\dotnet-bridge\publish" --no-self-contained /nologo" />
|
|
74
100
|
</Target>
|
|
101
|
+
|
|
102
|
+
<!--
|
|
103
|
+
Copies the published bridge files to the output directory AFTER PublishDotNetBridge
|
|
104
|
+
runs, avoiding the MSBuild evaluation-order problem where Condition="Exists(...)"
|
|
105
|
+
on a static Content item is checked before the publish target creates the directory.
|
|
106
|
+
Must land at dotnet-bridge\publish\ relative to the EXE so the Rust runtime can
|
|
107
|
+
locate DotNetBridge.dll via AppContext.BaseDirectory.
|
|
108
|
+
-->
|
|
109
|
+
<Target Name="CopyDotNetBridge"
|
|
110
|
+
AfterTargets="PublishDotNetBridge"
|
|
111
|
+
BeforeTargets="Build"
|
|
112
|
+
Condition="Exists('$(NSWindowsRoot)\dotnet-bridge\publish')">
|
|
113
|
+
<ItemGroup>
|
|
114
|
+
<_DotNetBridgeFiles Include="$(NSWindowsRoot)\dotnet-bridge\publish\**\*" />
|
|
115
|
+
</ItemGroup>
|
|
116
|
+
<Copy SourceFiles="@(_DotNetBridgeFiles)"
|
|
117
|
+
DestinationFiles="@(_DotNetBridgeFiles->'$(OutDir)dotnet-bridge\publish\%(RecursiveDir)%(Filename)%(Extension)')"
|
|
118
|
+
SkipUnchangedFiles="true" />
|
|
119
|
+
</Target>
|
|
120
|
+
|
|
121
|
+
<!-- Allow project-level Windows overrides: place App_Resources\Windows\app.csproj to extend/override generated settings -->
|
|
122
|
+
<Import Project="App_Resources\Windows\app.csproj" Condition="Exists('App_Resources\Windows\app.csproj')" />
|
|
123
|
+
|
|
124
|
+
<!-- CLI-generated plugin imports (managed by the CLI during prepare) -->
|
|
125
|
+
<Import Project="plugins\Plugins.props" Condition="Exists('plugins\Plugins.props')" />
|
|
126
|
+
<Import Project="plugins\Plugins.targets" Condition="Exists('plugins\Plugins.targets')" />
|
|
75
127
|
</Project>
|