C# Windows通用应用程序:从C调用python方法#

C# Windows通用应用程序:从C调用python方法#,c#,python,scikit-learn,uwp,C#,Python,Scikit Learn,Uwp,我想调用一个.py文件,获取它在我的应用程序中返回的值 我的主要意图是在基于C#的通用应用程序中使用scikit learn进行机器学习,我将如何实现这一点?我相信如果您使用类似的()来运行python脚本并捕获标准输出,您应该能够实现所需的功能要运行python脚本并捕获标准输出,您应该能够在UWP中实现所需的功能,因为您的选项非常有限。通用应用程序在沙箱中运行,并且在如何与经典桌面应用程序(如Python)交互方面受到限制,这使得您无法使用本地Python安装简单地“shell执行”脚本 有

我想调用一个.py文件,获取它在我的应用程序中返回的值


我的主要意图是在基于C#的通用应用程序中使用scikit learn进行机器学习,我将如何实现这一点?

我相信如果您使用类似的()来运行python脚本并捕获标准输出,您应该能够实现所需的功能要运行python脚本并捕获标准输出,您应该能够在UWP中实现所需的功能,因为您的选项非常有限。通用应用程序在沙箱中运行,并且在如何与经典桌面应用程序(如Python)交互方面受到限制,这使得您无法使用本地Python安装简单地“shell执行”脚本

有一种方法可以在Windows8.1WinRT中使用,但应用程序需要侧加载;它不适用于从应用商店安装的应用程序。当然,它需要桌面版的Windows,也不能在Windows Phone上运行。此外,我没有看到任何关于Windows10UWP的提及,我严重怀疑它是否仍然有效

也许你最好的办法就是试试这个。我从未使用过它,我不知道它处于什么状态,我也不知道,要让scikit学习在其中工作需要付出多少努力。但是,如果你想让你的应用程序在多个平台(桌面、移动、物联网……)上工作,我不知道还有其他选择


另一方面,如果您只针对桌面,我建议您放弃使用UWP,而是创建一个经典的桌面应用程序。这将允许您通过调用本地安装的版本或将其嵌入到应用程序中,无任何限制地使用标准CPython版本。

在UWP中,您的选项非常有限。通用应用程序在沙箱中运行,并且在如何与经典桌面应用程序(如Python)交互方面受到限制,这使得您无法使用本地Python安装简单地“shell执行”脚本

有一种方法可以在Windows8.1WinRT中使用,但应用程序需要侧加载;它不适用于从应用商店安装的应用程序。当然,它需要桌面版的Windows,也不能在Windows Phone上运行。此外,我没有看到任何关于Windows10UWP的提及,我严重怀疑它是否仍然有效

也许你最好的办法就是试试这个。我从未使用过它,我不知道它处于什么状态,我也不知道,要让scikit学习在其中工作需要付出多少努力。但是,如果你想让你的应用程序在多个平台(桌面、移动、物联网……)上工作,我不知道还有其他选择


另一方面,如果您只针对桌面,我建议您放弃使用UWP,而是创建一个经典的桌面应用程序。这将允许您通过调用本地安装的版本或将其嵌入到应用程序中,无任何限制地使用标准CPython版本。

您可以使用独立的应用程序代理。正如Damir Arh所说,这种方法不能用于通过应用商店分发应用程序。 其主要思想是为代理注册一个自定义扩展名,并通过执行一个helper文件来启动它

代理:

static class Program
{
    const string ProxyExtension = ".python-proxy";
    const string ResultExtension = ".python-proxy-result";

    [STAThread]
    static void Main(params string[] args)
    {
        if (args.Length != 1)
            return;

        if ("install".Equals(args[0], StringComparison.Ordinal))
        {
            var path = Application.ExecutablePath;
            SetAssociation(ProxyExtension, "PythonProxy", path, "Python Proxy");
        }
        else
        {
            var path = args[0];
            if (!File.Exists(path))
                return;
            var serviceExt = Path.GetExtension(path);
            if (!ProxyExtension.Equals(serviceExt, StringComparison.OrdinalIgnoreCase))
                return;
            path = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path).TrimEnd());
            var ext = Path.GetExtension(path);
            if (!".py".Equals(ext, StringComparison.OrdinalIgnoreCase))
                return;

            var start = new ProcessStartInfo
            {
                FileName = "python.exe",
                Arguments = '"' + path + '"',
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true,
            };

            using (var process = Process.Start(start))
            {
                using (var reader = process.StandardOutput)
                {
                    var result = reader.ReadToEnd();
                    var output = path + ResultExtension;
                    using (var mutex = new Mutex(true, "PythonProxy Mutex"))
                    {
                        File.WriteAllText(output, result);
                    }
                }
            }
        }
    }

    public static void SetAssociation(string ext, string name, string openWithPath, string description)
    {
        using (var key = Registry.ClassesRoot.CreateSubKey(ext))
        {
            if (key == null)
                return;

            key.SetValue("", name);
        }

        using (var key = Registry.ClassesRoot.CreateSubKey(name))
        {
            if (key == null)
                return;

            key.SetValue("", description);

            using (var shellKey = key.CreateSubKey("shell"))
            {
                if (shellKey == null)
                    return;

                using (var openKey = shellKey.CreateSubKey("open"))
                {
                    if (openKey == null)
                        return;

                    using (var commandKey = openKey.CreateSubKey("command"))
                    {
                        if (commandKey == null)
                            return;

                        commandKey.SetValue("", $"\"{openWithPath}\" \"%1\"");
                    }
                }
            }
        }

        using (var key = Registry.CurrentUser.OpenSubKey($@"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{ext}"))
        {
            if (key != null)
                key.DeleteSubKey("UserChoice", false);
        }

        Native.SHChangeNotify(Native.SHCNE_ASSOCCHANGED, Native.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
    }

    class Native
    {
        public const uint SHCNE_ASSOCCHANGED = 0x08000000;
        public const uint SHCNF_IDLIST = 0x0000;

        [DllImport("shell32.dll")]
        public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
    }
}
普遍适用:

public async void Fun()
{
    var local = ApplicationData.Current.LocalFolder;

    var scriptFile = await local.CreateFileAsync("script.py", CreationCollisionOption.ReplaceExisting);
    using (var stream = await scriptFile.OpenStreamForWriteAsync())
    using (var writer = new StreamWriter(stream))
    {
        await writer.WriteLineAsync(@"print ""Hello, World!""");
    }

    var proxyFile = await local.CreateFileAsync("script.py.python-proxy", CreationCollisionOption.ReplaceExisting);
    await Launcher.LaunchFileAsync(proxyFile);

    var resultPath = "script.py.python-proxy-result";
    var counter = 0;
    IStorageItem resultFile = null;
    while (resultFile == null)
    {
        if (counter != 0)
        {
            if (counter++ > 5)
                throw new Exception();
            await Task.Delay(250);
        }
        resultFile = await local.TryGetItemAsync(resultPath);
    }

    try
    {
        using (var mutex = new Mutex(true, "PythonProxy Mutex")) { }
    }
    catch (AbandonedMutexException) { }

    using (var stream = await local.OpenStreamForReadAsync(resultPath))
    using (var reader = new StreamReader(stream))
    {
        var content = await reader.ReadToEndAsync();
        var dialog = new MessageDialog(content);
        await dialog.ShowAsync();
    }

    await scriptFile.DeleteAsync();
    await proxyFile.DeleteAsync();
    await resultFile.DeleteAsync();
}

您可以使用独立的应用程序代理。正如Damir Arh所说,这种方法不能用于通过应用商店分发应用程序。 其主要思想是为代理注册一个自定义扩展名,并通过执行一个helper文件来启动它

代理:

static class Program
{
    const string ProxyExtension = ".python-proxy";
    const string ResultExtension = ".python-proxy-result";

    [STAThread]
    static void Main(params string[] args)
    {
        if (args.Length != 1)
            return;

        if ("install".Equals(args[0], StringComparison.Ordinal))
        {
            var path = Application.ExecutablePath;
            SetAssociation(ProxyExtension, "PythonProxy", path, "Python Proxy");
        }
        else
        {
            var path = args[0];
            if (!File.Exists(path))
                return;
            var serviceExt = Path.GetExtension(path);
            if (!ProxyExtension.Equals(serviceExt, StringComparison.OrdinalIgnoreCase))
                return;
            path = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path).TrimEnd());
            var ext = Path.GetExtension(path);
            if (!".py".Equals(ext, StringComparison.OrdinalIgnoreCase))
                return;

            var start = new ProcessStartInfo
            {
                FileName = "python.exe",
                Arguments = '"' + path + '"',
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true,
            };

            using (var process = Process.Start(start))
            {
                using (var reader = process.StandardOutput)
                {
                    var result = reader.ReadToEnd();
                    var output = path + ResultExtension;
                    using (var mutex = new Mutex(true, "PythonProxy Mutex"))
                    {
                        File.WriteAllText(output, result);
                    }
                }
            }
        }
    }

    public static void SetAssociation(string ext, string name, string openWithPath, string description)
    {
        using (var key = Registry.ClassesRoot.CreateSubKey(ext))
        {
            if (key == null)
                return;

            key.SetValue("", name);
        }

        using (var key = Registry.ClassesRoot.CreateSubKey(name))
        {
            if (key == null)
                return;

            key.SetValue("", description);

            using (var shellKey = key.CreateSubKey("shell"))
            {
                if (shellKey == null)
                    return;

                using (var openKey = shellKey.CreateSubKey("open"))
                {
                    if (openKey == null)
                        return;

                    using (var commandKey = openKey.CreateSubKey("command"))
                    {
                        if (commandKey == null)
                            return;

                        commandKey.SetValue("", $"\"{openWithPath}\" \"%1\"");
                    }
                }
            }
        }

        using (var key = Registry.CurrentUser.OpenSubKey($@"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{ext}"))
        {
            if (key != null)
                key.DeleteSubKey("UserChoice", false);
        }

        Native.SHChangeNotify(Native.SHCNE_ASSOCCHANGED, Native.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
    }

    class Native
    {
        public const uint SHCNE_ASSOCCHANGED = 0x08000000;
        public const uint SHCNF_IDLIST = 0x0000;

        [DllImport("shell32.dll")]
        public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
    }
}
普遍适用:

public async void Fun()
{
    var local = ApplicationData.Current.LocalFolder;

    var scriptFile = await local.CreateFileAsync("script.py", CreationCollisionOption.ReplaceExisting);
    using (var stream = await scriptFile.OpenStreamForWriteAsync())
    using (var writer = new StreamWriter(stream))
    {
        await writer.WriteLineAsync(@"print ""Hello, World!""");
    }

    var proxyFile = await local.CreateFileAsync("script.py.python-proxy", CreationCollisionOption.ReplaceExisting);
    await Launcher.LaunchFileAsync(proxyFile);

    var resultPath = "script.py.python-proxy-result";
    var counter = 0;
    IStorageItem resultFile = null;
    while (resultFile == null)
    {
        if (counter != 0)
        {
            if (counter++ > 5)
                throw new Exception();
            await Task.Delay(250);
        }
        resultFile = await local.TryGetItemAsync(resultPath);
    }

    try
    {
        using (var mutex = new Mutex(true, "PythonProxy Mutex")) { }
    }
    catch (AbandonedMutexException) { }

    using (var stream = await local.OpenStreamForReadAsync(resultPath))
    using (var reader = new StreamReader(stream))
    {
        var content = await reader.ReadToEndAsync();
        var dialog = new MessageDialog(content);
        await dialog.ShowAsync();
    }

    await scriptFile.DeleteAsync();
    await proxyFile.DeleteAsync();
    await resultFile.DeleteAsync();
}

到目前为止你试过什么?我们恳请您在尝试向您提供帮助之前,先尝试自己解决它。@Torxed到目前为止,我已经使用了Ironpython,但它不包括scikit learn,因此我不得不放弃该路径。到目前为止,您尝试了什么?我们恳请您在尝试向您提供帮助之前,先尝试自己解决它。@Torxed到目前为止,我已经使用了Ironpython,但它不包括scikit学习,所以我不得不放弃该路径谢谢您的回复,我考虑过切换到WPF,但它不包括Microsoft Band的SDK。我正在考虑使用Azure机器学习,因为它允许我包含Python脚本,你认为如何?我对Microsoft Band SDK一点也不熟悉,但如果它依赖于UWP API,也许你可以在的帮助下使用它。它允许您从桌面应用程序访问UWP API。我没有Azure机器学习的经验,我只参加过一次关于它的介绍会。如果它适合您的需要,这可能是有道理的,尽管听起来有点过分。感谢您的回复,我考虑过切换到WPF,但它不包括Microsoft Band的SDK。我正在考虑使用Azure机器学习,因为它允许我包括Python脚本,你觉得呢?我对微软Band SDK一点也不熟悉,但是如果它依赖于UWP API,也许你可以在微软的帮助下使用它。它允许您从桌面应用程序访问UWP API。我没有Azure机器学习的经验,我只参加过一次关于它的介绍会。如果它适合你的需要,这可能是有道理的,尽管听起来有点过分了。