0
import os
import subprocess
import sys
import re

## fname_ext=sys.argv[1]
fname_ext=r"C:\mine\.cs\test.cs"
exe=os.path.splitext(fname_ext)[0]+".exe" # Executable
fdir=os.path.split(fname_ext)[0]
fcontent=open(fname_ext).read()

p_using=re.compile("\s*using\s+((\w+[.]*)+)")
p_namespace=re.compile("\s*namespace\s+(\w+)")
usings=p_using.findall(fcontent)
usings=[x[0] for x in usings]
references=[]
for i in os.listdir(fdir):
    path=fdir+"\\"+i
    try:
        if os.path.isdir(path) or (not path.endswith('cs')):continue
        with open(path) as fp:
            content=fp.read()
            namespaces=p_namespace.findall(content)
            for n in namespaces:
                if n in usings and 'System' not in n:
                    references+=[path]
    except:
        pass

command="csc /nologo "+" ".join(references)+" "+fname_ext
## command=" ".join(references)
#~ ---------------------------------------------------------
# Build:
option=1
if option==0:
    # using os.system
    print ">>",command
    if os.system(command)==0:
        os.system(exe)
else:
    #~ Using subprocess module
    ## print type(references)
    command=['csc']
    ## print command,references
    command.extend(["/nologo","/out:"+exe])
    command.extend(references)
    command.append(fname_ext)
    ## print command
    if subprocess.call(command,shell=True)==0:
        ## print "running %s"%exe
        subprocess.call([exe],shell=True)
    else:
        pass
        ## print "Failed to run"
#~ ---------------------------------------------------------

我上面有这段代码,它应该从SciTE. 它搜索目录中的
每个.cs文件,并找到具有当前
文件包含的名称空间的文件。在 SciTE 中运行文件的命令是:
command.go.*.cs=python C:\mine\.py\csc.py $(FilePath)
command.go.subsystem.*.cs=0

那个程序逻辑部分没问题。
问题是,当使用如下示例 Csharp 代码按 F5 时:

using System;
using System.Collections;
using MyNamespace;
class Test{
    public static void Main(String[] args){
        MyObject inst=new MyObject();
        MyObject.self_destruct(inst);
    }
}

它运行正常。但是,当我取消注释第二个fname_ext并注释第一个
并运行 csc.py 文件时,会打开一个窗口并继续运行,打印command
使用该os.system选项会发生这种情况)。当您使用the subprocess.call选项时,会发生同样的事情
,但这次仅在shell=True. 它只运行了 15 秒,并且有 800 多个 cmd.exe 和 python.exe 进程。我不得不在杀死cmd.exe
鼠标后等待将近 5 分钟才能开始响应,并且还要等待 2 分钟才能让桌面窥视工作。
shell=False,它运行正常,就像您从文件中按 F5 键时一样。
这里发生了什么?
shell=True什么让它表现得那样?

4

2 回答 2

1

问题是你sys.argv看起来像这样:

['python', r'C:\mine\.py\csc.py', 'whatever.cs']

因此,在未fname_ext注释该行的情况下,您设置fname_extr'C:\mine\.py\csc.py'. 这意味着您的脚本最终只会运行自己——它会再次运行自己,等等,尽可能快地运行,直到您的系统阻塞。

它没有发生的原因shell=False是您实际上无法执行 Python 脚本。最终,您最终CreateProcess使用脚本调用,该脚本试图将其解释为 .exe 文件,但失败并返回错误。但是使用shell=True,您将脚本传递cmd.exe给以作为程序运行,会做与交互式提示或资源管理器相同的事情:找到正确的映射来执行 .py 文件并使用它。(并且os.system与 有效地做同样的事情shell=True,但为了更好地衡量,需要添加几个额外的层。)

于 2013-08-09T20:01:56.140 回答
0

好的,我会对此进行尝试。如果我理解这种情况,这个脚本叫做 csc.py 并且你想调用 csc c# 编译器。当您运行csc /nologo (etc...)cmd.exe 时,它​​会开始寻找具有已知扩展名的名为“csc”的东西。它在当前目录中找到 csc.py 并且由于 .py 是一个注册的扩展名,这就是被执行的内容。

解决方案是重命名您的 python 文件或显式调用“csc.exe”。

于 2013-08-09T20:40:23.260 回答