一、编译方法
安装WinFsp开发包
-
https://github.com/winfsp/winfsp/releases下载
-
以管理员管理运行命令行,安装WinFsp
msiexec /i winfsp-2.1.24255.msi
-
安装时加选Developer组件
-
设置装winfsp_passthrough项目属性
设置include目录:C:\Program Files (x86)\WinFsp\inc
设置lib目录:C:\Program Files (x86)\WinFsp\lib
添加链接库winfsp-$(PlatformTarget).lib
添加环境变量:C:\Program Files (x86)\WinFsp\bin
Windows安装Protobuf、gRPC 库
-
安装vcpkg
git clone https://github.com/microsoft/vcpkg.git cd vcpkg bootstrap-vcpkg.bat
-
让VS使用vcpkg
vcpkg integrate install
等效于设置VS的头文件目录(D:\vcpkg\installed\x64-windows\include) 和库目录(D:\vcpkg\installed\x64-windows\lib),并将库目录下所有的lib添加链接
-
通过vcpkg安装相关的库
vcpkg install protobuf:x64-windows vcpkg install grpc:x64-windows
查询grpc版本:
vcpkg list | findstr grpc
Linux安装Protobuf、gRPC 库
-
安装vcpkg
git clone https://github.com/microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh
-
生成vcpkg.cmake
./vcpkg integrate install
-
通过vcpkg安装相关的库
./vcpkg install protobuf:x64-linux ./vcpkg install grpc:x64-linux --recurse
查询grpc版本:
vcpkg list | grep grpc
Android下载 gRPC 库(包含了Protobuf等子库)
下载gRPC及其子库源码 (注意版本号要与服务端相同, 只用来构建,使用–depth 1浅克隆即可)
cd windows_passthrough
git clone -b v1.70.1 --depth 1 --recurse-submodules https://github.com/grpc/grpc.git
CMakeLists.txt导入Protobuf、gRPC 库
如果是vcxproj项目,通过 vcpkg integrate install 设置后可以直接检测vcpkg安装的库,CMake项目需要通过CMakeLists.txt配置,示例如下:
cmake_minimum_required(VERSION 3.10)
project(windows_passthrough)
# 选择 C++ 标准
set(CMAKE_CXX_STANDARD 17)
# 根据平台选择不同的编译选项
if(WIN32)
add_definitions(
-DUNICODE
-DPLATFORM_WINDOWS
-D_CRT_SECURE_NO_WARNINGS
-DNOMINMAX
-D_WINSOCKAPI_
-D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
)
set(CMAKE_TOOLCHAIN_FILE "D:/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "vcpkg toolchain file")
elseif(ANDROID)
add_definitions(
-DPLATFORM_ANDROID
-D_CRT_SECURE_NO_WARNINGS
-DNOMINMAX
-D_WINSOCKAPI_
-D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# 关闭不需要的构建项,避免依赖 host 工具
set(gRPC_BUILD_GRPC_CPP_PLUGIN OFF)
set(gRPC_BUILD_REFLECTION OFF)
# 使用模块构建所有 gRPC 依赖
set(gRPC_ABSL_PROVIDER "module")
set(gRPC_CARES_PROVIDER "module")
set(gRPC_RE2_PROVIDER "module")
set(gRPC_SSL_PROVIDER "module")
set(gRPC_PROTOBUF_PROVIDER "module")
set(gRPC_ZLIB_PROVIDER "module")
set(CMAKE_SKIP_INSTALL_RULES ON)
add_subdirectory(grpc EXCLUDE_FROM_ALL)
elseif(UNIX)
add_definitions(
-DPLATFORM_LINUX
-D_CRT_SECURE_NO_WARNINGS
-DNOMINMAX
-D_WINSOCKAPI_
-D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
)
set(CMAKE_TOOLCHAIN_FILE "/data/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "vcpkg toolchain file")
endif()
# 查找并列出源文件
file(GLOB SOURCES
"local_fs.cpp"
"local_fs.h"
"main.cpp"
"mount_client.cpp"
"mount_client.h"
"service.cpp"
"service.h"
"winfs.grpc.pb.cc"
"winfs.grpc.pb.h"
"winfs.pb.cc"
"winfs.pb.h"
"common.cpp"
"common.h"
)
# 打印源文件路径
message(STATUS "Source files: ${SOURCES}")
# 添加可执行文件
add_executable(windows_passthrough ${SOURCES})
if(ANDROID)
add_custom_command(TARGET windows_passthrough POST_BUILD
COMMAND ${CMAKE_TOOLCHAIN_FILE}/../../../toolchains/llvm/prebuilt/windows-x86_64/bin/llvm-strip ${CMAKE_BINARY_DIR}/windows_passthrough
COMMENT "strip剥离符号,减小可执行文件体积"
)
target_include_directories(windows_passthrough PRIVATE grpc/include)
target_link_libraries(windows_passthrough PRIVATE
grpc++
)
else()
# 查找并链接 gRPC
find_package(gRPC CONFIG REQUIRED)
# 添加 gRPC 头文件目录
target_include_directories(windows_passthrough PRIVATE ${gRPC_INCLUDE_DIRS})
# 添加链接库
target_link_libraries(windows_passthrough PRIVATE
gRPC::grpc++
)
endif()
重新生成 .proto
代码
由于Protobuf和gRPC库更新后,与旧版本生成的.proto代码不兼容,需要重新生成
- 设置环境变量
将protoc.exe所在的目录D:\vcpkg\installed\x64-windows\tools\protobuf设置到Path环境变量中,并重启[资源管理器]和[命令行窗口] - 生成 pb.h 和 pb.cc 以及 grpc.pb.h 和 grpc.pb.c
cd winfsp_passthrough\pb #项目中winfs.proto所在的目录 # 生成 Protobuf 数据结构 的 C++ 代码(pb.h 和 pb.cc) protoc --cpp_out=. winfs.proto #--cpp_out=. 表示输出到当前目录 # 生成 gRPC 服务 的 C++ 代码(grpc.pb.h 和 grpc.pb.cc) protoc --grpc_out=. --plugin=protoc-gen-grpc=D:\vcpkg\installed\x64-windows\tools\grpc\grpc_cpp_plugin.exe winfs.proto
设置预编译宏
由于更新了Protobuf和gRPC库,导致某些编译错误,可以在项目属性页的[C/C++]–>[预处理器]中添加宏定义:
_CRT_SECURE_NO_WARNINGS
NOMINMAX
_WINSOCKAPI_
或者在预编译头文件stdafx.h中添加定义(一定要是预编译头文件中)
二、使用方法
服务端初始配置
- 安装winfsp-2.1.24255.msi (https://github.com/winfsp/winfsp/releases)
组件只要默认的Core即可,添加环境变量:C:\Program Files (x86)\WinFsp\bin,安装后重启电脑,如果权限不够, 以管理员身份运行命令行, 执行命令msiexec /i winfsp-2.1.24255.msi
- 文件夹属性设置(打开用户全部权限,取消只读限制)
挂一个盘,退盘后自动结束服务
- 运行服务端,监听所有网卡的12345端口 (不要用管理员权限运行服务端)
winfsp_passthrough.exe -work 0.0.0.0:12345
- 运行客户端,将本地的d:盘挂载成127.0.0.1机器的f:盘(必须指定盘符, 最后的数字是指定的盘符的ID号)
windows_passthrough.exe -mount d: 127.0.0.1:12345 f: 1
- ctrol+c停掉客户端完成卸载(点X关闭服务端窗口可能导致进程不退出)
支持多次挂盘的服务端守护进程
- 运行服务端,监听所有网卡的12345端口(不要用管理员权限运行服务端)
winfsp_passthrough.exe -gateway 0.0.0.0:12345
- 运行客户端,将本地的d:盘挂载到127.0.0.1机器的任意两个盘(最后的ID号必须不相同, 也可以在ID号前带上盘符参数来指定盘符)
windows_passthrough.exe -mount d: 127.0.0.1:12345 1 windows_passthrough.exe -mount d: 127.0.0.1:12345 2
- ctrol+c停掉客户端完成卸载
支持检测U盘插入的客户端守护进程
- 运行客户端守护进程,插入U盘后自动透传
windows_passthrough.exe -daemon 127.0.0.1:12345
ctrl+c停掉客户端完成卸载
支持检测U盘插入的客户端守护进程
- 运行客户端守护进程,插入U盘后自动透传
windows_passthrough.exe -daemon 127.0.0.1:12345