python 调用C#的dll文件并创建一个托盘图标

python 调用C#的dll文件并创建一个托盘图标

使用前需要先安装库

pip install pythonnet

.NET API 浏览器 System.Windows.Forms.NotifyIcon 类
WPF入门之WPF加载和编译xaml

import os
import sys
import clr
import sys
import threading
import pythoncom
from pathlib import Path

def add_WPF_PATH():
    sysdll = clr.FindAssembly('System')
    if sysdll is not None:
        framework_path , name = os.path.split(sysdll)
        WPF_path = framework_path+'\\WPF'
        if WPF_path not in sys.path:
            sys.path.append(str(WPF_path))
            
add_WPF_PATH()

import time
import threading
import queue
import ctypes
import pprint
ctypes.windll.shcore.SetProcessDpiAwareness(1)


pprint.pprint(sys.path)

# 非常重要,不能省略
import System

__cs_name = [
    'System',
    # System.Windows.Window 在 PresentationFramework之中
    'PresentationFramework',
    'System.Windows',
    'System.Console',
    'System.Drawing',
    'System.Windows',
    'System.IO',
    'System.Windows.Forms',
    # 'Python.Runtime'
    # 'WindowsBase',
    # 'System.Windows.Threading',
    # 'System.Windows.Window',
    # 'System.Windows.Markup',
]

def func1(_name) -> None:
    try:
        clr.FindAssembly(_name)
    except:
        print('FindAssembly异常', _name)
    try:
        clr.AddReference(_name)
    except:
        print('AddReference异常', _name)


list(map(func1, __cs_name))

# 正式开始使用dll 中的方法了,这里要重点说一下,在使用C# 中的方法之前呢也需要先实例化一下类,然后方可使用类中的所有方法:
# 也可以
# from System.Windows.Forms import Form,NotifyIcon,ContextMenu,MenuItem,Application,FormWindowState

Form = System.Windows.Forms.Form
NotifyIcon = System.Windows.Forms.NotifyIcon
ContextMenu = System.Windows.Forms.ContextMenu
MenuItem = System.Windows.Forms.MenuItem
Application = System.Windows.Forms.Application
FormWindowState = System.Windows.Forms.FormWindowState
XamlReader = System.Windows.Markup.XamlReader
XamlWriter = System.Windows.Markup.XamlWriter
# FileStream = System.IO.FileStream
FileMode = System.IO.FileMode
Assembly = System.Reflection.Assembly
Dispatcher = System.Windows.Threading.Dispatcher

ApartmentState = System.Threading.ApartmentState
ThreadState = System.Threading.ThreadState


class FileStream(System.IO.FileStream):
    '''System.IO.FileStream with Context manager support'''

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

    # Context manager support
    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.Dispose()


class MemoryStream(System.IO.MemoryStream):
    '''System.IO.MemoryStream with Context manager support'''

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

    # Context manager support
    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.Dispose()


class Form1(Form):
    '''  '''

    def __init__(self) -> None:
        ''''''
        super().__init__()
        self.tray_exit = False

        # 设置Form的方法
        self.FormClosing += System.Windows.Forms.FormClosingEventHandler(self.OnFormClosing)
        self.FormClosed += System.EventHandler(self.OnFormClosed)

        # // Set up how the form should be displayed.
        self.ClientSize = System.Drawing.Size(600, 300)
        self.Text = "Notify Icon Example"

        # 创建其他内部控件
        self.components = System.ComponentModel.Container()
        self.contextMenu1 = System.Windows.Forms.ContextMenu()
        self.menuItem1 = System.Windows.Forms.MenuItem()

        # Initialize contextMenu1
        # self.contextMenu1.MenuItems.AddRange([self.menuItem1])
        self.contextMenu1.MenuItems.Add(self.menuItem1)

        # // Initialize menuItem1
        self.menuItem1.Index = 0
        self.menuItem1.Text = "退出程序(&Q)"
        self.menuItem1.Click += System.EventHandler(self.menuItem1_Click)

        # // Create the NotifyIcon.
        self.notifyIcon1 = System.Windows.Forms.NotifyIcon(self.components)

        # // The Icon property sets the icon that will appear
        # // in the systray for self application.
        notifyIcon1 = self.notifyIcon1
        notifyIcon1.Icon = self.Icon

        # // The ContextMenu property sets the menu that will
        # // appear when the systray icon is right clicked.
        notifyIcon1.ContextMenu = self.contextMenu1

        # // The Text property sets the text that will be displayed,
        # // in a tooltip, when the mouse hovers over the systray icon.
        notifyIcon1.Text = "Form1 (NotifyIcon example)"
        notifyIcon1.Visible = True

        # // Handle the DoubleClick event to activate the form.
        notifyIcon1.DoubleClick += System.EventHandler(self.notifyIcon1_DoubleClick)
        # notifyIcon1.DoubleClick += self.notifyIcon1_DoubleClick

    def Dispose(self, disposing):
        # // Clean up any components being used.
        print('清除资源')
        if disposing:
            if (self.components != None):
                self.components.Dispose()
        super().Dispose(disposing)

    def OnFormClosing(self, sender, e):
        '''
        object : sender
        FormClosingEventArgs : e
        '''
        # 可以在窗口的FormClosing事件中加上e.Cancel=true这句话,来阻止窗口关闭,从而实现隐藏窗口的效果。这种方法可以通过点击窗口的默认关闭按钮来调用。 blog.csdn.net
        self.WindowState = FormWindowState.Minimized
        self.Hide()
        if not self.tray_exit:
            e.Cancel = True
            print('窗口已经隐藏')
        else:
            e.Cancel = False

    def OnFormClosed(self, sender, e):
        # 在用户或Application类的Close方法或Exit方法关闭窗体后,会发生FormClosed事件。可以使用此事件释放窗体的一些资源
        print('程序准备退出')
        self.Dispose(True)

    def notifyIcon1_DoubleClick(self, Sender, e):
        # // Show the form when the user double clicks on the notify icon.
        # // Set the WindowState to normal if the form is minimized.
        print('双击')
        self.Show()
        if self.WindowState == FormWindowState.Minimized:
            self.WindowState = FormWindowState.Normal
        # // Activate the form.
        self.Activate()

    def menuItem1_Click(self, Sender, e):
        # private void menuItem1_Click(object Sender, EventArgs e)
        # // Close the form, which closes the application.
        print('单击了托盘退出')
        self.tray_exit = True
        self.Close()


base_window = '''<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />'''
test_xaml = '''<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
        <Label Name="Lb1" Content="Label" HorizontalAlignment="Left" Margin="44,33,0,0" VerticalAlignment="Top"/>
        <Button Name="Btn1" Content="Button" HorizontalAlignment="Left" Margin="44,76,0,0" VerticalAlignment="Top"/>
</Grid>'''


class WPF_Window(System.Windows.Window):
    ''''''

    def __init__(self) -> None:
        super().__init__()
        self.Width = 400
        self.Height = 400

        self.Left = self.Top = 400
        self.Title = "动态创建的元素"

        rootElement: System.Windows.DependencyObject
        # with FileStream(r'D:\test.xaml', FileMode.Open) as fs:
        #     rootElement = XamlReader.Load(fs)

        buffer = System.Text.Encoding.UTF8.GetBytes(test_xaml)
        with MemoryStream(buffer) as fs:
            rootElement = XamlReader.Load(fs)

        self.Content = rootElement
        # rootElement.FindName("Btn1").Click += self.Button_Click
        rootElement.FindName("Btn1").Click += System.EventHandler(self.Button_Click)

        # self.ShowDialog()
        # self.win_xaml = XamlWriter.Save(self)

    def Button_Click(self, sender, e):
        # def  Button_Click(self,object sender, RoutedEventArgs e):
        print('单击了按钮')
        # WPF1 = WPF_Window()
        # WPF1.Show()

class w1(threading.Thread):
    '''线程类'''

    def __init__(self) -> None:
        threading.Thread.__init__(self)
        self.daemon = True

    def run(self):
        # 初始化线程的Apartment状态为STA
        pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
        Application.Run(Form1())

class w2(threading.Thread):
    '''线程类'''

    def __init__(self) -> None:
        threading.Thread.__init__(self)
        self.daemon = True

    def run(self):
        # 初始化线程的Apartment状态为STA
        pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
        self.WPF1 = WPF_Window()
        self.WPF1.ShowDialog()

        # app = System.Windows.Application()
        # app.Run(self.WPF1)
        print('窗口结束')


W1 = w1()
W2 = w2()

W1.start()
W2.start()

W1.join()
W2.join()

System.Console.Write('应用程序结束\n')
pass

Python是一种高级编程语言,由于其易学易用的特点被广泛使用,但在某些方面比如计算速度方面表现欠佳,此时可以使用C语言的高性能来提升效率。Python通过调用C语言扩展实现对C语言的支持,可以通过Python的扩展模块来调用C语言。通过使用扩展模块,可以在Python调用写好的C语言函数,这样可以使用C语言的底层算法和数据结构,从而提升Python在复杂计算场景下的执行效率。 Python中有多个扩展模块可以实现对C语言的支持,其中最为常用的是Cython和Ctypes等模块,这些模块都能够实现Python调用C语言的功能。 其中,Cython是基于Python语言的C扩展语言,它将Python源代码转换为C语言来运行,在Cython中可以直接调用C语言函数,从而提升Python程序的速度。 Ctypes是Python的一个外部函数库,它可以通过Python调用本地的共享库和动态链接库,实现与C语言之间的互操作性。Ctypes可以通过装载共享库提供的动态函数库,并指定这些函数库的执行入口地址,从而调用C语言库函数。 需要注意的是,使用Python调用C语言函数有时需要进行函数类型和参数匹配。在调用C语言函数时,需要注意参数数据类型的匹配,并且需要遵循C语言函数的命名规则和调用规则。因此,在编写Python调用C语言函数时,需要了解C语言的语法和调用方式,同时也要注意Python调用C语言函数的规范和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值