diff --git a/Commands/Commands.csproj b/Commands/Commands.csproj
index c4a41360..7e3274b5 100644
--- a/Commands/Commands.csproj
+++ b/Commands/Commands.csproj
@@ -51,7 +51,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/Commands/ExtensionMethods.cs b/Commands/ExtensionMethods.cs
index a7082d40..ddc903a3 100644
--- a/Commands/ExtensionMethods.cs
+++ b/Commands/ExtensionMethods.cs
@@ -82,6 +82,6 @@ internal static string MiddleString(this string input, string firstParam, string
///
///
///
- internal static string GetParamValueFirewall(this string arg, string param) => arg.SplitByText(param, 1).Trim().Split(' ')[0];
+ internal static string GetParamValue(this string arg, string param) => arg.SplitByText(param, 1).Trim().Split(' ')[0];
}
}
\ No newline at end of file
diff --git a/Commands/Properties/AssemblyInfo.cs b/Commands/Properties/AssemblyInfo.cs
index 23f1f531..6a85076f 100644
--- a/Commands/Properties/AssemblyInfo.cs
+++ b/Commands/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.8.2.0")]
-[assembly: AssemblyFileVersion("1.8.2.0")]
+[assembly: AssemblyVersion("1.8.3.0")]
+[assembly: AssemblyFileVersion("1.8.3.0")]
diff --git a/Commands/TerminalCommands/ConsoleSystem/Firewall.cs b/Commands/TerminalCommands/ConsoleSystem/Firewall.cs
index 255ef992..da82027a 100644
--- a/Commands/TerminalCommands/ConsoleSystem/Firewall.cs
+++ b/Commands/TerminalCommands/ConsoleSystem/Firewall.cs
@@ -141,30 +141,30 @@ public void Execute(string arg)
}
if (arg.Contains("-pf "))
- profile = Int32.Parse(arg.GetParamValueFirewall("-pf "));
+ profile = Int32.Parse(arg.GetParamValue("-pf "));
if (arg.Contains("-di "))
- direction = arg.GetParamValueFirewall("-di ");
+ direction = arg.GetParamValue("-di ");
if (arg.Contains("-a "))
- action = arg.GetParamValueFirewall("-a ");
+ action = arg.GetParamValue("-a ");
if (arg.Contains("-lP "))
- localPort = arg.GetParamValueFirewall("-lP ");
+ localPort = arg.GetParamValue("-lP ");
if (arg.Contains("-rP "))
- remotePort = arg.GetParamValueFirewall("-rP ");
+ remotePort = arg.GetParamValue("-rP ");
if (arg.Contains("-lA "))
- localAddress = arg.GetParamValueFirewall("-lA ");
+ localAddress = arg.GetParamValue("-lA ");
if (arg.Contains("-rA "))
- remoteAddress = arg.GetParamValueFirewall("-rA ");
+ remoteAddress = arg.GetParamValue("-rA ");
if (arg.Contains("-pr "))
- protocol = Int32.Parse(arg.GetParamValueFirewall("-pr "));
+ protocol = Int32.Parse(arg.GetParamValue("-pr "));
if (arg.Contains("-e "))
- enable = arg.GetParamValueFirewall("-e ");
+ enable = arg.GetParamValue("-e ");
if (arg.Contains("-de "))
{
@@ -233,7 +233,7 @@ public void Execute(string arg)
}
catch (Exception ex)
{
- FileSystem.ErrorWriteLine($"{ex.ToString()}. Use -h for more information!");
+ FileSystem.ErrorWriteLine($"{ex.Message}. Use -h for more information!");
}
}
}
diff --git a/Commands/TerminalCommands/ConsoleSystem/Help.cs b/Commands/TerminalCommands/ConsoleSystem/Help.cs
index 01fd5c38..ed6fad89 100644
--- a/Commands/TerminalCommands/ConsoleSystem/Help.cs
+++ b/Commands/TerminalCommands/ConsoleSystem/Help.cs
@@ -74,6 +74,7 @@ public void Execute(string arg)
pjson -- Prettify the JSON data. Use -h for additional help.
attr -- Displays/Sets/Removes the current attributes of a file or directory. Use -h for additional help.
cmp -- Check if two files are identical by comparing MD5 hash. Use -h for additional help.
+ waifu -- Host temporary files on https://waifuvault.moe/. Use -h for additional help.
---------------------- Networking ----------------------
ifconfig -- Display onboard Network Interface Cards configuration (Ethernet and Wireless)
diff --git a/Commands/TerminalCommands/DirFiles/Waifu.cs b/Commands/TerminalCommands/DirFiles/Waifu.cs
new file mode 100644
index 00000000..06c0722a
--- /dev/null
+++ b/Commands/TerminalCommands/DirFiles/Waifu.cs
@@ -0,0 +1,162 @@
+using Core;
+using System;
+using System.Collections.Generic;
+using System.Runtime.Versioning;
+using WaifuManager = Core.DirFiles.WaifuManage;
+
+namespace Commands.TerminalCommands.DirFiles
+{
+ [SupportedOSPlatform("windows")]
+ public class Waifu : ITerminalCommand
+ {
+ public string Name => "waifu";
+ private string _currentLocation;
+ private List _params = ["-cb", "-u", "-b", "-p", "-o", "-e", "-h", "-db", "-df", "-gf", "-lb"];
+ private static string s_helpMessage = $@"
+Host files with https://waifuvault.moe/.
+WaifuVault is a temporary file hosting service that allows for file uploads that are hosted for a set amount of time.
+
+Usage of waifu command:
+
+ -cb : Create bucket.
+ -u : Upload file (From path or URL).
+ -b : Specify bucket token. (optional)
+ -p : Specify file password. (optional)
+ -o : One time download. (optional)
+ -e : Expire download link. A string containing a number and a unit (1d = 1day). Valid units are m, h and d. (optional)
+ -h : Hide file name.(optional)
+ -db : Delete bucket. Example : waifu -db
+ -lb : List all files from bucket with detailed information: waifu -lb
+ -df : Delete file. Example : waifu -df
+ -gf : Get uploaded file information. waifu -gf
+ -lr : List wifuvault restrictions types.
+
+Example: waifu -u -p -b -o -e 1h -h
+
+ATTENTION what you upload. xTerminal developers takes no responsibility for what you upload.
+
+All restriction and privacy policy information can be found here https://waifuvault.moe/
+";
+ public void Execute(string arg)
+ {
+ try
+ {
+ // Check if site is up.
+ if (!NetWork.PingHost("waifuvault.moe"))
+ {
+ FileSystem.SuccessWriteLine("https://waifuvault.moe/ seems down or no internet connection!");
+ return;
+ }
+
+ if (arg == Name && !GlobalVariables.isPipeCommand)
+ {
+ FileSystem.SuccessWriteLine("Use -h for more information!");
+ return;
+ }
+
+ arg = arg.Substring(5);
+
+ // Display help message.
+ if (arg.Trim() == "-h" && !GlobalVariables.isPipeCommand)
+ {
+ Console.WriteLine(s_helpMessage);
+ return;
+ }
+
+ var waifu = new WaifuManager();
+
+ // Create bucket
+ if (arg.Trim().StartsWith("-cb"))
+ {
+ waifu.CreateBucket();
+ return;
+ }
+
+ // Delete bucket
+ if (arg.Trim().StartsWith("-db"))
+ {
+ var token = arg.SplitByText("-db", 1);
+ waifu.DeleteBucket(token.Trim());
+ return;
+ }
+
+ // Delete file
+ if (arg.Trim().StartsWith("-df"))
+ {
+ var token = arg.SplitByText("-df", 1);
+ waifu.DeleteFile(token.Trim());
+ return;
+ }
+
+ // List files from bucket.
+ if (arg.Trim().StartsWith("-lb"))
+ {
+ var token = arg.SplitByText("-lb", 1);
+ waifu.ListBucketFiles(token.Trim());
+ return;
+ }
+
+
+ // Get uploaded file info.
+ if (arg.Trim().StartsWith("-gf"))
+ {
+ var token = arg.SplitByText("-gf", 1);
+ waifu.GetFileInfo(token.Trim());
+ return;
+ }
+
+ // List waifuvault restrictions.
+ if (arg.Trim().StartsWith("-lr"))
+ {
+ waifu.ListRestrictions();
+ return;
+ }
+
+
+ // Upload file
+ if (arg.Trim().StartsWith("-u"))
+ {
+ var fileUrl = "";
+ var bucket = "";
+ var password = "";
+ var expire = "";
+ bool oneTimeDownload = false;
+ bool hideFileName = false;
+
+
+ var desData = arg.SplitByText("-u ", 1);
+ fileUrl = arg.GetParamValue("-u ");
+
+ if (arg.Contains("-o"))
+ oneTimeDownload = true;
+
+ if (arg.Contains("-h"))
+ hideFileName = true;
+
+ if (arg.Contains("-p "))
+ {
+ password = arg.GetParamValue("-p ");
+ }
+ if (arg.Contains("-e "))
+ expire = arg.GetParamValue("-e ");
+
+ if (arg.Contains("-b "))
+ bucket = arg.GetParamValue("-b ");
+
+ waifu.URLorFile = fileUrl;
+ waifu.Upload(bucket, oneTimeDownload, expire, hideFileName, password);
+ }
+ }
+ catch (Exception ex)
+ {
+ if (ex.Message.Contains("Unknown token"))
+ {
+ FileSystem.ErrorWriteLine("Bucket/File token was already removed! Use -h for more information!");
+ return;
+ }
+ FileSystem.ErrorWriteLine($"{ex.Message}. Use -h for more information!");
+ }
+
+ }
+ }
+}
diff --git a/Commands/TerminalCommands/Network/WakeOverLan.cs b/Commands/TerminalCommands/Network/WakeOverLan.cs
index 6313cc28..a1031c20 100644
--- a/Commands/TerminalCommands/Network/WakeOverLan.cs
+++ b/Commands/TerminalCommands/Network/WakeOverLan.cs
@@ -10,8 +10,8 @@ public class WakeOverLan : ITerminalCommand
{
private const int _port = 9;
private static string s_helpMessage = @"Usage of wol (Wake Over LAN) command:
- wol -ip IP_Address -mac MAC_Address : sends wake packet for ip/mac.
- wol -ip IP_Address -mac MAC_Address -port number_port : sends wake packet for ip/mac and custom WOL port.
+ wol -ip IPAddress/HostName -mac MAC_Address : sends wake packet for ip/mac.
+ wol -ip IPAddress/HostName -mac MAC_Address -port number_port : sends wake packet for ip/mac and custom WOL port.
";
public string Name => "wol";
public void Execute(string args)
diff --git a/Core/Core.csproj b/Core/Core.csproj
index f19a8a7a..00d399cc 100644
--- a/Core/Core.csproj
+++ b/Core/Core.csproj
@@ -1,8 +1,7 @@
-
+
net8.0-windows7.0
Library
- 8.0
false
true
true
@@ -48,16 +47,17 @@
-
+
-
-
+
+
+
diff --git a/Core/DirFiles/WaifuManage.cs b/Core/DirFiles/WaifuManage.cs
new file mode 100644
index 00000000..5fdccf52
--- /dev/null
+++ b/Core/DirFiles/WaifuManage.cs
@@ -0,0 +1,172 @@
+using System.Runtime.Versioning;
+using System.Threading.Tasks;
+using System.IO;
+using System.Linq;
+using Waifuvault;
+using System.Collections.Generic;
+
+namespace Core.DirFiles
+{
+ /*
+
+ Based on https://www.nuget.org/packages/Waifuvault documentaiton.
+
+ */
+ [SupportedOSPlatform("windows")]
+ public class WaifuManage
+ {
+ public string URLorFile { get; set; }
+
+ private string CurrentDirectory { get; set; }
+ private List ExpireFormatList = ["d","m","h"];
+
+ ///
+ /// Waifuvault manager
+ ///
+ public WaifuManage() { }
+
+
+ ///
+ /// Create waifu bucket.
+ ///
+ public void CreateBucket()
+ {
+ var bucket = Task.Run(()=>Api.createBucket()).Result;
+ FileSystem.SuccessWriteLine($"Your waifu bucket token: {bucket.token}");
+ }
+
+ ///
+ /// Upload from file or URL.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void Upload(string bucket = "", bool onetimeDownload = false, string expires = "", bool hidefileName = false, string password = "")
+ {
+ var fileUrl = URLorFile;
+ if (string.IsNullOrEmpty(fileUrl))
+ {
+ FileSystem.ErrorWriteLine("You need to specify the path to file or URL. Use -h for more information!");
+ return;
+ }
+
+ var isParamPresent = ExpireFormatList.Any(param => expires.EndsWith(param));
+ if (!isParamPresent) {
+ FileSystem.ErrorWriteLine("You need to use the expire data format. Use -h for more information!");
+ return;
+ }
+
+ if (!fileUrl.StartsWith("http"))
+ {
+ CurrentDirectory = File.ReadAllText(GlobalVariables.currentDirectory);
+ fileUrl = FileSystem.SanitizePath(fileUrl, CurrentDirectory);
+ if (!File.Exists(fileUrl))
+ {
+ FileSystem.ErrorWriteLine($"File does not exist: {fileUrl}. Use -h for more information!");
+ return;
+ }
+ }
+ var uploadFile = new FileUpload(fileUrl, bucket, expires,password,hidefileName,onetimeDownload);
+ var uploadResp = Task.Run(()=>Api.uploadFile(uploadFile)).Result;
+ var tokenInfo = Task.Run(() => Api.fileInfo(uploadResp.token, true)).Result;
+ FileSystem.SuccessWriteLine($"File {fileUrl} was uploaded!");
+ if(!string.IsNullOrEmpty(bucket))
+ FileSystem.SuccessWriteLine($"Bucket {bucket}");
+ FileSystem.SuccessWriteLine($"URL: {uploadResp.url}");
+ FileSystem.SuccessWriteLine($"Token: {uploadResp.token}");
+ FileSystem.SuccessWriteLine($"Expire date: {tokenInfo.retentionPeriod}");
+ }
+
+ ///
+ /// Delete file by token.
+ ///
+ ///
+ public void DeleteFile(string token)
+ {
+ if (string.IsNullOrEmpty(token))
+ {
+ FileSystem.ErrorWriteLine("You need to specify the uploaded file token. Use -h for more information!");
+ return;
+ }
+ var deleted = Task.Run(()=>Api.deleteFile(token)).Result;
+ if (deleted)
+ FileSystem.SuccessWriteLine($"File with token {token} was deleted!");
+ else
+ FileSystem.SuccessWriteLine($"File with {token} was NOT deleted!");
+ }
+
+ ///
+ /// Delete bucket token.
+ ///
+ ///
+ public void DeleteBucket(string bucketToken)
+ {
+ if (string.IsNullOrEmpty(bucketToken))
+ {
+ FileSystem.ErrorWriteLine("You need to specify the bucket token. Use -h for more information!");
+ return;
+ }
+ var resp = Task.Run(()=> Api.deleteBucket(bucketToken)).Result;
+ if(resp)
+ FileSystem.SuccessWriteLine($"Bucket {bucketToken} was deleted!");
+ else
+ FileSystem.SuccessWriteLine($"Bucket {bucketToken} was NOT deleted!");
+ }
+
+ ///
+ /// Get uploaded file info
+ ///
+ ///
+ public void GetFileInfo(string fileToken)
+ {
+ if (string.IsNullOrEmpty(fileToken))
+ {
+ FileSystem.ErrorWriteLine("You need to specify the uploaded file token. Use -h for more information!");
+ return;
+ }
+ var tokenInfo = Task.Run(()=>Api.fileInfo(fileToken, true)).Result;
+ FileSystem.SuccessWriteLine($"URL: {tokenInfo.url}");
+ FileSystem.SuccessWriteLine($"Expire date: {tokenInfo.retentionPeriod}");
+ FileSystem.SuccessWriteLine($"Bucket: {tokenInfo.bucket}");
+ FileSystem.SuccessWriteLine($"Hidden Name: {tokenInfo.options.hideFilename}");
+ FileSystem.SuccessWriteLine($"Password protected: {tokenInfo.options.fileprotected}");
+ }
+
+ ///
+ /// List file from bucket
+ ///
+ ///
+ public void ListBucketFiles(string bucketToken)
+ {
+ var bucket =Task.Run(()=>Api.getBucket(bucketToken)).Result;
+ foreach (var file in bucket.files)
+ {
+ FileSystem.SuccessWriteLine($"-----------------------------------------------");
+ FileSystem.SuccessWriteLine($"URL: {file.url}");
+ FileSystem.SuccessWriteLine($"File Token: {file.token}");
+ FileSystem.SuccessWriteLine($"Expire date: {FileSystem.EpohConverter(long.Parse(file.retentionPeriod))}");
+ FileSystem.SuccessWriteLine($"Hidden Name: {file.options.hideFilename}");
+ FileSystem.SuccessWriteLine($"Password protected: {file.options.fileprotected}");
+ }
+ }
+
+ ///
+ /// List vault restrictions.
+ ///
+ public void ListRestrictions()
+ {
+ Api.clearRestrictions();
+ var restrictions =Task.Run(()=> Api.getRestrictions()).Result;
+ foreach (var restriction in restrictions.Restrictions)
+ {
+ var restrictionType = restriction.type;
+ if (restrictionType.Contains("MAX_"))
+ FileSystem.SuccessWriteLine($"{restriction.type} : {FileSystem.GetSize(restriction.value,false)}");
+ else
+ FileSystem.SuccessWriteLine($"{restriction.type} : {restriction.value}");
+ }
+ }
+ }
+}
diff --git a/Core/FileSystem.cs b/Core/FileSystem.cs
index dc8d4639..36594a6d 100644
--- a/Core/FileSystem.cs
+++ b/Core/FileSystem.cs
@@ -529,5 +529,18 @@ public static string GetFileDirOwner(string path)
}
return outp;
}
+
+ ///
+ /// Convert time stamp to local time.
+ ///
+ ///
+ ///
+ public static string EpohConverter(long unixTimeStamp)
+ {
+ DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
+ var epoh = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + unixTimeStamp;
+ dateTime = dateTime.AddMilliseconds(epoh).ToLocalTime();
+ return dateTime.ToString("HH:mm:ss dd/MM/yyyy");
+ }
}
}
diff --git a/Core/InterceptKeys.cs b/Core/InterceptKeys.cs
index 0d506898..0aeb527b 100644
--- a/Core/InterceptKeys.cs
+++ b/Core/InterceptKeys.cs
@@ -1,10 +1,12 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
using System.Windows.Forms;
namespace Core
{
+ [SupportedOSPlatform("windows")]
public class InterceptKeys
{
// https://blogs.msdn.microsoft.com/toub/2006/05/03/low-level-keyboard-hook-in-c/
diff --git a/Core/NetWork.cs b/Core/NetWork.cs
index e6e54d4b..46810d2c 100644
--- a/Core/NetWork.cs
+++ b/Core/NetWork.cs
@@ -312,6 +312,28 @@ public static string GetMacAddress(string ipAddress)
return macAddress;
}
+ ///
+ /// Return IP address from hostname.
+ ///
+ ///
+ ///
+ public static string GetIPV4FromHostName(string host)
+ {
+ var ip = "";
+ try
+ {
+ IPHostEntry hostEntry = Dns.GetHostEntry(host);
+ var firstIp = hostEntry.AddressList[0];
+ if(!firstIp.ToString().Contains(":"))
+ ip = firstIp.ToString();
+ }
+ catch
+ {
+ //Ignore
+ }
+ return ip;
+ }
+
///
/// Inititialize the Get IP and MAC from IP
diff --git a/Core/OpenAI/OpenAIManage.cs b/Core/OpenAI/OpenAIManage.cs
index 205e0c4c..11b7d0a5 100644
--- a/Core/OpenAI/OpenAIManage.cs
+++ b/Core/OpenAI/OpenAIManage.cs
@@ -2,9 +2,11 @@
using System.Net.Http;
using System.Threading.Tasks;
using System.Linq;
+using System.Runtime.Versioning;
namespace Core.OpenAI
{
+ [SupportedOSPlatform("windows")]
public class OpenAIManage
{
private string _apiKey = string.Empty;
diff --git a/Core/Properties/AssemblyInfo.cs b/Core/Properties/AssemblyInfo.cs
index 1866efa3..f7e197a7 100644
--- a/Core/Properties/AssemblyInfo.cs
+++ b/Core/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.7.1.0")]
-[assembly: AssemblyFileVersion("1.7.1.0")]
+[assembly: AssemblyVersion("1.7.2.0")]
+[assembly: AssemblyFileVersion("1.7.2.0")]
diff --git a/Core/WakeOverLAN.cs b/Core/WakeOverLAN.cs
index cfe1d29f..d3b08820 100644
--- a/Core/WakeOverLAN.cs
+++ b/Core/WakeOverLAN.cs
@@ -39,6 +39,10 @@ public void Wake()
Log.ErrorWriteLine("Parameters should not be empty!");
return;
}
+
+ var host = NetWork.GetIPV4FromHostName(IP);
+ if(!string.IsNullOrEmpty(host))
+ IP = host.Trim();
int countSymbolIP = Regex.Matches(IP, "\\.").Count;
if (countSymbolIP != 3)
diff --git a/README.md b/README.md
index 485becfb..d0605d5d 100644
--- a/README.md
+++ b/README.md
@@ -304,6 +304,20 @@ This is the full list of commands that can be used in xTerminal:
Example 2: attr -r : Remove the attribute/attributes to a file or directory. Attributes needs to be splited by ';' if more then 1 are added.
cmp -- Check if two files are identical by comparing MD5 hash.
Example: cmp ;
+ waifu -- Host temporary files on https://waifuvault.moe/.
+ -cb : Create bucket.
+ -u : Upload file (From path or URL).
+ -b : Specify bucket token. (optional)
+ -p : Specify file password. (optional)
+ -o : One time download. (optional)
+ -e : Expire download link. A string containing a number and a unit (1d = 1day). Valid units are m, h and d. (optional)
+ -h : Hide file name.(optional)
+ -db : Delete bucket. Example : waifu -db
+ -lb : List all files from bucket with detailed information: waifu -lb
+ -df : Delete file. Example : waifu -df
+ -gf : Get uploaded file information. waifu -gf
+ -lr : List wifuvault restrictions types.
+ Example: waifu -u -p -b -o -e 1h -h
---------------------- Networking ----------------------
ifconfig -- Display onboard Network Interface Cards configuration (Ethernet and Wireless)
@@ -331,8 +345,8 @@ This is the full list of commands that can be used in xTerminal:
Cport check command can be used with --noping parameter to disable ping check on hostname/ip.
Example: cport IPAddress/HostName -p 80 --noping
wol -- Sends Wake over LAN packet to a machine.
- Example 1: wol -ip IP_Address -mac MAC_Address : sends wake packet for ip/mac.
- Example 2: wol -ip IP_Address -mac MAC_Address -port number_port : sends wake packet for ip/mac and custom WOL port.
+ Example 1: wol -ip IPAddress/HostName -mac MAC_Address : sends wake packet for ip/mac.
+ Example 2: wol -ip IPAddress/HostName -mac MAC_Address -port number_port : sends wake packet for ip/mac and custom WOL port.
dspoof -- The command detects MITM(man in the middle) attacks using ARP spoof method. Use -h for additional parameters.
---------------- C# Code Runner and Add-ons -------------
diff --git a/Shell/Properties/AssemblyInfo.cs b/Shell/Properties/AssemblyInfo.cs
index 26c5471b..15eff0e4 100644
--- a/Shell/Properties/AssemblyInfo.cs
+++ b/Shell/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.8.9")]
-[assembly: AssemblyFileVersion("1.8.9")]
+[assembly: AssemblyVersion("1.9.0")]
+[assembly: AssemblyFileVersion("1.9.0")]