[我在PC上为朋友运行了许多模块化的Minecraft服务器,我正在尝试构建一个程序,以使其更容易启动并将命令发送给他们。
我使用bat文件启动服务器,并且能够获得subprocess
没问题,但是我不确定如何通过控制台向服务器添加发布命令的功能。
我曾考虑过使用stdin.write()
,并且在交互式控制台中效果很好。问题是,当我将其添加到代码中时,它甚至在服务器启动之前执行了stop命令,因此服务器永不停止。我已经尝试过在单独的函数中执行此操作,但这也不起作用。
到目前为止是我的代码:
类文件:
import subprocess
class Server:
def __init__(self, server_start_bat, dir):
self.server_start_bat = server_start_bat
self.dir =dir
def start_server(self):
server = subprocess.Popen(self.server_start_bat, cwd=self.dir, shell=True, stdin=subprocess.PIPE, text=True)
server.communicate()
def stop_server(self):
server = subprocess.Popen(self.server_start_bat, cwd=self.dir, shell=True, stdin=subprocess.PIPE, text=True)
server.stdin.write('stop\n')
def command(self, command):
server = subprocess.Popen(self.server_start_bat, cwd=self.dir, shell=True, stdin=subprocess.PIPE, text=True)
self.command = command
server.stdin.write(f'{self.command}\n')
简单的GUI,我通过它运行:
from tkinter import *
import Servers
server = Servers.Server('path\\to\\bat\\file\\batfile.bat', 'dir\\to\\run\\command\\in')
main = Tk()
main.title('Server Commander')
server_title = Label(main, text="server, hosted on port ")
server_title.pack()
server_start = Button(main, text='Start', command=server.start_server)
server_start.pack()
server_stop = Button(main, text='Stop', command=server.stop_server)
server_stop.pack()
main.mainloop()
我认为有两个问题:
[stop_server
和command
各自启动一个新的子过程,只能在start_server
中完成。
[start_server
使用server.communicate()
阻塞该子进程,直到子进程完成,阻止程序在服务器运行时向服务器发送任何其他命令。
相反,
start_server
应该创建子过程,然后将其存储在可由stop_server
和command
访问的变量中,server.communicate
应该在stop_server
中完成。stop_server
也是command
的特例。
import subprocess
class Server:
def __init__(self, server_start_bat, dir):
self.server_start_bat = server_start_bat
self.dir = dir
def start_server(self):
self.server = subprocess.Popen(self.server_start_bat, cwd=self.dir, shell=True, stdin=subprocess.PIPE, text=True)
def stop_server(self):
self.command('stop')
self.server.communicate()
def command(self, command):
self.server.stdin.write(f'{command}\n')