Skip to content

Commit a84dbb3

Browse files
committed
Installer will now create a symbolic link in both the ProtocolScripts and ProtocolScript\DllImport folder.
Installer will now also sync the symbolic links across the DMS so it doesn't matter where the Low Code App Editor get's run from.
1 parent 453c1aa commit a84dbb3

File tree

3 files changed

+106
-53
lines changed

3 files changed

+106
-53
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Ignore Spelling: App
2+
3+
namespace Low_Code_App_Editor_Package
4+
{
5+
using System;
6+
using System.Diagnostics;
7+
using System.IO;
8+
9+
using Skyline.AppInstaller;
10+
using Skyline.DataMiner.Net;
11+
using Skyline.DataMiner.Net.Messages;
12+
using Skyline.DataMiner.Net.Messages.Advanced;
13+
14+
internal static class Extensions
15+
{
16+
public static void SyncFile(this IConnection connection, string filePath, FileSyncType fileSyncType, Action<string> logger = null)
17+
{
18+
SetDataMinerInfoMessage message = new SetDataMinerInfoMessage
19+
{
20+
What = 41,
21+
StrInfo1 = filePath,
22+
IInfo2 = (int)fileSyncType,
23+
};
24+
25+
var response = connection.HandleSingleResponseMessage(message);
26+
if (response == null)
27+
{
28+
logger?.Invoke($"Could not sync file, did not receive a response. Path: {filePath}");
29+
}
30+
31+
if (response is CreateProtocolFileResponse createProtocolFileResponse && createProtocolFileResponse.ErrorCode != 0)
32+
{
33+
logger?.Invoke($"Could not sync file, the returned error code was {createProtocolFileResponse.ErrorCode}. Path: {filePath}");
34+
}
35+
}
36+
37+
public static void CreateSymbolicLink(this IConnection connection, string path, string targetPath, Action<string> logger = null)
38+
{
39+
var command = $"mklink \"{path}\" \"{targetPath}\"";
40+
if (!File.Exists(path))
41+
{
42+
ExecuteCommand(command, logger);
43+
connection.SyncFile(path, FileSyncType.Added);
44+
logger?.Invoke($"Created the symbolic link.");
45+
return;
46+
}
47+
48+
var attributes = File.GetAttributes(path);
49+
if ((attributes & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
50+
{
51+
logger?.Invoke($"Could not create the symbolic link, there is already a file named {Path.GetFileName(path)} in the {Path.GetDirectoryName(path)} folder.");
52+
}
53+
else
54+
{
55+
logger?.Invoke($"Symbolic link is already present in '{path}', skipping this step.");
56+
}
57+
}
58+
59+
private static void ExecuteCommand(string command, Action<string> logger = null)
60+
{
61+
ProcessStartInfo processInfo = new ProcessStartInfo("cmd.exe", "/c " + command)
62+
{
63+
CreateNoWindow = true, // Hides the console window
64+
UseShellExecute = false, // Necessary for redirecting output
65+
RedirectStandardOutput = true,
66+
RedirectStandardError = true,
67+
Verb = "runas", // Runs the process as administrator (needed for mklink)
68+
};
69+
70+
using (Process process = Process.Start(processInfo))
71+
{
72+
string output = process.StandardOutput.ReadToEnd();
73+
string error = process.StandardError.ReadToEnd();
74+
process.WaitForExit();
75+
76+
if (!string.IsNullOrEmpty(output))
77+
{
78+
logger?.Invoke(output);
79+
}
80+
81+
if (!string.IsNullOrEmpty(error))
82+
{
83+
logger?.Invoke(error);
84+
throw new InvalidOperationException(error);
85+
}
86+
}
87+
}
88+
}
89+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Ignore Spelling: App
2+
3+
namespace Low_Code_App_Editor_Package
4+
{
5+
internal enum FileSyncType
6+
{
7+
Changed = 32,
8+
Removed = 33,
9+
Added = 34,
10+
}
11+
}

Low Code App Editor Package/Low Code App Editor Package.cs

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ DATE VERSION AUTHOR COMMENTS
5353
using System.Diagnostics;
5454
using System.IO;
5555

56+
using Low_Code_App_Editor_Package;
57+
5658
using Skyline.AppInstaller;
5759
using Skyline.DataMiner.Automation;
5860
using Skyline.DataMiner.Net.AppPackages;
@@ -63,10 +65,9 @@ DATE VERSION AUTHOR COMMENTS
6365
internal class Script
6466
{
6567
private const string WebApiLib_ProtocolScripts_Path = @"C:\Skyline DataMiner\ProtocolScripts\WebApiLib.dll";
68+
private const string WebApiLib_ProtocolScripts_DllImport_Path = @"C:\Skyline DataMiner\ProtocolScripts\DllImport\WebApiLib.dll";
6669
private const string WebApiLib_WebPages_Path = @"C:\Skyline DataMiner\Webpages\API\bin\WebApiLib.dll";
6770

68-
private Action<string> logger;
69-
7071
/// <summary>
7172
/// The script entry point.
7273
/// </summary>
@@ -85,61 +86,13 @@ public void Install(Engine engine, AppInstallContext context)
8586
// Custom installation logic can be added here for each individual install package.
8687

8788
// Create a symbolic link to the WebApiLib.dll
88-
logger = installer.Log;
89-
CreateSymbolicLink(WebApiLib_ProtocolScripts_Path, WebApiLib_WebPages_Path);
89+
Action<string> logger = installer.Log;
90+
Engine.SLNetRaw.CreateSymbolicLink(WebApiLib_ProtocolScripts_Path, WebApiLib_WebPages_Path, logger);
91+
Engine.SLNetRaw.CreateSymbolicLink(WebApiLib_ProtocolScripts_DllImport_Path, WebApiLib_WebPages_Path, logger);
9092
}
9193
catch (Exception e)
9294
{
9395
engine.ExitFail("Exception encountered during installation: " + e);
9496
}
9597
}
96-
97-
private void CreateSymbolicLink(string path, string targetPath)
98-
{
99-
var command = $"mklink \"{path}\" \"{targetPath}\"";
100-
if (!File.Exists(path))
101-
{
102-
ExecuteCommand(command);
103-
logger?.Invoke($"Created the symbolic link.");
104-
return;
105-
}
106-
107-
var attributes = File.GetAttributes(path);
108-
if ((attributes & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
109-
{
110-
throw new InvalidOperationException($"Could not create the symbolic link, there is already a file named {Path.GetFileName(path)} in the {Path.GetDirectoryName(path)} folder.");
111-
}
112-
113-
logger?.Invoke($"Symbolic link is already present, skipping this step.");
114-
}
115-
116-
private void ExecuteCommand(string command)
117-
{
118-
ProcessStartInfo processInfo = new ProcessStartInfo("cmd.exe", "/c " + command)
119-
{
120-
CreateNoWindow = true, // Hides the console window
121-
UseShellExecute = false, // Necessary for redirecting output
122-
RedirectStandardOutput = true,
123-
RedirectStandardError = true,
124-
Verb = "runas", // Runs the process as administrator (needed for mklink)
125-
};
126-
127-
using (Process process = Process.Start(processInfo))
128-
{
129-
string output = process.StandardOutput.ReadToEnd();
130-
string error = process.StandardError.ReadToEnd();
131-
process.WaitForExit();
132-
133-
if (!string.IsNullOrEmpty(output))
134-
{
135-
logger?.Invoke(output);
136-
}
137-
138-
if (!string.IsNullOrEmpty(error))
139-
{
140-
logger?.Invoke(error);
141-
throw new InvalidOperationException(error);
142-
}
143-
}
144-
}
14598
}

0 commit comments

Comments
 (0)