Natural

 

[ZT]Cygwin上的服务

原文链接:http://guoyoooping.blog.163.com/blog/static/13570518320110953550756/

#Author: ypguo<guoyoooping@163.com>
#Date: 2011/01/9
#Version: 1.0
[目录]content(Created by TxtBrowser)
    1. cygrunsrv程序
    2. inetd服务:
    .   2.1 cvspserver服务
    .       2.1.1 在本地安装cvs
    .       2.1.2 安装cvspserver服务
    3. xinetd服务
    4. cygserver服务:
    5. sshd服务
    6. proftpd服务
    .   6.1 proftpd服务的安装
    .   6.2 proftpd建立虚拟用户
    7. apache服务
    .   7.1 关于配置
    .   7.1 启动和停止httpd服务
    8. syslogd服务

[摘要]: 本文总结了如何在cygwin上安装服务及其配置, 涉及到的服务主要有: sshd, ftp, cygserver, inetd, apache等.

首先回忆一下Linux下的服务有两种方式[1]:

    * stand_alone: 就字面上的意思来说,stand alone 就是『独立的启动』的意思,也就是说,该 daemon 启动之后,就直接常驻在内存当中啰!他虽然会一直的占用系统的资源,但最大的优点就是,他会一直启动的啦!所以当有要求来的时候,他就会很快速的响应啰! 常常用在这一种 daemon 的网络服务如常见的 httpd 这一个即是一例!

    * super daemon: 相对于 stand alone 的执行方式,这一种服务的启动方式则是藉由统一的一个 daemon 来负责唤起该服务!这一个统一负责的 daemon 就是 inet这支服务啦!不过,在后来的 Linux 发展套件中,则是使用 xinet 这个设定啰!我们这里以 Mandrake 的 xinet 来做说明。当有网络的服务要求来的时候,该要求会先送给 xinet 这个服务,然后 xinet 根据该网络要求送来的数据封包的内容 ( 该内容会记录 IP 与 port ) 来将数据封包送给实际运作的服务!而该服务这个时候才会启动的!最常见到的就是 ftp 这支网络服务啦!这种最大的优点就是当没有数据封
    包来的时候,该服务不会一直占据系统资源 ( 该服务会在 sleeping 的状态吧!),但是相对的,他的反应时间也会比较慢,因为还要花费一段时间去『唤醒』该服务呀!

把 一个程序注册为cygwin的服务, 总的来说就是调用cygrunsrv将其注册为Windows的服务, 但是根据上面的回忆, 在cygwin上启动服务也有两种方式, 一是将inetd(或xinetd)注册为系统的超级服务, 再由inetd.conf(或xinetd.conf)配置启动该服务, 另一种就是直接调用cygrunsrv将该服务注册成一个stand_alone服务.

两种方式的优缺点参考[1]已经介绍的很多了, 现在提一下实现方式上的不同: 第一种方式完全依靠inetd(或xinetd)来启动或关闭服务, 第二种方式则可以利用Windows的服务管理器里设置服务的启动状态(自己, 手动还是禁止), 也可以手动开启, 关闭服务.

所以, 首先我们讨论两个超级服务inetd和xinetd的启动, 其次再讨论可以作为stand_alone启动的服务.

1. cygrunsrv程序

#摘自cygrunsrv README:
|cygrunsrv is an implementation of an NT/W2K service starter, similar to
|Microsoft's INSTSRV and SRVANY programs, or the FireDaemon program. However,
|cygrunsrv is a cygwin program itself, so it obviously supports Cygwin
|applications better.

在讨论之前, 我们先认识一下注册, 启动, 注销服务的一般性方法, 也即cygrunsrv的用法, 详细的使用方法请参考cygrunsrv的Readme文档[2]和cygrunsrv --help, 这里仅用例子给出使用的一般方法:

#将cygwin下不带参数的应用程序/bin/foo安装成服务"foo":
|$ cygrunsrv -I foo -p /bin/foo

#将带参数的应用程序/bin/foo安装为服务"bar":
|$ cygrunsrv -I bar -p /bin/foo -a '--opt1 --opt2 -x'

#将带命令行可选项(有空格)的应用程序/bin/foo安装为服务"baz":
|$ cygrunsrv -I baz -p /bin/foo -a "-x 'this has spaces inside'"
|或者:
|$ cygrunsrv -I baz -p /bin/foo -a '-x "this has spaces inside"'

#将应用程序/bin/foo安装为手动启动的服务"foo bar"
|$ cygrunsrv -I "foo bar" -p /bin/foo -t manual

#将需要环境变量的应用程序/bin/foo安装为服务"bongo"
|$ cygrunsrv -I bongo -p /bin/foo -e "ENV_VAR_1=important_1"  -e "ENV_VAR_2=also_important"

#将sshd安装为用户"joey"下的服务
|$ cygrunsrv -I "Joey sshd" -p /usr/sbin/sshd -a '-d' -u joey

#cygrunsrv访问用户joey的密码, 比如说为"privy23":
|$ cygrunsrv -I "Joey sshd" -p /usr/sbin/sshd -a '-D' -u joey -w privy23

#启动服务"foo"
|$ cygrunsrv -S foo(或者net start foo)
|也可以在Windows服务管理器里手动启动该服务.

#停止服务"foo"
|$ cygrunsrv -E foo(或者net stop foo)
|也可以在Windows服务管理器里手动停止该服务.

#卸载服务"foo"
|$ cygrunsrv -R foo

2. inetd服务:

inetd 被叫做 “超级 Internet 服务器”, 因为它能够管理许多不同的服务程序的连接。 当 inetd 接到连入的连接时, 它就会判断连接所需要启动的服务程序,并运行它们, 然后将连接转交给这些服务程序 (在启动程序时,这些程序的标准输入、输出和错误输出描述符被替换为连入的连接)。与一个一个地运行单独的服务程序相比, 只启动一个inetd 能够削减平均的系统负荷. 换句话说, inetd提供了一种用一个服务侦听多个服务的机制. 当一个请求到达由inetd管理的服务端口, inetd将调用相应的注册程序完成相应的服务请求.

因此我们可以在cygwin上启动一个inetd服务, 然后在/etc/inetd.conf里注册自己的服务(如:ftpd、 telnet), 这样就起到了Linux标准inetd相应的功能.

1) 首先将cygserver注册为Windows的一个服务并起动该服务:

|$ cygrunsrv -I inetd -d "CYGWIN inetd" -p /usr/sbin/inetd -a -d -e CYGWIN=ntsec -t manual
|$ cygrunsrv -S inetd

2) 配置inetd.conf

#inetd.conf的例子
|#<service_name> <sock_type> <proto> <flags> <user> <server_path> <args>
|
|ftp     stream  tcp     nowait  root    /usr/sbin/ftpd ftpd
|telnet  stream  tcp     nowait  root    /usr/sbin/telnetd telnetd
|cvspserver stream tcp nowait cvsroot /usr/bin/cvs cvs -f --allow-root=/cygdrive/d/cvsroot pserver

如果该服务是新加的服务, 需要编辑修改/etc/services,加入:

#/etc/services文件:
|cvspserver 2401/tcp #cvs server tcp port
|cvspserver 2401/udp #cvs server udp port

3) 启动和停止inetd服务:

|$ net start inetd(cygrunsrv -S inetd)
|$ net stop inetd

2.1 cvspserver服务

cvspserver 只能在inetd或者xinetd下才能被做为服务启动, 本文只介绍作为inetd启动的方法, xientd启动的方法类似. 在cygwin上安装cvspserver应该和Linux上没有太大的区别, 为了方便参考, 还是将详细步骤摘录如下:

2.1.1 在本地安装cvs

1) 在windows下建立一个cvsroot的用户。这个用户需要是本地用户,不要是域用户,确定在Cygwin/home目录下有cvsroot户。如果没有切换windows登录到这个用户下,运行cygwin就可以了, 这个步骤相当于Linux上的命令:

#建立cvs用户组和cvsroot用户的Linux命令:
|#groupadd cvs
|#useradd -g cvs -s /sbin/nologin cvsroot

2)初始化cvs源代码库, 假设resository目录为/cygdrive/d/cvsroot:

#初始化cvs源代码库的命令:
|$ mkdir /cygdrive/d/cvsroot
|$ cvs -d /cygdrive/d/cvsroot init
|$ chmod -R 755 /cygdrive/d/cvsroot

3) 创建可以登陆cvs服务的用户及密码: 对 repository 初始化后,会在其目录下生成CVSROOT 子目录。然后,在 CVSROOT 目录中创建 passwd 文件,设置使用 cvs 的virtual 用户名、密码,及其所映射的操作系统用户:

#文件CVSROOT/passwd, 需要具有可读权限:
|foo:******:cvsroot
|goo::******:cvsroot

这里即将 cvs 的 virtual 用户 foo 和 goo 映射为操作系统用户 cvsroot 。而******部分对应的是由下面的 Perl 脚本加密后生成的密码:

#用于生成密码的脚本crypt.pl的内容, 需要具有可执行权限:
|#!/usr/bin/perl
|# Run me like this: crypt.pl "username"
|
|srand (time());
|my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))";
|my $salt = sprintf ("%c%c", eval $randletter, eval $randletter);
|my $plaintext = shift;
|my $crypttext = crypt ($plaintext, $salt);
|
|print "${crypttext}\n";

#如果需要密码为:123456, 则执行脚本crypt.pl:
|$ ./crypt.pl "123456"

回车即可得到加密密码,用其替换passwd文件中的xxxxxx.

4) 最 后,对生成的 repository 及其所有子目录设置相应的用户与组权限。权限的设置可以通过设置文件与目录的操作系统级权限,也可以在 CVSROOT 下建立 readers 或writers 文件,来控制 cvs virtual 用户的访问权限。这两个文件中均是 cvs 虚拟用户名的列表,每行写一个用户名,且在文件末尾留一空白行。写在 readers 文件中的用户只有 read-only 权限,写在 writers 中的用户同时拥有读写权限。若在 CVSROOT 下存
在 writers 文件,则凡是未列入该文件的用户都只有 read-only 权限。

2.1.2 安装cvspserver服务

1) 在services里加入cvspserver服务:

#编辑修改/etc/services,加入下面的两行:
|cvspserver 2401/tcp #cvs server tcp port
|cvspserver 2401/dup #cvs server udp port

2) 添加cvspserver到inetd.conf(或xinetd.d)文件中:

#编辑修改/etc/inetd.conf文件,加入下面的一行:
|cvspserver stream tcp nowait cvsroot /bin/cvs cvs -f --allow-root=/cygdrive/d/cvsroot pserver

如果使用xinetd, 则需要在xinetd.d里修改(或添加)cvspserver文件如下:

#文件cvspserver的内容:
|service cvspserver
|{
|disable = no
|flags = REUSE
|socket_type = stream
|wait = no
|user = root
|server = /usr/bin/cvs
|server_args = -f --allow-root=/home/cvsroot pserver
|log_on_failure += USERID
|}

3) 重新启动inetd或者xinetd: 参考本文第2节"2. inetd服务".

#重启后然后察看cvs服务器是否已经运行:
|# netstat -a
|TCP    cnrd-ypguo-hp7700:cvspserver  cnrd-ypguo-hp7700.jnpr.net:0  LISTENING
#或
|# netstat -a |grep cvspserver
|tcp        0      0 *:cvspserver           *:*                      LISTEN  
则说明cvs服务器已经运行。

4) 验证CVS服务是否已经配置成功(用户cvsroot, 密码111111,IP192.168.0.2)

#验证CVS服务, 如果不出现其它信息表示已经配置成功
|$ cvs -d :pserver:cvsroot@192.168.0.2/cygdrive/d/cvsroot login
|Logging in to :pserver:cvsroot@192.168.0.2:2401/cygdrive/d/cvsroot
|CVS password:
|$

5) 设置只读,写入权限设置:在CVSROOT目录建立readers,writers文件把需要设定的用户名直接写入即可。注意:

    * 首先需要在passwd文件中存在该用户名。
    * writers中的用户不能在readers中,要不然不能上传更新文件。

cvs服务器上的用户(本文中是cvsroot用户)必须是cvs组的才能用, 如果还是报repository找不到, 在客户端用户的home目录下touch文件.cvspass, 文件是空的,但是当你login一次服务器后自动就有内容

用户名必须/cvsroot/CVSROOT/passwd 下已经加入的CVS用户。这样可以在客户端创建模块,和添加文件,提交等CVS操作了。

3. xinetd服务

xinetd(eXtended InterNET services daemon)提供类似于inetd+tcp_wrapper的功能,但是更加强大和安全。

|$ cygrunsrv -R xinetd
|$ cygrunsrv -I xinetd -p /usr/sbin/xinetd -d 'CYGWIN xinetd' -1 /dev/null  -2 /dev/null -t manual
|$ cygrunsrv -S xinetd

[注意]: 根据我的经验, xinetd一旦启动, 就没有办法用命令行的办法停止或卸载. 只能在Windows的任务管理器里强行杀死该进程, 这也许是一个bug.

当你的xinetd的服务能过cygrunsrv -S xinetd或windows的服务管理器启动xinetd服务后,在windows命令行中运行netstat -a 可以看到许多类似于下面:

|TCP HJLeoChen:telnet HJLeoChen:0 LISTENING

的很多的网络监听,这说明你开启的这服务,你可以在cygwind的/etc/xinetd.d(Cygwin安装目录,如:F:\cygwin\etc\xinetd.d下)中看到很多对应的文件,这些就是服务的配置文件,你可以编辑这些文件把不需要的服务中的:

|disable= no

一行改为 disable= yes 来禁用这些服务,一方面提高系统安全性,一方面减少内存占用(?)。(我是把除了telnet外的所有服务都关闭了).

4. cygserver服务:

Cygwin 有一些特殊的功能, 如IPC Message Queues, XSI IPC Semaphores, XSI IPCShared Memory.默认是没有打开的, 大概是为了安全等问题. 要想使用这些功能, 必须先启动cygserver程序或服务. 否则会报错: "Bad system call"

1) 首先将cygserver注册为Windows的一个服务:

|$ set CYGWIN=server(或者加到$CYGWIN/Cygwin.bat, 一劳永逸)
|$ cygserver-config(按照提示配置, 注册cygserver服务)

2) 启动或停止cygserver服务:

|$ net start cygserver(cygwinserver &)
|$ net stop cygserver (也可以在Windows任务管理器里结束进程)

注意, 以下的服务都是以stand_alone方式开启的.

5. sshd服务

sshd 服务在cygwin上默认是不开启的, 可能是出于安全的需要. 但是有些服务可能需要cygwin作为一个sshd服务器. 这时你需要手动打开sshd服务.[4]

1) 先确认一下cygrunsrv.exe 已经安装.

|whereis cygrunsrv

2) 利用ssh-host-config命令将sshd注册为Windows的一个服务, 并生成配置文件:

|$ ssh-host-config

运行ssh-host-config 会提示你一些信息, 照着做就是了, 多数是yes, 在选择是否加载为service的时候小心一点, 这里的service是指windows的service, 即使cygwin不启动,sshd也会在开机的时候启动起来.

3) 启动或停止sshd

|$ net start sshd (cygrunsrv -S sshd)
|$ net stop sshd (或$ cygrunsrv -R sshd)

6. proftpd服务

6.1 proftpd服务的安装

cygwin有两个程序可以做为ftpd服务, ftpd和proftpd, 我们选择proftpd, 因为这个比较专业一点. 首先介绍一下proftpd:

#This is the README for the Cygwin ProFTPD distribution.
|ProFTPD is an enhanced FTP server with a focus toward simplicity, security,
|and ease of configuration. It features a very Apache-like configuration
|syntax, and a highly customizable server infrastructure, including support for
|multiple 'virtual' FTP servers, anonymous FTP, and permission-based directory
|visibility.

1) 首先保证ftpd不以inetd方式运行. 这很好理解, 因为inetd和standalone都可以启动ftpd服务, 但同一时刻只能有一个起作用, 所以修改inetd.conf(或xinet.conf), 禁止ftpd启动:

#对于inetd, 在/etc/inetd.conf里注释掉下面的话:
|#ftp stream tcp nowait root /usr/sbin/in.ftpd in.ftpd

#对于xinetd, 在/etc/xinetd.d/ftpd里注释掉下面的话:
|#server = /usr/sbin/in.ftpd

完成上述配置后应重启inetd(或xinetd), 保证上一步的修改生效:

|$ net stop inetd(net stop inetd);
|$ net start xinetd (net start xinetd)

2) 将ProFTPD安装为Windows的服务:

#将ProFTPD安装为Windows的服务:
|$ cygrunsrv -I proftpd -p /usr/sbin/proftpd -d 'CYGWIN proftpd' -a --nodaemon --termsig TERM --shutdown
|$ cygrunsrv -I telnetd -p /usr/sbin/telnetd -d 'CYGWIN telnetd'

#也可以用下面的命令把proftpd从Windows的服务列表里去掉:
|$ cygrunsrv -R proftpd

3) 启动或停止ProFTPD服务

#启动或停止ProFTPD服务
|$ net start proftpd
|$ net stop proftpd

关于proftpd的配置请参考[9], [10].

6.2 proftpd建立虚拟用户


在Windows下FTPD以某一个帐号运行,所有的FTP用户权限管理全部由FTPD来完成与系统帐号无关。但是在xNix下则不同,FTPD只允许那些系统帐号登陆。但是我们往往希望FTPD用户和系统帐号分离方便管理。这样就需要使用ProFTPD的虚拟用户功能。

1) 安装ftpasswd工具:

#安装ftpasswd工具:
|cd /tmp
|wget ftp://ftp.proftpd.org/distrib/source/proftpd-1.3.1rc2.tar.bz2
|tar xjvf proftpd-1.3.1rc2.tar.bz2
|cd proftpd-1.3.1rc2
|./configure –with-modules=mod_quotatab:mod_quotatab_file
|make
|cp contrib/ftpasswd /usr/local/bin/
|cp contrib/ftpquota /usr/local/bin/
|make install

2) 在/etc/proftpd.conf中加入

|RequireValidShell off
|AuthOrder mod_auth_file.c
|AuthUserFile /usr/local/etc/proftpd/passwd
|AuthGroupFile /usr/local/etc/proftpd/group(这一行貌似不是必须)

其中,AuthOrder指定了权限检查的顺序。这里只使用虚拟用户。AuthUserFile和AuthGroupFile的文件格式看passwd(5)和group(5)。如果用户名和组名与系统的重复,看DirFakeUser和DirFakeGroup。

3) 使用ftpasswd创建passwd和group文件

#创建了一个ftpuser和test2用户
|$ ftpasswd --passwd --file=/usr/local/etc/proftpd/passwd --name=ftpuser
|           --uid=2001 --home=/home/nohome --shell=/bin/false
|$ ftpasswd --passwd --file=/usr/local/etc/proftpd/passwd --name=test2
|           --uid=2002 --home=/home/nohome --shell=/bin/false

#把ftpuser和test2加入ftpgroupt组, 成员有ftpuser和test2(貌似不是必须)
|$ ftpasswd --group --file=/usr/local/etc/proftpd/group --name=ftpgroup --gid=2001 --member=ftpuser --member=test2

4) 用虚拟用户更新proftpd.conf, 重启proftpd

7. apache服务

7.1 关于配置

我的cygwin版本已经有了apache 和 apache2两个版本,第一个版本配置好在/etc/apache/httpd.conf 的内容后,在/usr/sbin/下运行“apachectl start”即可运行。

而apache2的配置文档在/etc/apache2/httpd.conf

更改信息如下:

(1)找到被注释了的#Listen 12.34.56.78:80这个地方,在下面添加“Listen127.0.0.1:8080”,IP和端口号可根据实际需要更改

(2)找到被注释了的149行“#ServerName ”,“ServerName 127.0.0.1:8080”.

但在/usr/sbin/下运行“apachectl2 start”会报错,错误信息为“Bad system call”. 需要启动cygserver程序, 参考本文第4部分: cygserver服务的安装和启动.

然后重新打开XTerm,进入cygwin命令窗口,输入“/usr/sbin/apachectl2 start” 然后查看进程即可发现已经有httpd后台服务进程在运行了。

在windows操作系统的IE浏览器打开地址“http://localhost:8080”,打开网页显示“Itworks!”。

注:两个版本的文件存放地不同

apache存放在:/var/www/htdocs        (httpd.conf中由下面内容指定DocumentRoot "/var/www/htdocs")
apache2的文件存放在:/srv/www/htdocs  (由httpd.conf中下面内容指定 DocumentRoot"/srv/www/htdocs")

7.1 启动和停止httpd服务

#手动启动httpd
|$ /usr/sbin/apachectl2 start
#手动停止httpd
|$ /usr/sbin/apachectl2 stop
#注册服务
|$ cygrunsrv -I httpd -p /usr/sbin/httpd2.exe -d 'CYGWIN httpd' -t manual  --args "-D NO_DETACH -k start" --dep cygserver --shutdown
#注销服务:
|$ cygrunsrv -R httpd
#启动服务
|$ cygrunsrv -S httpd(net start httpd)
# 停止服务:
|$ cygrunsrv -E httpd(net stop httpd)

8. syslogd服务

#安装syslogd服务的过程:
|ypguo@localhost ~
|$ syslogd-config
|*** Query: Overwrite existing /etc/syslog.conf file? (yes/no) yes
|*** Info: Creating default /etc/syslog.conf file
|
|*** Warning: The following function requires administrator privileges!
|*** Query: Do you want to install syslogd as service? (yes/no) yes
|
|*** Info: The syslogd service has been installed under the LocalSystem
|*** Info: account (also known as SYSTEM). To start the service now, call
|*** Info: `net start syslogd' or `cygrunsrv -S syslogd'. Otherwise, it
|*** Info: will start automatically after the next reboot.
|
|*** Info: Check /etc/syslog.conf first, if it suits your needs.
|
|*** Info: Keep in mind that any file mentioned in /etc/syslog.conf
|*** Info: must exist and be readable and writable for the SYSTEM account.
|*** Info: Oh and, use tabs, not spaces in /etc/syslog.conf...
|
|Configuration finished. Have fun!

#启动syslogd的过程:
|ypguo@localhost ~
|$ net start syslogd
|The CYGWIN syslogd service is starting.
|The CYGWIN syslogd service was started successfully.

#停止syslogd的过程:
|ypguo@localhost ~
|$ net stop syslogd
|The CYGWIN syslogd service is stopping.
|The CYGWIN syslogd service was stopped successfully.

[参考资料]


[1] 鸟哥的 Linux 与 ADSL 私房菜--认识系统服务 daemons, 鸟哥,
http://linux-vbird.bluedata.org/linux_base/0560daemons.htm

[2] cygrunsrv.README,
http://web.mit.edu/cygwin/cygwin_v1.3.2/usr/doc/Cygwin/cygrunsrv.README

[3] 对inetd、xinetd与TCP_Wrapper的基本了解, 非偶然的博客,
http://blog.chinaunix.net/u1/44257/showart_689244.html

[4] cygwin问题, epeaktop的博客:
http://hi.baidu.com/epeak/blog/item/c35f79ee48b991feb3fb95c7.html

[5] Cygwin上的ssh服务的putty自动登录问题,http://markli.javaeye.com/blog/39661

[6]proftpd with cygwin on windows 2003 server, cifan的博客,
http://blog.chinaunix.net/u/22117/showart_318515.html

[7] proftpd新建虚拟用户, yaoge123的博客,
http://www.huomo.cn/sysapp/article-10fc.html

[8] 楼氏博客, proftpd建立虚拟用户,
http://blog.ednchina.com/loudongming/231651/message.aspx

[9] proftpd实现虚拟用户和quota(不用数据库), 嘻嘻哈哈的部落格,
http://www.haw-haw.org/node/213

[10] CVS 服务基本配置, Posted by Orlando on October 9, 2010,
http://www.orlando-tian.net/blog/2010/10/cvs-%E6%9C%8D%E5%8A%A1%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE.html

[11] cygwin+cvs+pserver, 后发之人的博客,
http://www.cublog.cn/u3/95649/showart_1917076.html

[12] cygwin下配置subversion, ivaneeo's blog,
http://www.blogjava.net/ivanwan/archive/2006/03/13/35092.html

[13] cvs服务 - cvs服务器端配置 - 客户端使用, Linux教程网,
http://linux.sheup.com/linux/linux556.htm

[14] Example Configurations, proftpd官方网站:
http://www.proftpd.org/docs/configs/anonymous.conf

[15] 教你配置安全的ProFTPD服务器, 华江,
http://publish.it168.com/2006/0830/20060830001801.shtml

[16] 如何在 Cygwin 上安裝 Syslogd, cheeren, http://www.cheeren.com/node/6

[17] cygwin下使用apache2, http://it.chinawin.net/internet/article-12c17.html

[18] apache2 as a cygwin service, maelstrom's blog,
http://blogs.thegotonerd.com/maelstrom/archives/000511.html

posted on 2012-11-26 14:01 此号已被删 阅读(758) 评论(0)  编辑  收藏 所属分类: Cygwin


只有注册用户登录后才能发表评论。


网站导航:
 

导航

统计

常用链接

留言簿(8)

随笔分类(83)

随笔档案(78)

文章档案(2)

相册

收藏夹(7)

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜