Cygwin的好选择? - Cygwin不支持原生支持Win32应用程序

时间:2012-04-30 14:31:47

标签: windows bash cygwin

更新2014年9月9日:TL; DR版本:转到本文的底部,了解如何让Cygwin能够调用非Cygwin程序。

在花了一些时间制作一些碰巧具有相当规模的bash脚本之后,Cygwin的新版本已经破坏了它们。这些脚本调用本机Win32应用程序,这些应用程序不与Cygwin链接,Cygwin显然没有得到Cygwin的正式支持。

这让我感到惊讶,因为多年来我认为Cygwin可以在更复杂的环境中使用,该环境结合了原生的非Cygwin Win32应用程序和使用Cygwin兼容性层的POSIX程序。但显然只支持POSIX兼容层,如果原生的Win32非Cygwin应用程序工作,那么它被认为是一个快乐的巧合。

我从与Cygwin中针对.NET Framework编译的运行程序遇到的不兼容性中发现了这一点。这曾经很好,但几个月前被打破了。具体来说,通过管道传输到任何其他Win32程序的标准输入的.NET程序的标准输出通常会导致接收Win32程序获得过早的文件结束信号,因为Cygwin最近从字节管切换到消息管道几个月前 - 消息管道似乎与使用Visual C ++或.NET Framework的任何接收应用程序不兼容。这是因为.NET向标准输出发出空写,只有在使用消息管道时才会将其传递给接收应用程序。接收应用程序成功读取零字节,因此认为它是文件结束。项目负责人似乎并不认为这是一个真正的问题,因为他们显然不支持从Cygwin中运行非Cygwin程序(惊喜!)。

从邮件列表中的多封电子邮件中引用项目负责人Christopher Faylor:

  

您所看到的可能是因为Cygwin已更改为使用   消息类型管道几个修订前。这不是   更改。采用这种改变来解决Cygwin程序的问题   这些显然是我们的首要任务。

     

无论有多少人使用Visual C ++或.NET,他们都是如此   不是我们的目标受众。当事情适用于那些人时,这很好   不想使用UNIX工具,但它们不是我们的主要关注点。   修复那些想要使用非Cygwin东西的人的问题不是   我认为最重要的事情。

     

来自pipe.cc:请注意,管道的写入侧打开为PIPE_TYPE_MESSAGE。   这个似乎更接近地模仿Linux管道行为而且是   因为fhandler_pty_master写道,pty处理肯定是必需的   以块为单位的管道,当CANON模式为新行时终止   指定。

     

以上评论显示"和"这里的关系。消息类型   管道更接近模仿Linux(UNIX)管道行为和肯定   ptys需要。

     
    

我同意James的说法,运行时可能是错误的,但我也是     同意cygwin应该能够处理这些情况。

  
     

你们之间的完全协议不会有太大的影响   影响。 Cygwin源代码不会通过投票来改变。

即使这个问题最终以某种方式得到解决 - 谁知道 - 他们可能会在3个月内破坏别的东西而不关心修复回归。他们可能会考虑一个补丁,但我需要花一些时间才能找到有用的东西。我认为我的时间最好花在其他地方,因为很明显他们非常愿意破坏与原生Win32应用程序的兼容性,并且不想浪费更多时间让Win32应用程序正常工作。所以我猜Cygwin不应该被认为是混合Win32 / Cygwin环境的稳定平台 - 我的替代方案是什么?我应该从哪里开始,以避免完全重写为bash以外的东西?我不会使用基本的Cygwin安装+一些基本的perl脚本。

更新:在发布此原始问题后,他们最终在pipe_byte环境变量中执行了新的CYGWIN标记:查看文档。如果设置了此标志,它将解决上面讨论的问题。在调用非Cygwin Win32程序时,始终确保设置了pipe_byte标志。

但是,我发现了与.NET Framework 4.0和Cygwin不兼容的问题。以前版本的.NET Framework没有此问题。我在Cygwin邮件列表上首先提到了这个问题:

Pipe syncronization and incompatibility between Cygwin and .NET Framework 4.0

没有得到富有成效的回应,我进一步调查并发现Cygwin正在创建重叠的管道,这会导致问题。请注意,尝试使用具有重叠管道的非重叠Win32 API调用是未定义的,并且大多数(所有?)Win32非Cygwin程序不会将重叠I / O与其标准文件句柄一起使用。我提交了一个补丁,该补丁在pipe_nooverlap环境变量中创建了一个CYGWIN标志,可以防止这种情况发生:

Patch to optionally disable overlapped pipes

不幸的是,他们拒绝了补丁,所以你永远不会在主Cygwin DLL中看到这个:

Re: Patch to optionally disable overlapped pipes

拒绝补丁的原因:

  1. 暗示我打破了Cygwin中的信号实现;我没有发现这种情况,因为信号仍然使用重叠管道。
  2. 他们不想添加环境变量标志,即使它显然已经解决了问题。
  3. 他们不想支持甚至可以选择使用非重叠管道的代码。
  4. 有了这样的推理和态度,我担心我无法想办法改变补丁以满足他们的要求......他们似乎决定禁止使用不重叠的管道。我一直在使用补丁一段时间,并没有遇到任何问题。此外,我无法想到pipe_nooverlap旗帜会破坏的任何情况(请参阅我的邮件列表中的后续电子邮件),但我将其留作旗帜,以防万一出现问题

    因此,如果要从Cygwin调用非Cygwin Win32或.NET Framework程序,则需要执行以下操作:

    1. 将我的补丁应用于您正在使用的Cygwin版本的源代码。不要指望这个补丁会在未来的Cygwin版本中出现。
    2. pipe_byte环境变量中设置pipe_nooverlapCYGWIN标记。
    3. 这个有效...现在!!!我发布这个以防万一其他人仍然想要使用Cygwin来做某些事情。

5 个答案:

答案 0 :(得分:45)

我找到的最佳替代方案是Gow (Gnu On Windows)

它是Cygwin的轻量级替代品,重量轻了约10倍。 据我所知,使用Gow安装的130个工具是常规的Win32应用程序。

答案 1 :(得分:16)

2016答案

今年我构建了Cash,这是在Node.js上运行的Linux命令的跨平台实现。

这支持path中每个命令的全局安装,或者支持完全支持类似bash的语法,命令管道,自动完成和历史记录的交互式shell。

这另外在shell中运行win32应用程序。

答案 2 :(得分:10)

MSYS

可能会有更少的“支持”软件包,因为您必须手动安装,但不会:

  • 路径问题(cygpath是非解决方案,因为您无法随时将其推入)
  • 程序混淆的cygwin软件包将其操作系统报告为“cygwin”
  • .dll / .so / .lib / .a confusion

与Windows应用程序有更好的互操作性。

答案 3 :(得分:4)

Cygnal是我创建一个经过修改的Cygwin的项目,它是一个运行时支持库,用于运行本机Windows程序的应用程序,遵循Windows用户熟悉的外部约定。

这个想法是你可以使用完整的Cygwin环境来开发,使用它的默认工具链:生成Cygwin可执行文件的相同编译器。 然后,您可以将程序与Cygnal项目中修改后的cygwin1.dll捆绑在一起,将程序部署为Cygnal程序。

这对于具有大量POSIX依赖性且需要功能丰富,质量优良的POSIX实现的程序特别有用。

  

项目负责人似乎并不认为这是一个真正的问题,因为他们显然不支持在Cygwin中运行非Cygwin程序(惊喜!)。

相比之下,在Cygnal项目中,这类事情被认为是合理解决方案合并的问题。

答案 4 :(得分:3)

我以前主要使用cygwin作为X11服务器功能。在远程服务器上运行任何工具并将显示导出到本地cygwin是很有用的。我发现使用更轻的Xming服务器可以实现同样的目的。