千家信息网

Python集成C#实现界面操作下载文件功能的示例分析

发表于:2024-10-08 作者:千家信息网编辑
千家信息网最后更新 2024年10月08日,这篇文章给大家分享的是有关Python集成C#实现界面操作下载文件功能的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、这个功能是怎么样的我很熟悉用 C# & W
千家信息网最后更新 2024年10月08日Python集成C#实现界面操作下载文件功能的示例分析

这篇文章给大家分享的是有关Python集成C#实现界面操作下载文件功能的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

一、这个功能是怎么样的

我很熟悉用 C# & WinForm 的方式开发界面,现在刚好学习了 Python 的网络编程的基础库 socket,于是我就想到写一个程序,思路如下:

  • 程序运行时会打开一个 WinForm 窗体,窗体上有:

    • 输入文件下载地址的地址栏

    • 选择文件保存位置的文件开窗按钮

    • 当前下载状态的状态区域

    • 下载按钮

  • 输入下载地址,选择一个文件保存位置

  • 点击下载按钮下载文件,状态区域显示文件下载状态,最好能显示下载进度

  • 界面放到 WinForm,下载功能放到 Python

二、WinForm 端功能实现

WinForm 分为几部分功能

  • 界面设计

  • 提供下载地址的公共属性

  • 提供文件存储地址公共属性

  • 提供用于委托下载事件的委托定义

  • 提供记录状态信息的公共方法

  • 提供更新进度信息的公共方法

1. 界面设计

首先我们使用 VS 创建一个类库项目

至于为什么没有使用 .NET 5 或者 .net core,是因为:Python 调用 C# 动态链接库

创建项目后新建窗体

本例中设计界面设计如下:

2. 方法定义

/// /// 当前地址/// public string ThisUrl{    get    {        return textUrl.Text;    }}/// /// 当前保存路径/// public string ThisSavePath{    get    {        return textSavePath.Text;    }}
/// /// 下载事件委托/// public event EventHandler DownloadEvent;/// /// 下载按钮事件/// /// /// private void buttonDownload_Click(object sender, EventArgs e){    if (string.IsNullOrEmpty(this.textUrl.Text))    {        MessageBox.Show("请先输入要下载的文件地址!");        this.textUrl.Focus();        return;    }    if (string.IsNullOrEmpty(this.textSavePath.Text))    {        MessageBox.Show("请先选择文件要保存的地址!");        this.textSavePath.Focus();        return;    }        // 调用委托事件    if(this.DownloadEvent != null)    {        this.DownloadEvent.Invoke(this, e);    }}

打开选择保存文件路径时候由于会报错

在可以调用OLE之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute标记

很无奈,因为我们的调用方并不是 C# 的 Main 函数,而我目前并不知道 Python 调用 C# 如何实现的,所以只能另外想方法,就是把选择保存文件路径的开窗单独启一个线程开发,在子线程上再标记 STA

/// 选择按钮事件/// /// /// private void buttonSelect_Click(object sender, EventArgs e){    if (string.IsNullOrEmpty(this.textUrl.Text))    {        MessageBox.Show("请先输入要下载的文件地址!");        this.textUrl.Focus();        return;    }    var index = this.textUrl.Text.LastIndexOf("/");    var fileName = this.textUrl.Text.Substring(index + 1);    Thread importThread = new Thread(() => {        var text = OpenDialog(fileName);        MessageEvent(text);    });    importThread.SetApartmentState(ApartmentState.STA); //重点    importThread.Start();}/// /// 打开对话框/// private string OpenDialog(string fileName){    var saveFileDialog = new SaveFileDialog();    saveFileDialog.Filter = "所有文件 (*.*)|*.*";    saveFileDialog.FilterIndex = 0;    if (!string.IsNullOrEmpty(fileName))    {        saveFileDialog.FileName = Path.Combine(saveFileDialog.FileName, fileName);    }    DialogResult dialogResult = saveFileDialog.ShowDialog();    if (dialogResult == DialogResult.OK)    {        return saveFileDialog.FileName;    }    return String.Empty;}

三、Python 端功能实现

Python 中分几部分功能

  • 程序调用 .NET 类库打开窗体

  • 程序中存在下载指定 URL 文件存储到指定路径的函数定义

  • 程序结束的函数定义

  • 把当前程序封装成可运行程序(如:Windows 中为封装成 exe)

import socketimport timeimport remainapp = None# 调用动态链接库的更新状态信息def LogInfo(text):    # print(text)    mainapp.LogInfo(text)    # 调用动态链接库的更新下载进度def downloadInfo(c, all):    mainapp.SetProcess(c, all)    if c == all:        # LogInfo("下载进度 {:.2f}".format(c / all * 100))        LogInfo("下载完成。")    # else:        # LogInfo("下载进度 {:.2f}%".format(c / all * 100))# 监听下载委托事件def Download(source, args):    thisurl = source.ThisUrl.lower()    thispath = source.ThisSavePath    LogInfo("下载地址是: {}".format(thisurl))    LogInfo("保存路径为: {}".format(thispath))        reobj = re.compile(r"""(?xi)\A    [a-z][a-z0-9+\-.]*://                                # Scheme    ([a-z0-9\-._~%!$&'()*+,;=]+@)?                       # User    ([a-z0-9\-._~%]+                                     # Named or IPv4 host    |\[[a-z0-9\-._~%!$&'()*+,;=:]+\])                    # IPv6+ host    """)    match = reobj.search(thisurl)    if match:        HOST = match.group(2)        PORT = 443 if thisurl.startswith('https') else 80        mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        mysock.connect((HOST, PORT))                urlend = 'GET {} HTTP/1.0\r\n\r\n'.format(thisurl).encode()        # LogInfo("传递参数: {}".format(urlend))        LogInfo("开始下载……")        mysock.sendall(urlend)        count = 0                picture = b""        hearlength = 0        filelength = 0        hearc = b""        while True:            data = mysock.recv(5120)            if (len(data) < 1): break            time.sleep(0.1)            count = count + len(data)            picture = picture + data                        # print(len(data), count)            if hearlength == 0:                hearlength = picture.find(b"\r\n\r\n")                if hearlength > 0:                    hearc = picture[:hearlength].decode()                    # print(hearc)                    sear = re.search('Content-Length: ([0-9]+)', hearc)                    if sear:                        filelength = int(sear.groups()[0])                        downloadInfo(count - 4 - hearlength, filelength)            else:                downloadInfo(count - 4 - hearlength, filelength)        mysock.close()        # Skip past the header and save the picture data        picture = picture[hearlength+4:]        fhand = open(thispath, "wb")        fhand.write(picture)        fhand.close()        # Code: http://www.py4e.com/code3/urljpeg.py        # Or select Download from this trinket's left-hand menu    else:        LogInfo('下载失败,地址格式存在问题!')# 使用 pythonnet 的方式引入动态链接库import clr# 此处保证动态链接库文件放在当前文件夹中,如果不在应该使用这种方式# clr.AddReference('D:\\Path\\DotNetWithPython')# clr.AddReference('D:\\Path\\DotNetWithPython.dll')clr.AddReference('DotNetWithPython')from DotNetWithPython import *mainapp = MainForm()mainapp.DownloadEvent += Downloadmainapp.ShowDialog()

四、运行效果

五、存在问题

功能实现了,但是存在一个无法解决的问题,就是当文件开始下载后 WinForm 的界面会卡住,疑似是没有用现线程打开主窗体的原因,但是不能解释为什么下载开始的时候没有卡顿,有哪位大白指导一下呢?不胜感激!

感谢各位的阅读!关于"Python集成C#实现界面操作下载文件功能的示例分析"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

文件 地址 功能 界面 程序 C# 事件 状态 选择 动态 按钮 窗体 线程 路径 进度 链接 委托 函数 方法 输入 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 hivemc服务器 软件开发需求分析说明书例子 软件开发营销团队组织架构 黑客小说软件开发 数据库技术及应用期中考试 网络安全编程课程设计 应聘软件开发问你最擅长领域 数据库被盗怎么找到源头 esp软件开发公司有几家 用友数据库设计详细说明 国风网络技术有限公司电话 中科院软件开发中心 网络游戏软件开发流程规范 数据库静态数据初始化脚本 侠盗猎车手联机服务器下载 河西区高科技软件开发价钱 中国数据库采购 服务器安装游戏显示没显卡 人大金仓数据库 oracle 成都计算机软件开发人员有前途吗 曙光服务器管理口装操作系统 附加数据库提示无权限 广州燕处互联网科技有限公司 服务器的机箱耳朵是什么作用 网络安全三级管理 福建网络服务器机柜云主机 从sftp服务器下载文件 山西省党委党组网络安全责任制 重装系统后数据库表 软件开发工具有哪些优势
0