System.Runtime.InteropServices.ExternalException: Cannot execute a program. The command being executed was “C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe” /noconfig /fullpaths @”C:\WINDOWS\TEMP\bld_39642\thr_114\seps7hdv.cmdline”.

上上周收到了一个bug说我们的tools在执行的时候出现了这样的错误:

System.Runtime.InteropServices.ExternalException: Cannot execute a program. The command being executed was "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe" /noconfig /fullpaths @"C:\WINDOWS\TEMP\bld_39642\thr_114\seps7hdv.cmdline".

仔细看了一下,出错的程序师一个dotnet程序,但是程序里面从来没有调用csc的内容啊。这个程序是在一个很复杂的tools chain中被调用的。更奇怪的是,如果自己直接运行这个程序,配合正确的参数,却不会出现这个问题。只有当从tools chain中调用时,才会这样。而且只在xp和2k3上出现,vista和seven都没有问题。

拿到bug时有点儿天狗吃月无处下口的感觉,就去网上搜了一下,看到很多link,但是都没有实质内容,有一个倒是说到了可能是security的问题,但是那个只有在asp。net上才出现,我的又不是asp应用,应该没有关系。

虽然没有解决方案,但是调用csc原因倒是有人提及:如果使用Xml Serialization的话,DotNEt runtime会在运行时生成一小段code,并调用csc编译。这一小段code就是需要的XmlSerialization的代码。

有了这个原因,我就试着从根本上解决这个问题,据说有个SGen的tool可以生成对应的XmlSerialization dll,这样runtime就不会动态编译了,东西我倒是生成了,然后runtime死活就是不理我的东西,唉,也不知道是路径不对,文件名不对,还是version不对,process monitor也没有帮助,dotnet还是不熟啊,什么这方面的工具也没有。

没办法,要赶进度,只好另外寻找突破口。既然单独运行没问题,那就肯定是两种运行模式有些内容不一样,会是什么呢?我的第一反应就是环境变量!的确,通过插入一些脚本,我导出了从tool chain运行的时候的环境变量,跟单独运行果然差别很大啊。可是我怎么看,也看不出那个环境变量与这个是相关的。实在没办法,就把所有的导出的环境变量再导入当前环境,然后单独运行,果然出错,同样的错误,然后我就开始二分法,一半一半的去掉不同的变量,做了两步忽然意识到自己傻逼了,忘了环境变量数目的影响了。

网上一查,xp系列的环境变量限制是32k,vista和windows 7 的是64k。按这样说,我应该也能在vista上重现的,果然,在加了无数垃圾环境变量之后,出了同样的错误,还是vista先进,这次的错误信息明确的指出来环境变量块超过64k无法创建新进程!靠!

最后的总结,这个错误的原因嘛,就如它的提示信息所说,无法创建新进程,至于为什么无法创建嘛,原因很多了,安全是一个,环境变量是一个,你要把可执行程序删了,那也会出现同样的错误

Advertisements
This entry was posted in Win32 Programming. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s