我使用来自this的代码来为某些程序(本例中为BS.player)上下调高音量,但是在调用get_master_volume函数时我遇到了问题。我在pyHook的“OnKeyboardEvent”中使用它,这是代码的一部分:
def get_master_volume():
config.read('%s/config.cfg'%os.path.abspath(os.path.dirname(__file__)))
proc = subprocess.Popen('%s sget Master '%config.get('main', input1), shell=True, stdout=subprocess.PIPE) #config.get gives FULL and correct path to bsplayer.exe
amixer_stdout = proc.communicate()[0].split('\n')[4]
proc.wait()
find_start = amixer_stdout.find('[') + 1
find_end = amixer_stdout.find('%]', find_start)
return float(amixer_stdout[find_start:find_end])
def set_master_volume(volume):
config.read('%s/config.cfg'%os.path.abspath(os.path.dirname(__file__)))
val = float(int(volume))
proc = subprocess.Popen('%s sset Master '%config.get('main', input1) + str(val) + '%', shell=True, stdout=subprocess.PIPE) #config.get gives FULL and correct path to bsplayer.exe
proc.wait()
def OnKeyboardEvent(event):
#nothing important
if config.has_option('main', input1):
set_master_volume(get_master_volume() - 1)
print "New volume:", get_master_volume()
这是错误:
File "c:/Users/Amar/Documents/volume+/main.py", line 53, in get_master_volume
amixer_stdout = proc.communicate()[0].split('\n')[4]
IndexError: list index out of range
任何人都可以解释为什么会发生此错误以及导致错误的原因(我应该怎么做才能修复它)?
祝你好运!
编辑:
当我打印proc.communicate()时,我得到了这个错误,这意味着什么?
proc.communicate:'C:\Program' is not recognized as an internal or external comma
nd,
operable program or batch file.
('', None)
编辑2:
我修复了我的配置中指向错误的bsplayer.exe路径的错误后的新错误:
Traceback (most recent call last):
File "c:\Python27\lib\site-packages\pyHook\HookManager.py", line 351, in Keybo
ardSwitch
return func(event)
File "c:/Users/Amar/Documents/volume+/main.py", line 101, in OnKeyboardEvent
set_master_volume(get_master_volume() - 1)
File "c:/Users/Amar/Documents/volume+/main.py", line 54, in get_master_volume
amixer_stdout = proc.communicate()[0].split('\n')[4]
File "c:\Python27\lib\subprocess.py", line 798, in communicate
stdout = _eintr_retry_call(self.stdout.read)
File "c:\Python27\lib\subprocess.py", line 478, in _eintr_retry_call
return func(*args)
ValueError: I/O operation on closed file
答案 0 :(得分:2)
uuuuh ...我只是看了你正在使用的另一个问题以及你完全没有的东西。您正尝试使用与前者无关的Windows程序amixer
将发送到Linux程序bsplayer.exe
的参数。 非常 不太可能正常工作!这就是为什么它不起作用的原因。比作另一个问题:
proc = subprocess.Popen(' / usr / bin / amixer sget Master',shell = True,stdout = subprocess.PIPE)
因此,问题的第一部分是在调用bsplayer.exe
时解决您的问题,但您实际希望它做的事情不起作用。
你应该尝试以下方法来调用子进程:
proc = subprocess.Popen([config.get('main', input1), 'sget', 'Master'], stdout=subprocess.PIPE)
因为,虽然我没有太多关于Windows的经验。 python,我认为用shell调用它可能不会按预期工作,尝试将您的路径解释为参数。虽然如果你在论证中引用它可能会有效:
proc = subprocess.Popen('"%s" sget Master '%config.get('main', input1), shell=True, stdout=subprocess.PIPE)
是什么导致我得出的结论是:
'C:\Program' is not recognized as an internal or external command,
通常意味着bsplayer.exe
的路径在第一个空格处被切断。
编辑:
您可以运行以下内容,并将输出添加到您的问题中吗?
基本上:
proc.wait()
我想知道的是,您所遇到的错误是由于communicate()
无法正常工作,还是因为您在输出中得到的行少于四行。
因此,以下版本正在解决您的呼叫问题:
def get_master_volume():
config.read('%s/config.cfg'%os.path.abspath(os.path.dirname(__file__)))
p = [config.get('main', input1), 'sget', 'Master']
print("PROG:", p)
proc = subprocess.Popen(p, stdout=subprocess.PIPE)
proc.wait()
amixer_stdout = proc.communicate()[0].split('\n')
print("OUTPUT", amixer_stdout)
amixer_stdout = amixer_stdout[4]
find_start = amixer_stdout.find('[') + 1
find_end = amixer_stdout.find('%]', find_start)
return float(amixer_stdout[find_start:find_end])
虽然没有输出任何内容。
你的命令真的有用吗?!你真的尝试过这样做:
"C:\Program Files (x86)\Webteh\BSPlayer\bsplayer.exe" sget Master
在cmd中查看它是否有效?
答案 1 :(得分:1)
让我试着回答这些(实际上)你有的三个问题。
IndexError
File "c:/Users/Amar/Documents/volume+/main.py", line 53, in get_master_volume amixer_stdout = proc.communicate()[0].split('\n')[4] IndexError: list index out of range
这意味着[0]
访问尝试访问空序列(不太可能),或者[4]
尝试访问最多包含4个条目的序列,以便{{1} }不存在。
显然,输出少于4行,因此[4]
没有proc.communicate()[0].split('\n')
条目。
程序输出与预期不符,或其他错误。
[4]
proc.communicate
nd,可操作程序或批处理文件。 ('',无)
这似乎表明您的呼叫命令行有问题。
proc.communicate:'C:\Program' is not recognized as an internal or external comma
似乎包含完整路径,位于config.get('main', input1)
。因此,您应该使用C:\Program Files
(在正确的级别)正确地围绕您的计划路径。
关闭文件的I / O
通过检查呼叫追踪可以解决第三个问题。在这里我们可以看到调用事物的方式有问题:"
调用失败,因为子进程的communicate()
已经关闭。
我不清楚为什么会这样;也许你打电话给stdout
两次?在第一次通话时,它会关闭,当您尝试第二次通话时,由于communicate()
已经被读出,它会失败。