YOLO813

Stable Diffusion加载扩展项失败解决办法

    上一次在Stable Diffusion界面如何配置中英双语说到加载扩展项的问题,但是很遗憾,由于部分原因加载老是失败,但是人为老是去加host文件也不是个办法,那就干脆写个脚本来自动添加吧。

    大致的逻辑如下:

    首先拿到一批Githubusercontent的IP地址,然后逐个ping检测,凡是能够ping通的那就直接加入到C:\Windows\System32\drivers\etc目录下的host文件中。

    整理出一批IP地址如下:

ip_list = ["151.101.76.133","151.101.228.133","151.101.108.133","151.101.188.133","151.101.8.133","151.101.112.133","151.101.196.133","151.101.40.133","151.101.12.133","151.101.0.133","151.101.16.133","151.101.88.133","151.101.24.133","151.101.192.133","151.101.64.133","151.101.128.133","151.101.36.133","199.232.56.133","151.101.52.133","151.101.120.133"]

    然后写一个ping函数:

import subprocess
def ping_ip(ip):
    try:
        subprocess.run(["ping", "-n", "1", ip], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        print(f"{ip} 可以ping通")
        return True
    except subprocess.CalledProcessError:
        print(f"{ip} 无法ping通")
        return False
# 批量ping
for ip in ip_list:
    ping_ip(ip)

    判断hosts文件是否存在raw.githubusercontent.com的这一行内容,如果存在则修改其对应的ip地址,否则添加,由于这个文件必须要有管理员权限才能操作,因此有两种方式,第一种是以管理员运行脚本:

for ip in ip_list:
  if ping_ip(ip):
      hosts_path = r'C:\Windows\System32\drivers\etc\hosts'
      target_line = f'{ip} raw.githubusercontent.com'
      found_target_line = False

      # 读取hosts文件内容
      with open(hosts_path, 'r') as file:
          lines = file.readlines()
      # 寻找目标行并修改
      for i, line in enumerate(lines):
          if 'raw.githubusercontent.com' in line:
              lines[i] = target_line + "\n"
              found_target_line = True
              break

      # 如果没有找到目标行,则添加新行
      if not found_target_line:
          lines.append(target_line + "\n")

      # 将修改后的内容写回hosts文件
      with open(hosts_path, 'w') as file:
          file.writelines(lines)
      print('操作完成')
      break

    因为我们只需要一个ping通的ip就可以了,所以在找到适用的IP地址后就直接break掉。

    另外一种就是在python中使用ctypes库的windll来请求管理员权限

import ctypes
import sys

def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

    这个脚本中,is_admin函数用于检查是否有管理员权限。如果没有管理员权限,则使用ctypes.windll.shell32.ShellExecuteW请求以管理员身份运行脚本。这会弹出UAC(用户账户控制)提示框需要手动确认。

    完整代码如下:

import subprocess

import ctypes
import sys

def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

def ping_ip(ip):
    try:
        subprocess.run(["ping", "-n", "1", ip], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        print(f"{ip} 可以ping通")
        return True
    except subprocess.CalledProcessError:
        print(f"{ip} 无法ping通")
        return False
# 要ping的IP地址列表
ip_list = ["151.101.76.133","151.101.228.133","151.101.108.133","151.101.188.133","151.101.8.133","151.101.112.133","151.101.196.133","151.101.40.133","151.101.12.133","151.101.0.133","151.101.16.133","151.101.88.133","151.101.24.133","151.101.192.133","151.101.64.133","151.101.128.133","151.101.36.133","199.232.56.133","151.101.52.133","151.101.120.133"]
# 批量ping
for ip in ip_list:
    if ping_ip(ip):
        if is_admin():
            hosts_path = r'C:\Windows\System32\drivers\etc\hosts'
            target_line = f'{ip} raw.githubusercontent.com'
            found_target_line = False

            # 读取hosts文件内容
            with open(hosts_path, 'r') as file:
                lines = file.readlines()
            # 寻找目标行并修改
            for i, line in enumerate(lines):
                if 'raw.githubusercontent.com' in line:
                    lines[i] = target_line + "\n"
                    found_target_line = True
                    break

            # 如果没有找到目标行,则添加新行
            if not found_target_line:
                lines.append(target_line + "\n")

            # 将修改后的内容写回hosts文件
            with open(hosts_path, 'w') as file:
                file.writelines(lines)
            print('操作完成')
        else:
            ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
        break