Compare commits

...

11 Commits
4.4 ... 4.5

Author SHA1 Message Date
Frank Skare
cedd694e8e - 2019-07-01 02:45:22 +02:00
Frank Skare
d1c58585f5 - 2019-06-30 07:16:28 +02:00
Frank Skare
0fce626c46 - 2019-06-30 07:14:13 +02:00
Frank Skare
adb8f38c0d - 2019-06-30 02:09:30 +02:00
Frank Skare
735ee42580 - 2019-06-30 02:07:16 +02:00
Frank Skare
103ae81b8b - 2019-06-29 12:36:35 +02:00
Frank Skare
8e351193e1 - 2019-06-27 10:35:37 +02:00
Frank Skare
d57b9281a1 - 2019-06-27 07:51:19 +02:00
Frank Skare
e07627377e - 2019-06-27 07:44:23 +02:00
Frank Skare
8899f4b772 - 2019-06-27 06:59:34 +02:00
Frank Skare
e7fd268927 - 2019-06-27 02:43:17 +02:00
12 changed files with 113 additions and 63 deletions

View File

@@ -1,3 +1,19 @@
### 4.5
- opening a URL manually no longer uses a input box but uses the clipboard directly
- the manifest was missing the company attribute which caused
mpv.net not appearing in the 'Open with' menu of the Windows File Explorer,
thanks to 44vince44 for pointing this out!!!
- new Python and C# script examples were added to the wiki and the scripting and
add-on documentation was improved
- invalid command line arguments were ignored, now an error message is shown
- a description on how to start mpv.net from Google Chrome was added to the
manual, it's useful to play videos from sites like YouTube, find the
description [here](https://github.com/stax76/mpv.net/blob/master/Manual.md#chrome-extension)
- new config setting remember-height added to remember the window height,
otherwise the video's native resolution is used
- support for protocols other then http added
### 4.4 ### 4.4
- clipboard-monitoring was replaced by url-whitelist: - clipboard-monitoring was replaced by url-whitelist:

View File

@@ -7,6 +7,7 @@
* [Requirements](#requirements) * [Requirements](#requirements)
* [Installation](#installation) * [Installation](#installation)
+ [File Associations](#file-associations) + [File Associations](#file-associations)
+ [Chrome Extension](#chrome-extension)
* [Context Menu](#context-menu) * [Context Menu](#context-menu)
+ [Open > Open Files](#open--open-files) + [Open > Open Files](#open--open-files)
+ [Open > Open URL](#open--open-url) + [Open > Open URL](#open--open-url)
@@ -119,7 +120,7 @@ If you are new to mpv.net the portable download is recommended, for regular mpv.
The x64 editions require more memory and have the advantage of decoders being typically first and better optimized for x64. The x64 editions require more memory and have the advantage of decoders being typically first and better optimized for x64.
x86 should though still be well supported and work. x86 should though still be well supported and work but it's not as well tested than x64.
### File Associations ### File Associations
@@ -129,6 +130,16 @@ Windows 10 prevents apps to register as the default app, to define the default v
It's also possible to change the default application using the Open With feature of the context menu in Windows File Explorer. It's also possible to change the default application using the Open With feature of the context menu in Windows File Explorer.
### Chrome Extension
In order to play videos from sites such as YouTube the Chrome Extension [Play with mpv](https://chrome.google.com/webstore/detail/play-with-mpv/hahklcmnfgffdlchjigehabfbiigleji) can be used.
Due to Chrome Extensions not being able to start a app, another app that communicates with the extension is required, this app can be downloaded [here](http://www.mediafire.com/file/6tmwdjsfknhmsxy/play-with-mpvnet-server.7z/file). The extension works only when the app is running, to have the app always running a link can be created in the auto start folder located at:
`C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`
This will start the app on system start and have it running in the background. When the file association registration of mpv.net was executed then the app should find the location of mpv.net, alternativly the mpv.net folder can be added to the PATH environment variable.
## Context Menu ## Context Menu
The most important part of the user interface in mpv.net is the context menu, the menu can be customized as it is defined in the same file where the key bindings are defined. The most important part of the user interface in mpv.net is the context menu, the menu can be customized as it is defined in the same file where the key bindings are defined.

View File

@@ -1,4 +1,7 @@
Imports System.ComponentModel.Composition 'this addon implements the C# scripting feature of mpv.net,
'it is based on CS-Script: https://www.cs-script.net/
Imports System.ComponentModel.Composition
Imports System.IO Imports System.IO
Imports System.Windows.Forms Imports System.Windows.Forms

View File

@@ -1,4 +1,7 @@
using System; // this addon writes a rating to the filename of the current video,
// the input.conf defaults contain key bindings for this addon
using System;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -14,11 +17,11 @@ namespace RatingAddon
public RatingAddon() public RatingAddon()
{ {
mp.ClientMessage += mpv_ClientMessage; mp.ClientMessage += ClientMessage; //handles keys defined in input.conf
mp.Shutdown += mpv_Shutdown; mp.Shutdown += Shutdown;
} }
void mpv_Shutdown() void Shutdown()
{ {
foreach (var i in Dic) foreach (var i in Dic)
{ {
@@ -44,15 +47,11 @@ namespace RatingAddon
} }
} }
void mpv_ClientMessage(string[] args) //handles keys defined in input.conf
void ClientMessage(string[] args)
{ {
if (args == null || if (args[0] != "rate-file" || ! int.TryParse(args[1], out int rating))
args.Length != 2 ||
args[0] != "rate-file" ||
!int.TryParse(args[1], out int rating))
return; return;
Dic[mp.get_property_string("path")] = rating; Dic[mp.get_property_string("path")] = rating;
mp.commandv("show-text", $"Rating: {rating}"); mp.commandv("show-text", $"Rating: {rating}");
} }

View File

@@ -218,9 +218,13 @@ namespace mpvnet
public static void open_url(string[] args) public static void open_url(string[] args)
{ {
MainForm.Instance.Invoke(new Action(() => { MainForm.Instance.Invoke(new Action(() => {
string command = VB.Interaction.InputBox("Enter URL to be opened."); string clipboard = Clipboard.GetText();
if (string.IsNullOrEmpty(command)) return; if (string.IsNullOrEmpty(clipboard) || (!clipboard.Contains("://") && !File.Exists(clipboard)) || clipboard.Contains("\n"))
mp.Load(new [] { command }, false, Control.ModifierKeys.HasFlag(Keys.Control)); {
Msg.ShowError("The clipboard does not contain a valid URL or file, URLs have to contain :// and is not allowed to contain a newline character.");
return;
}
mp.Load(new [] { clipboard }, false, Control.ModifierKeys.HasFlag(Keys.Control));
})); }));
} }

View File

@@ -33,7 +33,7 @@ namespace mpvnet
List<string> files = new List<string>(); List<string> files = new List<string>();
foreach (string arg in args) foreach (string arg in args)
if (!arg.StartsWith("--") && (File.Exists(arg) || arg == "-" || arg.StartsWith("http"))) if (!arg.StartsWith("--") && (arg == "-" || arg.Contains("://") || File.Exists(arg)))
files.Add(arg); files.Add(arg);
if (files.Count > 0) if (files.Count > 0)

View File

@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("mpv.net")] [assembly: AssemblyTitle("mpv.net")]
[assembly: AssemblyDescription("A modern media player")] [assembly: AssemblyDescription("A modern media player")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("Frank Skare (stax76)")]
[assembly: AssemblyProduct("mpv.net")] [assembly: AssemblyProduct("mpv.net")]
[assembly: AssemblyCopyright("Copyright © 2017-2019 Frank Skare (stax76)")] [assembly: AssemblyCopyright("Copyright © 2017-2019 Frank Skare (stax76)")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("4.4.0.0")] [assembly: AssemblyVersion("4.5.0.0")]
[assembly: AssemblyFileVersion("4.4.0.0")] [assembly: AssemblyFileVersion("4.5.0.0")]

View File

@@ -25,7 +25,7 @@
# mpv input keys: https://github.com/stax76/mpv.net/wiki/mpv-input-keys # mpv input keys: https://github.com/stax76/mpv.net/wiki/mpv-input-keys
o script-message mpv.net open-files #menu: Open > Open Files... o script-message mpv.net open-files #menu: Open > Open Files...
u script-message mpv.net open-url #menu: Open > Open URL... u script-message mpv.net open-url #menu: Open > Open URL or file path from clipboard
_ ignore #menu: Open > - _ ignore #menu: Open > -
Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files... Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files...
Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files... Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files...

View File

@@ -254,6 +254,14 @@ default = "50%"
filter = "Screen" filter = "Screen"
help = "Set the initial window size in percent. Please note that this setting is only partly implemented in mpv.net, accepted are only integer values with percent sign added. Default: 50%" help = "Set the initial window size in percent. Please note that this setting is only partly implemented in mpv.net, accepted are only integer values with percent sign added. Default: 50%"
[[settings]]
name = "remember-height"
default = "yes"
filter = "Screen"
help = "mpv.net specific setting to remember the window height, otherwise the video's native resolution is used."
options = [{ name = "yes" },
{ name = "no" }]
[[settings]] [[settings]]
name = "keep-open-pause" name = "keep-open-pause"
default = "yes" default = "yes"

View File

@@ -1,7 +1,7 @@
[[settings]] [[settings]]
name = "dark-mode" name = "dark-mode"
default = "always" default = "always"
filter = "mpv.net" filter = "General"
help = "Enables a dark theme." help = "Enables a dark theme."
options = [{ name = "always" }, options = [{ name = "always" },
{ name = "system" , help = "Available on Windows 10 or higher" }, { name = "system" , help = "Available on Windows 10 or higher" },
@@ -9,15 +9,15 @@ options = [{ name = "always" },
[[settings]] [[settings]]
name = "url-whitelist" name = "url-whitelist"
filter = "mpv.net" filter = "General"
type = "string" type = "string"
help = "Whitelist to monitor the clipboard for URLs to play.\n\nDefault: tube vimeo ard zdf" help = "mpv.net specific whitelist setting to monitor the clipboard for URLs to play.\n\nDefault: tube vimeo ard zdf"
[[settings]] [[settings]]
name = "process-instance" name = "process-instance"
default = "single" default = "single"
filter = "mpv.net" filter = "General"
help = "Defines if more then one mpv.net process is allowed." help = "mpv.net specific setting that defines if more then one mpv.net process is allowed.\n\nTip: Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist."
options = [{ name = "multi", help = "Create a new process everytime the shell starts mpv.net" }, options = [{ name = "multi", help = "Create a new process everytime the shell starts mpv.net" },
{ name = "single", help = "Force a single process everytime the shell starts mpv.net" }, { name = "single", help = "Force a single process everytime the shell starts mpv.net" },
{ name = "queue", help = "Force a single process and add files to playlist" }] { name = "queue", help = "Force a single process and add files to playlist" }]
@@ -25,7 +25,7 @@ options = [{ name = "multi", help = "Create a new process everytime the shell s
[[settings]] [[settings]]
name = "debug-mode" name = "debug-mode"
default = "no" default = "no"
filter = "mpv.net" filter = "General"
help = "Writes debug info to a file located on the desktop." help = "mpv.net specific setting that writes debug info to a file located on the desktop."
options = [{ name = "yes" }, options = [{ name = "yes" },
{ name = "no" }] { name = "no" }]

View File

@@ -64,7 +64,7 @@ namespace mpvnet
void CM_Popup(object sender, EventArgs e) => CursorHelp.Show(); void CM_Popup(object sender, EventArgs e) => CursorHelp.Show();
void VideoSizeChanged() => BeginInvoke(new Action(() => SetFormPosAndSizeKeepHeight())); void VideoSizeChanged() => BeginInvoke(new Action(() => SetFormPosAndSize()));
void Shutdown() => BeginInvoke(new Action(() => Close())); void Shutdown() => BeginInvoke(new Action(() => Close()));
@@ -222,11 +222,12 @@ namespace mpvnet
Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */); Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
} }
void SetFormPosAndSizeKeepHeight() void SetFormPosAndSize()
{ {
if (IsFullscreen || mp.VideoSize.Width == 0) return; if (IsFullscreen || mp.VideoSize.Width == 0) return;
Screen screen = Screen.FromControl(this); Screen screen = Screen.FromControl(this);
int height = ClientSize.Height; int height = mp.VideoSize.Height;
if (mp.RememberHeight) height = ClientSize.Height;
if (height > screen.Bounds.Height * 0.9) height = Convert.ToInt32(screen.Bounds.Height * mp.Autofit); if (height > screen.Bounds.Height * 0.9) height = Convert.ToInt32(screen.Bounds.Height * mp.Autofit);
int width = Convert.ToInt32(height * mp.VideoSize.Width / (double)mp.VideoSize.Height); int width = Convert.ToInt32(height * mp.VideoSize.Width / (double)mp.VideoSize.Height);
Point middlePos = new Point(Left + Width / 2, Top + Height / 2); Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
@@ -272,7 +273,7 @@ namespace mpvnet
{ {
string path = mp.get_property_string("path"); string path = mp.get_property_string("path");
BeginInvoke(new Action(() => { BeginInvoke(new Action(() => {
if (File.Exists(path) || path.StartsWith("http")) if (File.Exists(path) || path.Contains("://"))
Text = Path.GetFileName(path) + " - mpv.net " + Application.ProductVersion; Text = Path.GetFileName(path) + " - mpv.net " + Application.ProductVersion;
else else
Text = "mpv.net " + Application.ProductVersion; Text = "mpv.net " + Application.ProductVersion;
@@ -311,7 +312,7 @@ namespace mpvnet
else else
FormBorderStyle = FormBorderStyle.None; FormBorderStyle = FormBorderStyle.None;
SetFormPosAndSizeKeepHeight(); SetFormPosAndSize();
} }
} }
@@ -533,8 +534,8 @@ namespace mpvnet
foreach (string url in App.UrlWhitelist) foreach (string url in App.UrlWhitelist)
{ {
if (clipboard.Contains("://") && !clipboard.Contains("\n") && if (clipboard.Contains("://") && ! clipboard.Contains("\n") &&
clipboard.Contains(url.ToLower()) && ! clipboard.Contains(" ") && clipboard.Contains(url.ToLower()) &&
RegHelp.GetString(App.RegPath, "LastURL") != clipboard && Visible) RegHelp.GetString(App.RegPath, "LastURL") != clipboard && Visible)
{ {
RegHelp.SetObject(App.RegPath, "LastURL", clipboard); RegHelp.SetObject(App.RegPath, "LastURL", clipboard);

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using System.Drawing.Imaging;
@@ -73,11 +72,12 @@ namespace mpvnet
public static bool Fullscreen { get; set; } public static bool Fullscreen { get; set; }
public static bool Border { get; set; } = true; public static bool Border { get; set; } = true;
public static bool RememberHeight { get; set; } = true;
public static int Screen { get; set; } = -1; public static int Screen { get; set; } = -1;
public static int Edition { get; set; } public static int Edition { get; set; }
public static float Autofit { get; set; } = 0.50f; public static float Autofit { get; set; } = 0.5f;
public static void ProcessProperty(string name, string value) public static void ProcessProperty(string name, string value)
{ {
@@ -92,6 +92,7 @@ namespace mpvnet
case "fullscreen": Fullscreen = value == "yes"; break; case "fullscreen": Fullscreen = value == "yes"; break;
case "border": Border = value == "yes"; break; case "border": Border = value == "yes"; break;
case "screen": Screen = Convert.ToInt32(value); break; case "screen": Screen = Convert.ToInt32(value); break;
case "remember-height": RememberHeight = value == "yes"; break;
} }
} }
@@ -164,7 +165,7 @@ namespace mpvnet
{ {
string dummy = ConfFolder; string dummy = ConfFolder;
LoadLibrary("mpv-1.dll"); LoadLibrary("mpv-1.dll");
Handle = mpv_create(); Handle = mpv_create();
set_property_string("osc", "yes"); set_property_string("osc", "yes");
set_property_string("config", "yes"); set_property_string("config", "yes");
set_property_string("wid", MainForm.Hwnd.ToString()); set_property_string("wid", MainForm.Hwnd.ToString());
@@ -180,23 +181,22 @@ namespace mpvnet
public static void LoadScripts() public static void LoadScripts()
{ {
string[] jsLua = { ".lua", ".js" };
string[] startupScripts = Directory.GetFiles(Application.StartupPath + "\\Scripts"); string[] startupScripts = Directory.GetFiles(Application.StartupPath + "\\Scripts");
foreach (var scriptPath in startupScripts) foreach (string scriptPath in startupScripts)
if (jsLua.Contains(Path.GetExtension(scriptPath).ToLower())) if (scriptPath.EndsWith(".lua") || scriptPath.EndsWith(".js"))
commandv("load-script", $"{scriptPath}"); commandv("load-script", $"{scriptPath}");
foreach (var scriptPath in startupScripts) foreach (string scriptPath in startupScripts)
if (Path.GetExtension(scriptPath) == ".py") if (Path.GetExtension(scriptPath) == ".py")
PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath))); PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath)));
foreach (var scriptPath in startupScripts) foreach (string scriptPath in startupScripts)
if (Path.GetExtension(scriptPath) == ".ps1") if (Path.GetExtension(scriptPath) == ".ps1")
PowerShellScript.Init(scriptPath); PowerShellScript.Init(scriptPath);
if (Directory.Exists(ConfFolder + "Scripts")) if (Directory.Exists(ConfFolder + "Scripts"))
foreach (var scriptPath in Directory.GetFiles(ConfFolder + "Scripts")) foreach (string scriptPath in Directory.GetFiles(ConfFolder + "Scripts"))
if (Path.GetExtension(scriptPath) == ".py") if (Path.GetExtension(scriptPath) == ".py")
PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath))); PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath)));
else if (Path.GetExtension(scriptPath) == ".ps1") else if (Path.GetExtension(scriptPath) == ".ps1")
@@ -213,7 +213,7 @@ namespace mpvnet
if (WindowHandle == IntPtr.Zero) if (WindowHandle == IntPtr.Zero)
WindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null); WindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
//Debug.WriteLine(evt.event_id.ToString()); //System.Diagnostics.Debug.WriteLine(evt.event_id.ToString());
try try
{ {
@@ -275,11 +275,11 @@ namespace mpvnet
var client_messageData = (mpv_event_client_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_client_message)); var client_messageData = (mpv_event_client_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_client_message));
string[] args = NativeUtf8StrArray2ManagedStrArray(client_messageData.args, client_messageData.num_args); string[] args = NativeUtf8StrArray2ManagedStrArray(client_messageData.args, client_messageData.num_args);
if (args != null && args.Length > 1 && args[0] == "mpv.net") if (args.Length > 1 && args[0] == "mpv.net")
{ {
bool found = false; bool found = false;
foreach (var i in mpvnet.Command.Commands) foreach (Command i in Command.Commands)
{ {
if (args[1] == i.Name) if (args[1] == i.Name)
{ {
@@ -287,6 +287,7 @@ namespace mpvnet
i.Action.Invoke(args.Skip(2).ToArray()); i.Action.Invoke(args.Skip(2).ToArray());
} }
} }
if (!found) if (!found)
{ {
List<string> names = mpvnet.Command.Commands.Select((item) => item.Name).ToList(); List<string> names = mpvnet.Command.Commands.Select((item) => item.Name).ToList();
@@ -294,7 +295,8 @@ namespace mpvnet
Msg.ShowError($"No command '{args[1]}' found.", $"Available commands are:\n\n{string.Join("\n", names)}\n\nHow to bind these commands can be seen in the [default input bindings and menu definition](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt)."); Msg.ShowError($"No command '{args[1]}' found.", $"Available commands are:\n\n{string.Join("\n", names)}\n\nHow to bind these commands can be seen in the [default input bindings and menu definition](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt).");
} }
} }
ClientMessage?.Invoke(args); else if (args.Length > 0)
ClientMessage?.Invoke(args);
break; break;
case mpv_event_id.MPV_EVENT_VIDEO_RECONFIG: case mpv_event_id.MPV_EVENT_VIDEO_RECONFIG:
VideoReconfig?.Invoke(); VideoReconfig?.Invoke();
@@ -524,11 +526,10 @@ namespace mpvnet
foreach (string i in args) foreach (string i in args)
{ {
if (!i.StartsWith("--") && (File.Exists(i) || i == "-" || i.StartsWith("http"))) if (!i.StartsWith("--") && (i == "-" || i.Contains("://") || File.Exists(i)))
{ {
files.Add(i); files.Add(i);
if (i.StartsWith("http")) if (i.Contains("://")) RegHelp.SetObject(App.RegPath, "LastURL", i);
RegHelp.SetObject(App.RegPath, "LastURL", i);
} }
} }
@@ -538,14 +539,21 @@ namespace mpvnet
{ {
if (i.StartsWith("--")) if (i.StartsWith("--"))
{ {
if (i.Contains("=")) try
{ {
string left = i.Substring(2, i.IndexOf("=") - 2); if (i.Contains("="))
string right = i.Substring(left.Length + 3); {
set_property_string(left, right); string left = i.Substring(2, i.IndexOf("=") - 2);
string right = i.Substring(left.Length + 3);
set_property_string(left, right, true);
}
else
set_property_string(i.Substring(2), "yes", true);
}
catch (Exception e)
{
Msg.ShowException(e);
} }
else
set_property_string(i.Substring(2), "yes");
} }
} }
} }
@@ -604,16 +612,16 @@ namespace mpvnet
return rootPointer; return rootPointer;
} }
static string[] NativeUtf8StrArray2ManagedStrArray(IntPtr pUnmanagedStringArray, int StringCount) static string[] NativeUtf8StrArray2ManagedStrArray(IntPtr unmanagedStringArray, int StringCount)
{ {
IntPtr[] pIntPtrArray = new IntPtr[StringCount]; IntPtr[] intPtrArray = new IntPtr[StringCount];
string[] ManagedStringArray = new string[StringCount]; string[] stringArray = new string[StringCount];
Marshal.Copy(pUnmanagedStringArray, pIntPtrArray, 0, StringCount); Marshal.Copy(unmanagedStringArray, intPtrArray, 0, StringCount);
for (int i = 0; i < StringCount; i++) for (int i = 0; i < StringCount; i++)
ManagedStringArray[i] = StringFromNativeUtf8(pIntPtrArray[i]); stringArray[i] = StringFromNativeUtf8(intPtrArray[i]);
return ManagedStringArray; return stringArray;
} }
static string StringFromNativeUtf8(IntPtr nativeUtf8) static string StringFromNativeUtf8(IntPtr nativeUtf8)