VNC的协议文档在RealVNC.com的帮助中心下载。
其实际文档只有3.3/3.7/3.8协议版本是属于公开的,而4.0是不公开的。
也就是该相关文档的最新版本日期是2011年。
其真正下载地址如下:
https://tools.ietf.org/html/rfc6143
最完整的协议文档是由TigerVNC维护:https://github.com/rfbproto/rfbproto
【VNC的粘贴板是通过CutBuffer实现,其已经被放弃。故最新系统的VNC都是不支持远程字符串复制和粘贴】
【https://github.com/sigmike/autocutsel】此粘贴技术的关键字是:CUT_BUFFER0
分类目录归档:QT
Android安卓sshserver服务器版
Android/lto物联网等
第一种方案是Libssh2/libssh1这两种方案,需要个人开发很多功能。
第二种使用已经安卓化的应用:https://github.com/CFM880/simplesshd,可搭配
http://www.galexander.org/software/simplesshd/
https://gitee.com/skyuning/frpc-Android安卓的反向代理。
https://github.com/fatedier/frp
https://github.com/FrpcCluster/frpc-Android安卓的集群版反向代理
Android添加第三方库
if(ANDROID) # the follow VARIABLE must be written before find_package or it will be no effective. # must add CACHE INTERNAL parameter. or it will failed. message("add the third so library to project") #set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android" CACHE INTERNAL "") set(ANDROID_EXTRA_LIBS "${LIBSSH_SOURCE_PATH}/lib/libssh.so" CACHE INTERNAL "") message("ANDROID_EXTRA_LIBS=${ANDROID_EXTRA_LIBS}") endif() |
The CACHE is mandatory, otherwise QtCreator won’t see the variable and it won’t use it
JETBRAIN/phpstorm/golang/clion的永久激活码
推荐方法是:
http://kxtry.com/upload/jetbrains-agent.tar.gz>
V0Z5FCVKUI-eyJsaWNlbnNlSWQiOiJWMFo1RkNWS1VJIiwibGljZW5zZWVOYW1lIjoi5rC45LmF5r+A5rS7IGlkZWEubWVkZW1pbmcuY29tIiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IiIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiSUkiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkFDIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJEUE4iLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUlNDIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBTIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU0YiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiR08iLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRNIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IkNMIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSUzAiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUkMiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUkQiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlBDIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU1YiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUlNVIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSTSIsInBhaWRVcFRvIjoiMjAyMC0wNS0xMyIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiV1MiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRCIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJEQyIsInBhaWRVcFRvIjoiMjAyMC0wNS0xMyIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQREIiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUFdTIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBHTyIsInBhaWRVcFRvIjoiMjAyMC0wNS0xMyIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQUFMiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUFBDIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBSQiIsInBhaWRVcFRvIjoiMjAyMC0wNS0xMyIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQU1ciLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiRFAiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUlMiLCJwYWlkVXBUbyI6IjIwMjAtMDUtMTMiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiRFBBIiwicGFpZFVwVG8iOiIyMDIwLTA1LTEzIiwiZXh0ZW5kZWQiOnRydWV9XSwibWV0YWRhdGEiOiIwMTIwMjAwNDE0UFBBTTAwMDAwNSIs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 |
CMake的目录输出
也许是CMake的版本问题,某些时候以下配置只需要配置其中一项就可以达到目的,有的根本无效。
—————————————————————-
———-这是Window的特色设置,在Linux中只需要一个CMAKE_INSTALL_PREFIX即可—————-
—————————————————————
以下是几乎百分百有效的配置。
SET(CMAKE_EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_EXECUTABLE_OUTPUT_PATH_DEBUG ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_EXECUTABLE_OUTPUT_PATH_RELEASE ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_LIBRARY_OUTPUT_PATH_DEBUG ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_LIBRARY_OUTPUT_PATH_RELEASE ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin) SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin) |
Qt项目。
cmake -A x64 -T host=x64 ../wotermt生成vc工程。
cmake –build . –config Release采用Release编译。
Ubuntu14.04的Qt编译环境
报错When executing step “Make”
sudo apt-get install build-essential
终端测试验证工具
https://misc.flogisoft.com/bash/home
终端配色:https://misc.flogisoft.com/bash/tip_colors_and_formatting
colors256.sh
#!/bin/bash for fgbg in 38 48 ; do # Foreground / Background for color in {0..255} ; do # Colors # Display the color printf "\e[${fgbg};5;%sm %3s \e[0m" $color $color # Display 6 colors per lines if [ $((($color + 1) % 6)) == 4 ] ; then echo # New line fi done echo # New line done exit 0 |
colors_and_formatting.sh
#!/bin/bash #Background for clbg in {40..47} {100..107} 49 ; do #Foreground for clfg in {30..37} {90..97} 39 ; do #Formatting for attr in 0 1 2 4 5 7 ; do #Print the result echo -en "\e[${attr};${clbg};${clfg}m ^[${attr};${clbg};${clfg}m \e[0m" done echo #Newline done done exit 0 |
——-
http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
http://www.xfree86.org/current/ctlseqs.html
Linux环境下,主要都是泛VT102的终端,以下是vt102终端。
https://vt100.net/docs/vt102-ug/introduction.html
https://vt100.net/docs/vt102-ug/contents.html
微软的
https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
VT100,VT101,
参考开源:https://konsole.kde.org/
headless vt100 emulator
https://github.com/JulienPalard/vt100-emulator
https://github.com/freanux/VTE
使用匿名函数,简易地把同步转异步
使用匿名函数,简易地把同步转异步。
大概思路,已经省去了线程池的相关说明。
#define MYASSERT(x) typedef std::function<QVariant(void)> FunAsyncTask; typedef std::function<void(QVariant)> FunSuccessCallBack; typedef std::function<void(QVariant)> FunErrorCallBack; //从KAsyncTask派生 class AsyncTask { private: const FunAsyncTask task; const FunSuccessCallBack ok_cb; const FunErrorCallBack err_cb; const QPointer<QObject> callerThiz; //外部调用者的This指针,目的利用它来检验当前匿名函数所捕获的参数是否仍有效。 QVariant result; QVariant err; //ToDo保存调用线程,调用线程与成功及错误的处理是同一个线程,也即是调用成功及错误之前先检查线程是否相同。 int threadCallId; //任务请求的线程。 int threadDoTaskId; //任务处理的线程 public: static void post_aync_task(QObject *thiz, FunAsyncTask t, FunSuccessCallBack ok, FunErrorCallBack err) { AsyncTask *task = new AsyncTask(thiz, t, ok, err); //ToDo推送至多线程任务队列。 } private: AsyncTask(QObject *thiz, FunAsyncTask t, FunSuccessCallBack ok, FunErrorCallBack err) : callerThiz(thiz), task(t), ok_cb(ok), err_cb(err) { threadCallId = GetCurrentThreadId(); } void run() { // AnyncThread do the job. threadDoTaskId = GetCurrentThreadId(); try { result = task(); //ToDo Save Ok } catch (...) { //TODO Save Error; } } void handleResult() { //ToDo MainThread to do the job. MYASSERT(callerThiz); MYASSERT(threadCallId == GetCurrentThreadId()); ok_cb(result); } void handleError() { //ToDo MainThread to do the Error MYASSERT(callerThiz); MYASSERT(threadCallId == GetCurrentThreadId()); err_cb(err); } }; void assertValidTaskLambda(char* txt) { //ToDo提取lamda表达式的中括号的参数进行检查,不允许使用"=&"的特殊字符,有该字符则输出错误及抛出异常。 //提取括号外及大括号前的字符串,不允许"mutable"参数使用。 printf("\r\n%s", txt); } void assertValidCallBackLambda(char* ok, char* err) { //ToDo提取lamda表达式的中括号的参数进行检查,不允许使用"&"的特殊字符,有该字符则输出错误及抛出异常。 //提取括号外及大括号前的字符串,不允许"mutable"参数使用。 printf("\r\n%s-%s", ok, err); } #define POST_AYNC_TASK(task, ok_cb, err_cb) \ {\ assertValidQObject(this); \ assertValidTaskLambda(#task); \ assertValidCallBackLambda(#ok_cb, #err_cb) \ AsyncTask::post_aync_task(this, task, ok_cb, err_cb); \ } int MyClass::execute() { int x = 1; int y = 2; int z = 3; int m = 4; FunAsyncTask task = [x, y, z]()->int{ return QVariant(123); }; FunSuccessCallBack ok = [x, m](QVariant r){ printf("ok...ok...%d", r); }; FunErrorCallBack err = [z, m](QVariant err){ printf("failed...failed...%d", err); }; POST_AYNC_TASK(task, ok, err); //这种使用,报错。 // 推荐以下方式使用,目的是语法检查,减少多线程出错。 // POST_AYNC_TASK((task_exp),(ok_exp),(err_exp)) // 如果表达式不用括号包裹起来的话,可能会导致编译出错。 POST_AYNC_TASK(([x, y, z]()->QVariant{ int v1 = x; int v2 = v1*2; Sleep(1000); return QVariant(v2 + z); }), ([=](QVariant r){ printf("ok...ok...%d", r); }), ([=](QVariant err){ printf("failed...failed...%d", err); })); getchar(); } |
Xperf与ETW脚本
@echo off pushd %~dp0 set now=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2% set now=%now: =0% echo %now% set path_current=%~dp0 set path=%path%;%path_current%;%path_current%\wpt set path_result=%path_current%\result if not exist %path_result% (md "%path_result%") set path_backup=%path_result%\backup if not exist %path_backup% (md "%path_backup%") set path_word=%path_result%\wps if not exist %path_word% (md "%path_word%") set path_et=%path_result%\et if not exist %path_et% (md "%path_et%") set path_ppt=%path_result%\_ppt if not exist %path__ppt% (md "%path__ppt%") set path_word_result=%path_result%\preread_word.txt set path_ppt_result=%path_result%\preread_ppt.txt set path_et_result=%path_result%\preread_et.txt set path_test=%~1 if not exist %path_test%\wpstest.exe ( echo "the path is wrong......" echo "can not find the wpstest.exe by that path." goto :exit ) set softnode=SOFTWARE IF "%PROCESSOR_ARCHITECTURE%"=="AMD64" set softnode=SOFTWARE\WOW6432Node reg query "HKLM\%softnode%\kxtry\test\6.0\Common\res">nul 2>nul && call :registry_clear if not exist %path_word_result% ( echo "ready to do wps preread info." pushd %path_word% call :dokswpt /kxtry /wps /runactions="sleep,10|closeapp" %path_current%/1.docx popd copy /Y %path_word%\prereaddata_%now%.txt %path_word_result% > nul 2>nul ) else if not exist %path_ppt_result% ( echo "ready to do _ppt preread info." pushd %path__ppt% call :dokswpt /kxtry /_ppt /runactions="sleep,10|closeapp" %path_current%/1.pptx popd copy /Y %path__ppt%\prereaddata_%now%.txt %path__ppt_result% > nul 2>nul ) else if not exist %path_et_result% ( echo "ready to do et preread info." pushd %path_et% call :dokswpt /kxtry /et /runactions="sleep,10|closeapp" %path_current%/1.xlsx popd copy /Y %path_et%\prereaddata_%now%.txt %path_et_result% > nul 2>nul ) else ( echo "all job was finished." ) echo "finish all..." goto :exit rem ------------- :registry_clear echo "remove the preRead's infomation from registry." reg export "HKEY_LOCAL_MACHINE\%softnode%\kxtry\test\6.0\Common\Res" %path_backup%\backup_%now%.reg /y reg delete "HKEY_LOCAL_MACHINE\%softnode%\kxtry\test\6.0\Common\Res">nul 2>nul /f reg delete "HKEY_CURRENT_USER\Software\kxtry\test\6.0\Common\Res" >nul 2>nul /f goto :exit rem -------- :dokswpt xperf -stop app_session -d app_tmp.etl xperf -stop -d base_tmp.etl if exist app_tmp.etl (del app_tmp.etl) if exist base_tmp.etl (del base_tmp.etl) echo "open session.." xperf -start -on Base xperf -start app_session -on CA80A0D7-6CA2-4F62-B22D-D0F88D79AE4B echo "%path_test%\wpstest.exe" %* call "%path_test%\wpstest.exe" %* xperf -stop app_session -d app_tmp.etl xperf -stop -d base_tmp.etl xperf -merge base_tmp.etl app_tmp.etl kxtry_%now%.etl xperf -tle -i kxtry_%now%.etl -o hardfaults_%now%.csv -a hardfault -file -bytes xperf -tle -i kxtry_%now%.etl -o time_%now%.csv -a dumper -provider {CA80A0D7-6CA2-4F62-B22D-D0F88D79AE4B} xperf -tle -i kxtry_%now%.etl -o pagefaults_%now%.csv -a dumper -provider {3D6FA8D3-FE05-11D0-9DDA-00C04FD7BA7C} hardpage.py wpstest time_%now%.csv pagefaults_%now%.csv _%now% goto :exit rem --------------- :exit echo "exit now..." popd |
预读处理
// FileOverlap.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <Windows.h> int cbCount = 0; BOOL printfDetail = FALSE; int loop_count = 200; int successCount = 0; int failedCount = 0; #define COMPUTE_TIME(fun) \ { \ DWORD begin = GetTickCount();\ fun;\ DWORD end = GetTickCount();\ printf("\r\n %s: loopCount:%d - cbCount:%d - successCount:%d - timeUsed:%d", #fun, loop_count, cbCount, successCount, end - begin);\ } void CALLBACK MyFileIOCompletionRoutine(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped) { if(printfDetail) { printf("\r\ndwErrorCode:%d - dwNumber:%d - offset:%d", dwErrorCode, dwNumberOfBytesTransfered, lpOverlapped->Offset); } cbCount++; if(dwNumberOfBytesTransfered > 0) { successCount++; } } void useReadFileEx(LPCTSTR file) { HANDLE hFile = CreateFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL); if(hFile == INVALID_HANDLE_VALUE) { printf("bad file"); return; } OVERLAPPED overlap = {0}; const DWORD dwStepSize = static_cast<DWORD>(1024 * 1024 * 1); const DWORD dwReadSize = dwStepSize - 3072; LPVOID buffer = ::VirtualAlloc( NULL, dwStepSize, MEM_COMMIT, PAGE_READWRITE); for(int i = 0; i < loop_count; i++) { overlap.Offset = (i % 1024) * dwStepSize; ::ReadFileEx(hFile, buffer, dwReadSize, &overlap, MyFileIOCompletionRoutine); } if(printfDetail){ printf("\r\nready wait....."); } while(loop_count > cbCount){ SleepEx(0, TRUE); } ::VirtualFree(buffer, 0, MEM_RELEASE); ::CloseHandle(hFile); if(printfDetail){ printf("\r\nuseReadFileEx:cbCount:%d ", cbCount); } } void useReadFile(LPCTSTR file) { HANDLE hFile = CreateFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL); if(hFile == INVALID_HANDLE_VALUE) { printf("bad file"); return; } DWORD len = 0; OVERLAPPED overlap = {0}; const DWORD dwStepSize = static_cast<DWORD>(1024 * 1024 * 1); const DWORD dwReadSize = dwStepSize - 3072; LPVOID buffer = ::VirtualAlloc( NULL, dwStepSize, MEM_COMMIT, PAGE_READWRITE); for(int i = 0; i < loop_count; i++) { overlap.Offset = (i % 1024) * dwStepSize; if(!::ReadFile(hFile, buffer, dwReadSize, &len, &overlap)) { if(GetLastError() == ERROR_IO_PENDING) { GetOverlappedResult(hFile, &overlap, &len, TRUE); } } } ::VirtualFree(buffer, 0, MEM_RELEASE); ::CloseHandle(hFile); } void useMoreReadFileEx(TCHAR (*files)[MAX_PATH], int count) { #if 1 for(int i = 0; i < count; i++) { useReadFileEx(files[i]); } #else OVERLAPPED overlap = {0}; const DWORD dwStepSize = static_cast<DWORD>(1024 * 1024 * 1); const DWORD dwReadSize = dwStepSize - 3072; LPVOID buffer = ::VirtualAlloc( NULL, dwStepSize, MEM_COMMIT, PAGE_READWRITE); for(int j = 0; j < count; j++) { HANDLE hFile = CreateFile(files[j], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL); if(hFile == INVALID_HANDLE_VALUE) { printf("bad file"); return; } for(int i = 0; i < loop_count; i++) { overlap.Offset = (i % 1024) * dwStepSize; ::ReadFileEx(hFile, buffer, dwReadSize, &overlap, MyFileIOCompletionRoutine); } } SleepEx(0, TRUE); #endif } void useMoreReadFile(TCHAR (*files)[MAX_PATH], int count) { for(int i = 0; i < count; i++) { useReadFile(files[i]); } } int _tmain(int argc, _TCHAR* argv[]) { TCHAR path[MAX_PATH] = _T("c:\\package.zip"); TCHAR files[10][MAX_PATH]; int fileCount = 1; if(argc < 3) { printf("\r\nexample1: 1024 c:\1.zip"); printf("\r\nexample1: 1024 c:\1.zip 1"); printf("\r\nexample1: 1024 c:\1.zip 1 2"); printf("\r\nexample2: 200 c:\cc|1.zip,2.zip"); printf("\r\nexample2: 200 c:\cc|1.zip,2.zip 1"); printf("\r\nexample2: 1024 c:\cc|1.zip,2.zip 1 2"); return 0; } loop_count = _ttoi(argv[1]); _tcscpy(path, argv[2]); if(argc >= 3) { TCHAR *pmain = _tcstok(path, _T("|")); if(pmain != NULL) { TCHAR *pfile = _tcstok(NULL, _T(",")); int i = 0; for(i = 0; i < 10 && pfile != NULL; i++) { _stprintf(files[i], _T("%s\\%s"), pmain, pfile); pfile = _tcstok(NULL, _T(",")); } fileCount = i; } } if(argc > 3) { printfDetail = argc > 4; if(fileCount > 1) { COMPUTE_TIME(useMoreReadFileEx(files, fileCount)); }else{ COMPUTE_TIME(useReadFileEx(path)); } }else if(argc == 3) { if(fileCount > 1) { COMPUTE_TIME(useMoreReadFile(files, fileCount)); }else{ COMPUTE_TIME(useReadFile(path)); } } getchar(); return 0; } |