XiZi's Blog
这里记录一个用CreatePipe的坑
1. 问题来源:在Windows上编译了一个cgit, 加了source-filter,代码高亮(使用highlight处理)之后,死活不显示代码。发现是execvp的问题,开始想好好弄,后来放弃了,反正只加个代码高亮,直接dirtry的解决方案算了。所以就参照微软的官方<Creating a Child Process with Redirected Input and Output>, 进行highlight进程的创建。测试小文件可以正常高亮,大文件就会卡住。
2.问题所在和解决方案:经过各种查找,定位到了WriteFile给子线程的Stdin pipe时发生了阻塞。查了查,发现CreatePipes时,有buffersize的设置,增大buffersize, 问题得到了解决。
贴出Dirty的核心代码吧:
-
#define _WIN32_WINNT 0x0600 #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winnt.h> #include <winternl.h> #include <stdio.h> #include <errno.h> #include <assert.h> #include <process.h> typedef struct ProcessPrepare_Info { PROCESS_INFORMATION child_pi; HANDLE IN_Rd; HANDLE IN_Wr; HANDLE OUT_Rd; HANDLE OUT_Wr; } PPInfo; #define BUFSIZE 4096 #define PIPE_BUFSIZE 1024*1024*1024
-
PPInfo prepare_highlight(const char* filename) { SECURITY_ATTRIBUTES saAttr; char file_ext[1024]; char *fext; PPInfo ppinfo; PROCESS_INFORMATION child_pi; HANDLE g_hChildStd_IN_Rd = NULL; HANDLE g_hChildStd_IN_Wr = NULL; HANDLE g_hChildStd_OUT_Rd = NULL; HANDLE g_hChildStd_OUT_Wr = NULL; fext = get_filename_ext(filename); if (!fext) strcpy(file_ext,"txt"); else strcpy(file_ext,fext); if (strstr(filename,"Makefile") == filename) strcpy(file_ext,"mk"); // printf("\n->Start of parent execution.\n"); // Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // Create a pipe for the child process's STDOUT. if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, PIPE_BUFSIZE)) debug_log(TEXT("StdoutRd CreatePipe")); // Ensure the read handle to the pipe for STDOUT is not inherited. if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) debug_log(TEXT("Stdout SetHandleInformation")); // Create a pipe for the child process's STDIN. if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, PIPE_BUFSIZE)) debug_log(TEXT("Stdin CreatePipe")); // Ensure the write handle to the pipe for STDIN is not inherited. if (!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) debug_log(TEXT("Stdin SetHandleInformation")); // Create the child process. child_pi = CreateChildProcess(file_ext,g_hChildStd_OUT_Wr,g_hChildStd_IN_Rd); debug_log("Create highlight process finished.\n"); ppinfo.child_pi = child_pi; ppinfo.IN_Rd = g_hChildStd_IN_Rd; ppinfo.IN_Wr = g_hChildStd_IN_Wr; ppinfo.OUT_Rd = g_hChildStd_OUT_Rd; ppinfo.OUT_Wr = g_hChildStd_OUT_Wr; return ppinfo; }
-
void wait_highlight(PPInfo ppinfo) { //WaitForSingleObject(ppinfo.child_pi.hProcess, INFINITE); WaitForSingleObject(ppinfo.child_pi.hProcess, 10000); if (!CloseHandle(ppinfo.OUT_Wr)) debug_log(TEXT("Child StdOutWr CloseHandle")); // Read from pipe that is the standard output for child process. //printf("\n->Contents of child process STDOUT:\n\n", argv[1]); ReadFromPipe(ppinfo.OUT_Rd); //printf("\n->End of parent execution.\n"); // The remaining open handles are cleaned up when this process terminates. // To avoid resource leaks in a larger application, close handles explicitly. }
-
DWORD WriteBufToPipe(HANDLE wHandle,const char* buf, DWORD bufsize) // Read from a file and write its contents to the pipe for the child's STDIN. // Stop when there is no more data. { int i, dwRead; DWORD dwWritten; CHAR chBuf[BUFSIZE+1]; BOOL bSuccess = FALSE; chBuf[BUFSIZE] = 0; #if false bSuccess = WriteFile(wHandle, buf, bufsize, &dwWritten, NULL); #else i=0; for (;;) { //bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL); //if (!bSuccess || dwRead == 0) break; dwRead = (bufsize - BUFSIZE*i); if ( dwRead <= 0) break; dwRead = min(dwRead+1,BUFSIZE); memcpy(chBuf,&(buf[BUFSIZE*i]),dwRead); debug_log("Write %d bytes of chbuf %s to handle\n",dwRead,chBuf); bSuccess = WriteFile(wHandle, chBuf, dwRead, &dwWritten, NULL); debug_log("Write buf %d time,bSuccess=%d\n",i,bSuccess); if (!bSuccess) break; FlushFileBuffers(wHandle); debug_log("Flush write handle.\n"); i=i+1; } #endif debug_log("Write buf finished\n"); // Close the pipe handle so the child process stops reading. if (!CloseHandle(wHandle)) debug_log(TEXT("StdInWr CloseHandle")); return dwWritten; }
-
PROCESS_INFORMATION CreateChildProcess(const char* file_ext,HANDLE hOutput, HANDLE hInput) // Create a child process that uses the previously created pipes for STDIN and STDOUT. { TCHAR szCmdline[1024] = TEXT("D:\\Data\\WebRoot\\cgit\\highlight-3.39-x64\\highlight.exe --force --inline-css -f -I -O xhtml -S "); PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bSuccess = FALSE; //Append file extension strcat(szCmdline,file_ext); debug_log("%s\n",szCmdline); // Set up members of the PROCESS_INFORMATION structure. ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION)); // Set up members of the STARTUPINFO structure. // This structure specifies the STDIN and STDOUT handles for redirection. ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdError = hOutput;//g_hChildStd_OUT_Wr; siStartInfo.hStdOutput = hOutput;//g_hChildStd_OUT_Wr; siStartInfo.hStdInput = hInput;//g_hChildStd_IN_Rd; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; // Create the child process. bSuccess = CreateProcess(TEXT("D:\\Data\\WebRoot\\cgit\\highlight-3.39-x64\\highlight.exe"), szCmdline, // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION // If an error occurs, exit the application. if (!bSuccess) debug_log(TEXT("CreateProcess Failed.")); else { // Close handles to the child process and its primary thread. // Some applications might keep these handles to monitor the status // of the child process, for example. CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); } return piProcInfo; }
-
const char *get_filename_ext(const char *filename) { const char *dot = strrchr(filename, '.'); if(!dot || dot == filename) return NULL; return dot + 1; }
-
Test Main Code
int test_process2(const char* filename,const char* buf, DWORD bufsize) { PPInfo cIn; int i, dwRead; DWORD dwWritten; CHAR chBuf[BUFSIZE+1]; BOOL bSuccess = FALSE; chBuf[BUFSIZE] = 0; debug_log("test_process2 start.\n"); cIn=prepare_highlight(filename); //WriteToPipe(cIn.IN_Wr,g_hInputFile); i=0; for (;;) { //bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL); //if (!bSuccess || dwRead == 0) break; dwRead = (bufsize - BUFSIZE*i); if ( dwRead <= 0) break; dwRead = min(dwRead+1,BUFSIZE); memcpy(chBuf,&(buf[BUFSIZE*i]),dwRead); debug_log("Write %d bytes of chbuf %s to handle\n",dwRead,chBuf); bSuccess = WriteFile(cIn.IN_Wr, chBuf, dwRead, &dwWritten, NULL); debug_log("Write buf %d time\n",i); if (!bSuccess) break; i=i+1; } debug_log("Write buf finished\n"); // Close the pipe handle so the child process stops reading. if (!CloseHandle(cIn.IN_Wr)) debug_log(TEXT("StdInWr CloseHandle")); wait_highlight(cIn); debug_log("test_process2 finished.\n"); return 0; }
PS:
这里在顺便提一下,如何在Windows下编译cgit, 下载并安装git-sdk,然后在打开的shell里面make即可。之后拷贝到Apache相关目录并设置即可。
apache + gerrit + gitweb on windows 的配置
折腾了几天终于比较完整的搞定了。
电脑运行Windows Server 2008R2 with SP1,Java 1.6.0_45 x86版。
1、需要的软件
msysgit(1.8.3),gerrit(2.8.4),apache(2.4.9),gerrit_service(git commit 29aa688d2312feeca1130ac96eed9a3810088e03)
括号内为当前使用的版本。
2、安装msysgit,apache,获取gerrit,及gerrit_service的源代码。
这里仅给出gerrit_service的git repo:https://github.com/asankah/gerrit_service.git
3、Apache 配置
这里我们使用VirtualHost并开启SSL加密,配置二级域名gerrit.fengtech.com提供review服务。配置本地客户端使用用户名密码/证书进行认证,internet客户端必须使用客户端证书进行认证。
#重定向普通端口的访问到SSl端口 <VirtualHost *:80> ServerName gerrit.fengtech.com Redirect / https://gerrit.fengtech.com/ </VirtualHost>
#在开启了SSL的443端口配置虚拟主机 <VirtualHost *:443> ServerAdmin xifeng.ren@gmail.com ServerName gerrit.fengtech.com ErrorLog "logs/error_log_ssl" TransferLog "logs/access_log_ssl" SSLEngine on SSLProtocol all -SSLv2 SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5 SSLCertificateFile "D:/path/to/conf/ssl/keys/.fengtech.com.crt" SSLCertificateKeyFile "D:/path/to/conf/ssl/keys/.fengtech.com.key" SSLVerifyClient none #配置客户端验证ca SSLCACertificateFile "D:/path/to/conf/ssl/keys/ca.crt" #配置客户端验证ca的吊销列表 SSLCARevocationFile "D:/path/to/conf/ssl/keys/ca.crl" SSLCARevocationCheck chain #配置代理把连接转向gerrit服务器 ProxyRequests Off ProxyVia Off ProxyPreserveHost On <Proxy *> Order deny,allow Allow from all </Proxy> #这里我们配置/login/需要认证,我们也可以设置所有的连接都需要真正,把"/login/"换成"/"即可,不包含引号. <Location /login/> SSLVerifyClient optional SSLOptions +FakeBasicAuth SSLOptions +StrictRequire # Force clients from the Internet to use HTTPS #RewriteEngine on #RewriteCond %{REMOTE_ADDR} !^192\.168\.1\.[0-9]+$ #RewriteCond %{HTTPS} !=on #RewriteRule . - [F] # Allow Network Access and/or Basic Auth <requireall> # Network Access Control Require ip ::1 127 10 219.217.159.76 # HTTP Basic Authentication AuthType basic AuthName "Gerrit Code Review" AuthBasicProvider file AuthUserFile D:/path/to/htpasswd Require valid-user </requireall> <requireall> SSLVerifyDepth 5 SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128 AuthBasicFake %{SSL_CLIENT_S_DN_CN} %{sha1:passphrase-%{SSL_CLIENT_S_DN_CN}} Require ssl-verify-client </requireall> </Location> AllowEncodedSlashes On #这里我们使用127.0.0.1:8081是我们后面要配置的gerrit服务监听的地址和端口。 ProxyPass / http://127.0.0.1:8081/ nocanon ProxyPassReverse / http://127.0.0.1:8081/ <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory "D:/path/to/WebRoot/cgi-bin"> SSLOptions +StdEnvVars </Directory> BrowserMatch "MSIE [2-5]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 CustomLog "logs/ssl_request_log_gerrit" \ "%t %h %u %{SSL_CLIENT_S_DN_CN}x %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost>
好了接下来配置gerrit。
4、gerrit的配置与安装。
gerrit需要java环境,x86或者x86_64均可,要求1.6以上版本。这里使用的是sun java1.6.0_45 x64的版本。
所有gerrit,去google下载war包,我下载的是gerrit-2.8.4.war。
配置gerrit目录
D:\Developer\WebRoot>java -jar gerrit-2.8.4.war init -d gerrit_git *** Gerrit Code Review 2.8.4 *** Create 'D:\Developer\WebRoot\gerrit_git' [Y/n]?y *** Git Repositories *** Location of Git repositories [git]:git *** SQL Database *** Database server type [h2]:h2 *** User Authentication *** 这里改为http的认证方式,使用我们刚才配置的apache认证。 Authentication method [OPENID/?]: http Get username from custom HTTP header [y/N]? SSO logout URL : *** Email Delivery 这里我们先采用默认设置稍后再更改邮件发送服务器设置。 *** SMTP server hostname [localhost]: SMTP server port [(default)]: SMTP encryption [NONE/?]: SMTP username [Administrator]: Administrator's password : confirm password : *** Container Process *** Run as [Administrator]: Java runtime [D:\Program Files\Java\jdk1.6.0_45\jre]: Copy gerrit-2.8.4.war to D:\Developer\WebRoot\gerrit_git\bin\gerrit.war [Y/n]? *** SSH Daemon *** 监听地址*,方便可以远程使用ssh协议clone和push代码,否则可以改为127.0.0.1,近监听本地端口。 Listen on address [*]: Listen on port [29418]: Gerrit Code Review is not shipped with Bouncy Castle Crypto v144 If available, Gerrit can take advantage of features in the library, but will also function without it. Download and install it now [Y/n]? y Generating SSH host key ... rsa(simple)... done *** HTTP Daemon *** 这里我们仅监听127.0.0.1这个地址即可,供给本机apache使用,当然如果使用不同的服务器,需要配置合适的监听地址。端口采用8081与apache里面的配置相对应。canonical url 使用我们的二级域名gerrit.fengtech.com Behind reverse proxy [y/N]? y Proxy uses SSL (https://) [y/N]? y Subdirectory on proxy server [/]: Listen on address [*]: 127.0.0.1 Listen on port [8081]: 8081 Canonical URL [https://127.0.0.1/]: https://gerrit.fengtech.com / *** Plugins *** 以下的plugin可以选择N,即默认。 Install plugin download-commands version v2.8.4 [y/N]? y Install plugin reviewnotes version v2.8.4 [y/N]? y Install plugin replication version v2.8.4 [y/N]? y Install plugin commit-message-length-validator version v2.8.4 [y/N]? y *** 提示配置完成,但没有自动启动,我们需要用gerrit_service配置启动gerrit Server。 Initialized D:\Developer\WebRoot\gerrit_git Automatic startup not supported on Win32.
接下来贴一下配置的结果,配置文件再gerrit目录的etc文件夹里面
[gerrit] basePath = git canonicalWebUrl = https://gerrit.fengtech.com/ [database] type = h2 database = db/ReviewDB [auth] type = HTTP [sendemail] smtpServer = smtp.gmail.com smtpServerPort = 465 smtpEncryption = ssl smtpUser = username@gmail.com smtpPass = password sslVerify = false from = Code Review <username@gmail.com> [container] user = Administrator javaHome = D:\\Program Files\\Java\\jdk1.6.0_45\\jre [sshd] listenAddress = *:29418 [httpd] listenUrl = proxy-https://127.0.0.1:8081/ [cache] directory = cache [gitweb] ;这个文件是我们一会儿要创建的对perlcgi的一个wrap,要么在windows下运行不了gitweb. cgi = /D:/path/to/Git/share/gitweb/gitweb.bat
gitweb.bat
@echo off rem 这里一定要使用git提供的perl. @"D:\Developer\Git\bin\perl.exe" "D:\Developer\Git\share\gitweb\gitweb.cgi" %*
gitweb.cgi
修改gitweb.cgi的变量
our $GIT = "D:/Developer/Git/bin/git"; 指定git
our $projectroot = "/path/to/GitRepos"; git respons 的目录
5、安装和配置gerrit_service服务。
获取源代码:git clone https://github.com/asankah/gerrit_service.git
具体是的使用参见clone得到的文档,这里仅给出用到的命令。
编译 cl /EHsc gerrit_service.cpp
安装 拷贝gerrit_service.exe 到 gerrit\bin目录
添加服务 gerrit_service.exe -j "d:\path\to\javahome" -d "d:\path\to\gerrit" -i -a apacheuser -p apachepassword
PS:注意这里一定到使用一个账户,不能用"本地系统账户",否者在配置使用cgi即gitweb的时候,打开gitweb页面非常慢,甚至停止反应。推荐新建apacheuser账户,把apache Server和 gerrit_service 都使用这个账户。
Build Apache On Windows
0、为目标平台准备 perl,zlib,pcre,openssl。
perl需要安装并加入到PATH环境变量里。pcre和httpd的编译都要用到。
zlib和pcre均使用cmake编译,这里就不说了。
openssl 的编译,按照源文件下的INSTALL进行编译,注意有win32,win64a,win64i之分。并enable-zlib。
1、使用window版本的源代码:
apr-1.5.0-win32-src.zip,apr-iconv-1.2.1-win32-src-r2.zip,apr-util-1.5.3-win32-src.zip
2、全部解压到当前目录
创建并重命名或者创建符号链接,去掉版本号即目录下:apr,apr-iconv,apr-util.
3、这里我们使用visual studio 编译:
1)IED编译。打开apr-util下的aprutil.dsw,会提示转换。选择是进行转换。然后尝试编译。
2)命令行编译。打开vs command promote 命令行,进入apr-util目录
NMAKE /f "libaprutil.mak" CFG="libaprutil - Win32 Release" REM "libaprutil - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") REM "libaprutil - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") REM "libaprutil - x64 Release" (based on "Win32 (x86) Dynamic-Link Library") REM "libaprutil - x64 Debug" (based on "Win32 (x86) Dynamic-Link Library")
这里要修改原来的文件的一处错误:
--- apr-iconv-1.2.1.orig\build\modules.mk.win Fri Oct 19 04:49:36 2007 +++ apr-iconv-1.2.1\build\modules.mk.win Mon Apr 21 14:56:22 2014 @@ -218,7 +218,7 @@ .c{$(OUTPUT_DIR)}.so: $(SILENT)cl $(ALL_CFLAGS) /Fo$*.obj /Yuiconv.h /c $< - $(SILENT)link $(ALL_LDFLAGS) $*.obj $(API_LIBS) /out:$@ \ + $(SILENT)link $(ALL_LDFLAGS) $*.obj $(MODRES).obj $(API_LIBS) /out:$@ \ /base:@"..\build\BaseAddr.ref",$(@F) $(SILENT)if exist $@.manifest \ $(SILENT)mt -nologo -manifest $@.manifest -outputresource:$@;2 \
4、编译httpd之前的准备
1)这里我们要把所有的include文件合并到一起,要门cmake进行configure的时候会出错。 拷贝apr,apr-iconv和apr-util下的include文件夹合并到上一层的include文件夹。
2)修正CMakeLists.txt的错误。
--- httpd-2.4.9.orig\CMakeLists.txt Tue Nov 19 05:18:12 2013 +++ httpd-2.4.9\CMakeLists.txt Mon Apr 21 18:42:32 2014 @@ -678,8 +678,8 @@ IF("${${mod_name}_install_lib}") SET(installed_mod_libs_exps ${installed_mod_libs_exps} - "${PROJECT_BINARY_DIR}/${mod_name}.lib" - "${PROJECT_BINARY_DIR}/${mod_name}.exp" + "${PROJECT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}/${mod_name}.lib" + "${PROJECT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}/${mod_name}.exp" ) ENDIF() SET(mod_extra_libs "${mod_name}_extra_libs") @@ -825,7 +825,7 @@ ) INSTALL(FILES ${other_installed_h} DESTINATION include) INSTALL(FILES ${installed_mod_libs_exps} DESTINATION lib) -INSTALL(FILES "${CMAKE_BINARY_DIR}/libhttpd.exp" DESTINATION LIB) +INSTALL(FILES "${CMAKE_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}/libhttpd.exp" DESTINATION LIB) IF(INSTALL_MANUAL) # Silly? This takes a while, and a dev doesn't need it. INSTALL(DIRECTORY docs/manual/ DESTINATION manual) @@ -849,7 +849,7 @@ # Windows anyway. STRING(REPLACE "/" "\\\\" native_src ${CMAKE_BINARY_DIR}/conf/original) STRING(REPLACE "/" "\\\\" native_dest ${CMAKE_INSTALL_PREFIX}/conf/original) -INSTALL(CODE "EXECUTE_PROCESS(COMMAND xcopy ${native_src} ${native_dest} /Q /S /Y)") +INSTALL(CODE "EXECUTE_PROCESS(COMMAND robocopy ${native_src} ${native_dest} /E)") STRING(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype) MESSAGE(STATUS "")
5、使用cmake生成httpd工程(这里使用的是httpd-2.4.9的版本)
这里我们要给定openssl,zlib,pcre,apr,当然如果用得到libxml2也一样给定。
configure,generate,build.
关掉Windows的权限提示
1、打开本地组策略编辑器
gpedit.msc
2、找到 计算机配置->Windows设置->安全设置->本地策略->安全选项
修改 用户帐户控制:管理员批准模式中的管理员提升权限提示的行为 为 不提示,直接提升
并检查:用户帐户控制:以管理员审批模式运行所有管理员 为 已启用
PS:
对于Server的系统,使用内部管理员账号(administrator),需要 启用 用户帐户控制:用于内置帐户的管理员审批模式
Gallery3 On Windows with Apache Server.
1.We need to patch some files to make gallery3 run on windows with apache web server. This is the path, but it's not stronge. you can not use this patch when you use linux etc.
2.This patch mainly fixed errors when you use none utf8 encode system. it convert the utf8 encoded filenames to locale encoded ones.
diff --git a/index.php b/index.php index e6636cf..70aeb3d 100644 --- a/index.php +++ b/index.php @@ -26,7 +26,8 @@ version_compare(PHP_VERSION, "5.2.3", "<") and // Gallery is not supported on Windows. if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - exit("Gallery is not supported on Windows (PHP reports that you're using: " . PHP_OS . ")"); +define("WIN",true); +// exit("Gallery is not supported on Windows (PHP reports that you're using: " . PHP_OS . ")"); } // PHP 5.4 requires a timezone - if one isn't set date functions aren't going to work properly. diff --git a/modules/gallery/helpers/system.php b/modules/gallery/helpers/system.php index f0879d6..2c34d11 100644 --- a/modules/gallery/helpers/system.php +++ b/modules/gallery/helpers/system.php @@ -48,7 +48,11 @@ class system_Core { foreach ($paths as $path) { $path = rtrim($path, "/"); - $candidate = "$path/$binary"; + if (!preg_match("/^win/i", PHP_OS)) { + $candidate = "$path/$binary"; + }else{ + $candidate = "$path/$binary.exe"; + } // @suppress errors below to avoid open_basedir issues if (@file_exists($candidate)) { if (!@is_executable($candidate) && diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index c446eea..cfc75f8 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -167,7 +167,7 @@ class Item_Model_Core extends ORM_MPTT { * movie: /usr/home/www/gallery3/var/albums/Bobs Wedding/First-Dance.mp4 */ public function file_path() { - return VARPATH . "albums/" . urldecode($this->relative_path()); + return VARPATH . "albums/" . iconv("UTF-8","GBK",urldecode($this->relative_path())); } /** @@ -194,7 +194,7 @@ class Item_Model_Core extends ORM_MPTT { * movie: /usr/home/www/gallery3/var/thumbs/Bobs Wedding/First-Dance.jpg */ public function thumb_path() { - $base = VARPATH . "thumbs/" . urldecode($this->relative_path()); + $base = VARPATH . "thumbs/" . iconv("UTF-8","GBK",urldecode($this->relative_path())); if ($this->is_photo()) { return $base; } else if ($this->is_album()) { @@ -245,7 +245,7 @@ class Item_Model_Core extends ORM_MPTT { * (*) Since only photos have resizes, album and movie paths are fictitious. */ public function resize_path() { - return VARPATH . "resizes/" . urldecode($this->relative_path()) . + return VARPATH . "resizes/" . iconv("UTF-8","GBK",urldecode($this->relative_path())) . ($this->is_album() ? "/.album.jpg" : ""); } diff --git a/modules/gallery/views/admin_block_platform.html.php b/modules/gallery/views/admin_block_platform.html.php index 9a594fa..76fb0a2 100644 --- a/modules/gallery/views/admin_block_platform.html.php +++ b/modules/gallery/views/admin_block_platform.html.php @@ -15,9 +15,11 @@ <li> <?= t("MySQL: %mysql_version", array("mysql_version" => Database::instance()->query("SELECT version() as v")->current()->v)) ?> </li> + <?php if (function_exists("sys_getloadavg")): ?> <li> <?= t("Server load: %load_average", array("load_average" => join(" ", sys_getloadavg()))) ?> </li> + <?php endif; ?> <li> <?= t("Graphics toolkit: %toolkit", array("toolkit" => module::get_var("gallery", "graphics_toolkit"))) ?> </li>
Windows系统下的ANSYS Fluent多机并行配置要点。
1.在每台机上上相同的目录安装ANSYS,这里假设为:D:\ANSYS.INC
2.在设置共享,我们共享计算实例所处的文件夹为workspace:这里为:\\RXF-WS2008R2\ANSYS Inc\workspace
3.启动fluent.exe,配置如图
我想要的多屏幕操作
- 在两个屏幕底部都能显示任务栏,任务栏显示当前屏幕包含横向主窗口的程序图标。
- 在屏幕之间拖动时,任务栏图标也随之改变。
- 没发现有类似的软件。