python自動安裝mysql5.7

来源:http://www.cnblogs.com/lyhabc/archive/2017/11/19/7859427.html
-Advertisement-
Play Games

python自動安裝mysql5.7 python版本:python2.6 centos版本:centos6.9 mysql版本:mysql5.7.19 安裝目錄路徑和數據目錄路徑都是固定,當然也可以自己修改 這個腳本的原理是,通過createmycnf.sh的shell腳本生成my.cnf,buf ...


python自動安裝mysql5.7

 

python版本:python2.6

centos版本:centos6.9

mysql版本:mysql5.7.19

 

安裝目錄路徑和數據目錄路徑都是固定,當然也可以自己修改

這個腳本的原理是,通過createmycnf.sh的shell腳本生成my.cnf,buffer pool大小等在shell腳本里已經計算好,然後installmysql.py修改生成好的my.cnf里的埠等變數

並根據my.cnf來初始化mysql,初始化完畢之後啟動mysql服務,並設置mysql的root用戶密碼,整個執行過程的日誌會保存在當前目錄下的installmysql.log

 

執行腳本前要先安裝MySQL-python

yum install -y MySQL-python

 

 

installmysql.py

installmysql.py腳本參數

-P:myslq埠
-f:mysql二進位安裝包位置
-b:createmycnf.sh文件的位置
-p:mysql的root用戶密碼

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author : huazai
# @Time : 2017/5/4 22:04
# @File : installmysql.py
# @Description : mysql數據目錄路徑:/data/mysql/  ,mysql安裝目錄路徑:/usr/local/mysql


import os
import sys
from optparse import OptionParser
from subprocess import Popen, PIPE
import shlex
import time
import MySQLdb
import re
import shutil
import tarfile
import stat
import logging
import  pwd


logger = None
MYSQL_DATA_DIR = '/data/mysql/'
MYSQL_INSTALL_DIR = '/usr/local/mysql/'
MYSQL_CONF_DIR = '/etc/'
MYSQL_BACK_DIR = '/data/backup/mysql/'
MYSQL_STARTUP_SCRIPT = '/etc/init.d/mysql'


def init_log():
    global logger
    fmt_date = '%Y-%m-%d %H:%M:%S.%s'
    fmt_file = '%(lineno)s %(asctime)s  [%(process)d]: %(levelname)s  %(filename)s  %(message)s'

    log_file = 'installmysql.log'
    logger = logging.getLogger('mysqlinstallloging')
    logger.setLevel(logging.INFO)
    file_handler = logging.FileHandler(log_file, mode='a')
    file_handler.setFormatter(logging.Formatter(fmt_file, fmt_date))
    logger.addHandler(file_handler)


def opt():
    parser = OptionParser("Usage: %prog -P -f -b -p")
    parser.add_option("-P", "--port",
                      dest="port",
                      action="store",
                      default="3306",
                      help='port 3306')
    parser.add_option("-f", "--tarfile",
                      dest="tarfile",
                      action="store",
                      default="/tmp/mysql-5.6.28-linux-glibc2.5-x86_64.tar.gz",
                      help='file  /tmp/mysql-5.6.28-linux-glibc2.5-x86_64.tar.gz')
    parser.add_option("-b", "--bashfile",
                      dest="myfile",
                      action="store",
                      default="/tmp/createmycnf.sh",
                      help='file  /tmp/createmycnf.sh')
    parser.add_option("-p", "--mysqlpwd",
                      dest="mysqlpwd",
                      action="store",
                      default="123456",
                      help='password 123456')
    options, args = parser.parse_args()
    return options, args


# 設置安裝目錄和數據目錄的許可權
def setOwner(mysqlport):
    list=[]
    with open('/etc/passwd', 'r') as fd:
        for line in fd:
            matchmysql = re.search(r'mysql', line, re.I)

    if matchmysql:
        os.system('chown -R mysql:mysql %s' % MYSQL_DATA_DIR)
        os.system('chown -R mysql:mysql %s' % MYSQL_INSTALL_DIR)
    else:
        os.system('useradd  -M  -s /sbin/nologin  mysql')
        os.system('chown -R mysql:mysql %s' % MYSQL_DATA_DIR)
        os.system('chown -R mysql:mysql %s' % MYSQL_INSTALL_DIR)
    #檢查安裝目錄和數據目錄許可權
    for i in  pwd.getpwnam('mysql'):
        list.append(i)
    mysqluid = list[2]
    mysqlgid = list[3]
    stdatadirmode = os.stat(MYSQL_DATA_DIR).st_mode
    stinstalldirmode = os.stat(MYSQL_INSTALL_DIR).st_mode
    if not (os.stat(MYSQL_DATA_DIR).st_uid == mysqluid and os.stat(MYSQL_DATA_DIR).st_gid == mysqlgid):
        logger.error('chown mysql datadir or installdir not ok ')
        sys.exit(1)
    if not (os.stat(MYSQL_DATA_DIR+'mysql%s/data' %(mysqlport)).st_uid == mysqluid and os.stat(MYSQL_DATA_DIR+'mysql%s/data' %(mysqlport)).st_gid == mysqlgid):
        logger.error('chown mysql datadir or installdir not ok ')
        sys.exit(1)
    if not (os.stat(MYSQL_DATA_DIR+'mysql%s/logs' %(mysqlport)).st_uid == mysqluid and os.stat(MYSQL_DATA_DIR+'mysql%s/data' %(mysqlport)).st_gid == mysqlgid):
        logger.error('chown mysql datadir or installdir not ok ')
        sys.exit(1)
    if not (os.stat(MYSQL_DATA_DIR + 'mysql%s/tmp' % (mysqlport)).st_uid == mysqluid and os.stat(MYSQL_DATA_DIR + 'mysql%s/tmp' % (mysqlport)).st_gid == mysqlgid):
        logger.error('chown mysql datadir or installdir not ok ')
        sys.exit(1)





# 創建必要的目錄
def makeDIR(port):
    if os.path.exists('/data/mysql/mysql%s/data' % port):
        logger.error('mysql %s already install' % port)
        sys.exit(1)

    try:
        # os.makedirs('/usr/local/mysql')
        os.makedirs('/data/mysql/mysql%s/data' % port)
        os.makedirs('/data/mysql/mysql%s/tmp' % port)
        os.makedirs('/data/mysql/mysql%s/logs' % port)
    except Exception, e:
        logger.error(e)


# 解壓二進位安裝包
def extract(mysqlfile):
    if not os.path.exists(mysqlfile):
        logger.error('%s is not exists' % mysqlfile)
        sys.exit(1)
    os.chdir(os.path.dirname(mysqlfile))
    t = tarfile.open(mysqlfile, 'r:gz')
    t.extractall()  # 解壓到當前目錄
    t.close()


# 拷貝安裝包文件到程式目錄
def copyFile(mysqlfile):
    shutil.copytree(mysqlfile.split('.tar.gz')[0], MYSQL_INSTALL_DIR)
    shutil.copy2(MYSQL_INSTALL_DIR + 'support-files/mysql.server', MYSQL_STARTUP_SCRIPT)
    shutil.rmtree(mysqlfile.split('.tar.gz')[0])


# 設置環境變數
def setEnv():
    with open('/etc/profile', 'a') as fd:
        fd.write('export PATH=$PATH:/usr/local/mysql/bin' + '\n')
    os.system('source /etc/profile')


# 初始化mysql
def mysqlInstall():
    cnf = '/etc/my.cnf'
    if os.path.exists(cnf):
        cmd = MYSQL_INSTALL_DIR + "bin/mysqld --defaults-file=%s  --initialize-insecure" % cnf
        p = Popen(shlex.split(cmd), stdout=PIPE, stderr=PIPE)
        stdout, stderr = p.communicate()
        if stdout:
            logger.info('install output: %s' % (stdout))
        if stderr:
            logger.error('install error output: %s' % (stderr))

        if p.returncode == 0:
            logger.info('initialize completed')
            logger.info('install returncode: %s' % (p.returncode))
        else:
            logger.info('initialize failed , please check the mysql errror log')
            logger.info('install returncode: %s' % (p.returncode))
            sys.exit(1)
    else:
        logger.error(cnf + ' do not esixts')
        sys.exit(1)


# 設置my.cnf
def mycnfCreate(mybashfile, mysqlport):
    cnf = '/etc/my.cnf'
    cmd = "/bin/bash  %s" % mybashfile
    p = Popen(shlex.split(cmd), stdout=PIPE, stderr=PIPE)
    p.communicate()
    p.returncode
    f1 = open(cnf, "r", )
    f2 = open("%s.bak" % cnf, "w", )
    for line in f1:
        f2.write(re.sub(r'3306', mysqlport, line, count=1))
    f1.close()
    f2.close()
    os.remove(cnf)
    os.rename("%s.bak" % cnf, cnf)


# 設置啟動腳本
def modifyStartupscript(port):
    isdatadirfind = 0
    isbasedirfind = 0
    f1 = open(MYSQL_STARTUP_SCRIPT, "r", )
    f2 = open("%s.bak" % MYSQL_STARTUP_SCRIPT, "w", )
    for line in f1:
        if line.startswith('datadir=') and not isdatadirfind:
            f2.write(line.replace('datadir=', 'datadir=/data/mysql/mysql%s/data' % port, 1))
            isdatadirfind = 1
        elif line.startswith('basedir=') and not isbasedirfind:
            f2.write(line.replace('basedir=', 'basedir=/usr/local/mysql', 1))
            isbasedirfind = 1
        else:
            f2.write(line)
    f1.close()
    f2.close()
    os.remove(MYSQL_STARTUP_SCRIPT)
    os.rename("%s.bak" % MYSQL_STARTUP_SCRIPT, MYSQL_STARTUP_SCRIPT)
    # 設置啟動腳本執行許可權
    stmode = os.stat(MYSQL_STARTUP_SCRIPT).st_mode
    os.chmod(MYSQL_STARTUP_SCRIPT, stmode | stat.S_IXOTH | stat.S_IXGRP | stat.S_IXUSR)


# 檢查安裝
def checkInstall(port):
    if not os.path.exists('/data/mysql/mysql%s/data/ibdata1' % port):
        logger.error('mysql not install ')
        sys.exit(1)
    with open('/data/mysql/mysql%s/logs/error.log' % port, 'r') as fd:
        fdlist = [i for i in fd if i]
        fdstr = ''.join(fdlist)
        re_error = re.compile(r'\s\[error\]\s', re.I | re.M)  # 匹配errorlog日誌格式
        errorlist = re_error.findall(fdstr)

    if errorlist:
        logger.error('error.log error count:' + str(len(errorlist)))
        logger.error('mysql not install ')
        sys.exit(1)
    else:
        logger.info('install mysql  ok')


def mysqlserviceStart():
    cnf = '/etc/my.cnf'
    cmd = MYSQL_INSTALL_DIR+"bin/mysqld --defaults-file=%s &" %(cnf)
    p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
    stdout, stderr = p.communicate()
    if stdout:
        logger.info('mysql startup output: %s' % (stdout))
    if stderr:
        logger.error('mysql startup error output: %s' % (stderr))

    if p.returncode == 0:
        logger.info('mysql startup completed')
        logger.info('mysql startup returncode: %s' % (p.returncode))
    else:
        logger.info('mysql startup failed , please check the mysql errror log')
        logger.info('mysql startup returncode: %s' % (p.returncode))
        sys.exit(1)
    time.sleep(4) # 休眠4秒 讓mysql完全啟動完畢


#連接mysql
def connMysql(mysqlport):
    cnf = '/etc/my.cnf'
    if os.path.exists(cnf):
        host = 'localhost'
        user = 'root'
        dbname = 'mysql'
        usocket = MYSQL_DATA_DIR+'mysql%s/tmp/mysql.sock' % (mysqlport)
        try:
            conn = MySQLdb.connect(host=host, user=user, db=dbname, unix_socket=usocket)
        except Exception, e:
            logger.error(e)
            sys.exit(1)
        cur = conn.cursor()
        return cur

#設置mysql的root的密碼
def runSQL(mysqlport, mysqlpwd):
    sql = "alter user root@localhost identified  by '%s' " % (mysqlpwd)
    cur = connMysql(mysqlport)
    cur.execute(sql)


if __name__ == '__main__':
    init_log()

    options, args = opt()
    try:
        cmd = args[0]
    except IndexError:
        print "%s follow a command" % __file__
        print "%s -h" % __file__
        sys.exit(1)

    if (options.port and str.isdigit(options.port)) and (options.tarfile and os.path.isfile(options.tarfile)) and (
                options.myfile and os.path.isfile(options.myfile)) and (
            options.mysqlpwd):
        mysqlport = options.port
        mysqlfile = options.tarfile
        mybashfile = options.myfile
        mysqlpwd = options.mysqlpwd

    else:
        print "%s -h" % __file__
        sys.exit(1)

    if cmd == 'create':
        mycnfCreate(mybashfile, mysqlport)
        logger.info('step1:mycnfCreate completed')

        makeDIR(mysqlport)
        logger.info('step2:makeDIR completed')

        extract(mysqlfile)
        logger.info('step3:extract completed')

        copyFile(mysqlfile)
        logger.info('step4:copyFile completed')

        setOwner(mysqlport)
        logger.info('step5:setOwner completed')

        mysqlInstall()
        logger.info('step6:mysql_install completed')

        setEnv()
        logger.info('step7:setEnv completed')

        modifyStartupscript(mysqlport)
        logger.info('step8:modify_startupscript completed')

        checkInstall(mysqlport)
        logger.info('step9:checkInstall completed')

        mysqlserviceStart()
        logger.info('step10:mysqlserviceStart completed')

        runSQL(mysqlport, mysqlpwd)
        logger.info('step11:runSQL completed')

        print  'mysql install finish'

        # 調用示例
        # python /tmp/installmysql.py  -f /data/download/mysql-5.7.19-linux-glibc2.12-x86_64.tar.gz -P3306 -p123456 -b /tmp/createmycnf.sh  create

 

 

 

createmycnf.sh

#!/bin/bash
# Written by steven
# Name:        createmycnf.sh
# Version:      v1.0
# Function:     創建my.cnf
# Create Date:  2016-08-27




port=3306   #
expirelogsdays=7   #binlog清除時間
relaylogpurge=1  #mha環境不能清除
innodbbufferpoolsize=$(printf "%1.f\n" `echo "$(free -m |grep Mem|awk '{ print $2}')*0.8"|bc`)M  # bufferpool大小,物理記憶體的80%
innodbiocapacity=800    # iocapacity大小
innodbpurgethreads=2   #清除線程數量
performanceschema=1   # 是否打開P_S庫
environment=product   #是否是生產環境


ip=$(ip a|awk -F "inet|/"  '/inet.*brd/ {print $2}'|awk -F'.' '{print $4}')
serverid=$ip$port




cat > /etc/my.cnf<< EOF
[client]
port            = $port
socket            = /data/mysql/mysql$port/tmp/mysql.sock   
  

# The MySQL server
[mysqld]
#########Basic##################
explicit_defaults_for_timestamp=true

port            = $port  
user            = mysql   
basedir         = /usr/local/mysql  
datadir         = /data/mysql/mysql$port/data   
tmpdir          = /data/mysql/mysql$port/tmp   
pid-file        = /data/mysql/mysql$port/tmp/mysql.pid    
socket            = /data/mysql/mysql$port/tmp/mysql.sock   
#skip-grant-tables  

#character set
character_set_server = utf8mb4


open_files_limit = 65535
back_log = 500
#event_scheduler = ON
#lower_case_table_names=0
log_timestamps = 1
skip-external-locking
skip_name_resolve = 1
#skip-networking = 1
default-storage-engine = InnoDB

#timeout
wait_timeout=1000
lock_wait_timeout=3600
interactive_timeout=1000
connect_timeout = 20


server-id       =$serverid  #ip最後一位+埠號


#percona 的--recursion-method slavehost模式
#report_host = 10.105.9.115
#report_port = 3306



#plugin
plugin-load="semisync_master.so;semisync_slave.so"



#########SSL#############
ssl-ca = /data/mysql/mysql$port/data/ca.pem 
ssl-cert = /data/mysql/mysql$port/data/server-cert.pem 
ssl-key = /data/mysql/mysql$port/data/server-key.pem




#########undo#############
innodb_undo_logs  =126  #每個tablespace里包含的rollback seg的個數
innodb_undo_directory =/data/mysql/mysql$port/logs/
innodb_max_undo_log_size = 1G
innodb_undo_tablespaces = 8   #undo tablespace的個數
innodb_undo_log_truncate = 1
innodb_purge_rseg_truncate_frequency = 128


#########error log#############
log-error = /data/mysql/mysql$port/logs/error.log  
log_error_verbosity  = 3    

#########general log#############
#general_log=1
#general_log_file=/data/mysql/mysql$port/logs/mysql.log 

#########slow log#############
slow_query_log = 1
long_query_time=1  #0表示記錄所有SQL
slow_query_log_file = /data/mysql/mysql$port/logs/mysql.slow   


############# for replication###################
log-bin     = /data/mysql/mysql$port/logs/mysql-bin   
binlog_format = row
max_binlog_size = 500M
binlog_cache_size = 5M
max_binlog_cache_size = 5M
expire-logs-days = $expirelogsdays
slave-net-timeout=30
log-slow-slave-statements =1 


log_bin_trust_function_creators = 1
log-slave-updates = 1   
skip-slave-start = 1
#super_read_only =1    

#GTID
gtid-mode = on
binlog_gtid_simple_recovery=1
enforce_gtid_consistency=1

#relay log
relay-log = /data/mysql/mysql$port/logs/mysql-relay  
relay-log-index=/data/mysql/mysql$port/logs/relay-bin.index
max-relay-log-size = 500M
relay_log_purge = $relaylogpurge  #MHA里不能清除relaylog


#replication crash safe
sync_master_info = 1
sync_relay_log_info = 1
sync_relay_log = 1
relay_log_recovery = 1
master_info_repository = TABLE
relay_log_info_repository = TABLE

#semisync   動態開啟 主從切換的時候用
#rpl_semi_sync_master_enabled = 1
#rpl_semi_sync_master_wait_no_slave = 1
#rpl_semi_sync_master_timeout = 1000
#rpl_semi_sync_slave_enabled = 1
#rpl_semi_sync_master_timeout = 100000000 
#rpl_semi_sync_master_wait_point = 'after_sync' # after_sync 5.7增強半同步 
#rpl_semi_sync_master_wait_for_slave_count = 2  等待多少個從庫接收到binlog


#ignore
#replicate-ignore-db = 'school','school2'
#replicate-do-db = 'school','school2'
#replicate-do-table = 'db1.t1'
#replicate-ignore-table= 'db1.t1'

#Multi-threaded Slave
#slave_parallel_workers=8
#slave-parallel-type=DATABASE(預設)/LOGICAL_CLOCK
#binlog_group_commit_sync_delay=1000 
#binlog_group_commit_sync_no_delay_count =100 
#slave_preserve_commit_order=1 

#replication error
#slave-skip-errors=1007,1051,1062

#######per_thread_buffers#####################
max_connections=1100
max_user_connections=1000
max_connect_errors=1000
#myisam_recover
max_allowed_packet = 16M
#table_cache = 3096
table_open_cache = 6144
table_definition_cache = 4096
table_open_cache_instances = 64 


read_buffer_size = 1M
join_buffer_size = 4M
read_rnd_buffer_size = 1M

#myisam
sort_buffer_size = 128K
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
key_buffer_size = 64M


myisam_sort_buffer_size = 32M
tmp_table_size = 64M
max_heap_table_size = 64M
query_cache_type=0
query_cache_size = 0
bulk_insert_buffer_size = 32M

thread_cache_size = 64
#thread_concurrency = 32
thread_stack = 192K


###############InnoDB###########################
innodb_data_home_dir = /data/mysql/mysql$port/data      
innodb_log_group_home_dir = /data/mysql/mysql$port/logs    
innodb_data_file_path = ibdata1:1000M:autoextend
innodb_temp_data_file_path = ibtmp1:12M:autoextend

innodb_buffer_pool_size = $innodbbufferpoolsize  

innodb_buffer_pool_instances    = 8
#innodb_additional_mem_pool_size = 16M
innodb_log_file_size = 500M
innodb_log_buffer_size = 16M
innodb_log_files_in_group = 3
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
innodb_lock_wait_timeout = 10
innodb_sync_spin_loops = 40
innodb_max_dirty_pages_pct = 80
innodb_support_xa = 1
innodb_thread_concurrency = 0
innodb_thread_sleep_delay = 500
innodb_concurrency_tickets = 1000
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_read_io_threads = 16
innodb_write_io_threads = 16
innodb_io_capacity = $innodbiocapacity  
innodb_flush_neighbors = 1
innodb_purge_threads=$innodbpurgethreads    
innodb_purge_batch_size = 32
innodb_old_blocks_pct=75
innodb_change_buffering=all
innodb_stats_on_metadata=OFF
innodb_print_all_deadlocks = 1
performance_schema=$performanceschema   
transaction_isolation = READ-COMMITTED
#innodb_force_recovery=0
#innodb_fast_shutdown=1
#innodb_status_output=1
#innodb_status_output_locks=1
#innodb_status_file = 1  




[mysqldump]
quick
max_allowed_packet = 128M


[mysql]
no-auto-rehash  
max_allowed_packet = 128M
prompt                         = '($environment)\u@\h:\p [\d]> '    
default_character_set          = utf8


[myisamchk]
key_buffer_size = 64M
sort_buffer_size = 512k
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout

[mysqld_safe]
#malloc-lib= /usr/local/mysql/lib/mysql/libjemalloc.so
EOF

 

 

 

如有不對的地方,歡迎大家拍磚o(∩_∩)o 

本文版權歸作者所有,未經作者同意不得轉載。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在閱讀一本HTML5游戲開發相關書籍時發現一個很好的例子,通過這個例子可以對面向對象的開發進行更深入的理解。這個對象要實現的是:將一個CSS sprite中的圖像繪製到canvas中。首先創建一個SpriteSheet對象,代碼如下: var SpriteSheet = new function() ...
  • 隨著互聯網的深入發展,前端開發工程師一躍成為市場上非常搶手的人才。很多同學,包括以前做UI的、Java的、或者對於IT完全零基礎的同學都想學習前端。下圖是網上流傳甚廣的一張前端學習思維導圖,很多初學者表示看到這些密密麻麻的知識點就已經暈了。確實,前端是一門涵蓋面很廣的學科。但是想學前端的你也不用慌張 ...
  • 前面的話 javascript里的關係又多又亂。作用域鏈是一種單向的鏈式關係,還算簡單清晰;this機制的調用關係,稍微有些複雜;而關於原型,則是prototype、proto和constructor的三角關係。本文先用一張圖開宗明義,然後詳細解釋原型的三角關係 圖示 概念 上圖中的複雜關係,實際上 ...
  • 一、變數 二、sass命名時橫杠和下劃線不區分 三、變數中可以套用變數 四、嵌套規則 五·、偽類和直接調用父級符號& 六、sass的導入 七、嵌套導入 八、關於註釋 九、預設變數 十、混合器的使用mixin 十一、混合器mixin傳參數 十二:繼承 十三:占位符 註意:占位符和繼承的區別:以上占位符 ...
  • 1、使用絕對定位垂直居中 絕對對位原理:元素在過度受限情況下,將margin設置為auto,瀏覽器會重算margin的值,過度受限指的是同時設置top/bottom與height或者left/right與width。 使用絕對定位要求元素必須設置明確高度。內容超過元素高度時需要設置overflow決 ...
  • #如何在main.js直接使用Vue.use()使用自己的自定義組件呢? 需要自己去定義一個test組件,在components下新建文件夾test,test下包含index.js和test.vue index.js內容如下: test.vue內容如下: 最後在main.js下導入: 在其他組件就可 ...
  • ToolBar比ActionBar更加可控,自由。因此,Google 逐漸使用ToolBar來代替ActionBar。 轉載請標明出處http://www.cnblogs.com/tangZH/p/7850572.html 使用ToolBar 1.要引入appCompat_v7支持 2.主題設置為N ...
  • 在iOS開發中,我們會經常遇到一個問題,例如,點擊一個按鈕,彈出一個遮罩層,上面顯示一個彈框,彈框顯示的位置在按鈕附近。如果這個按鈕的位置相對於屏幕邊緣的距離是固定的,那就容易了,可以直接寫死位置。可是,如果按鈕是在UITableView的cell上呢?隨著UITableView的滾動,按鈕可能在頂 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...