@@ -22,6 +22,7 @@ package winfsp
2222import (
2323 "fmt"
2424 "os"
25+ "os/exec"
2526 "path"
2627 "runtime"
2728 "strings"
@@ -35,6 +36,8 @@ import (
3536 "github.com/juicedata/juicefs/pkg/meta"
3637 "github.com/juicedata/juicefs/pkg/utils"
3738 "github.com/juicedata/juicefs/pkg/vfs"
39+
40+ "golang.org/x/sys/windows/registry"
3841)
3942
4043var logger = utils .GetLogger ("juicefs" )
@@ -669,3 +672,69 @@ func Serve(v *vfs.VFS, fuseOpt string, fileCacheTo float64, asRoot bool, delayCl
669672 logger .Debugf ("mount point: %s, options: %s" , conf .Meta .MountPoint , options )
670673 _ = host .Mount (conf .Meta .MountPoint , []string {"-o" , options })
671674}
675+
676+ func RunAsSystemSerivce (name string , mountpoint string ) error {
677+ // https://winfsp.dev/doc/WinFsp-Service-Architecture/
678+ logger .Info ("Running as Windows system service." )
679+
680+ var cmds []string
681+ for _ , v := range os .Args [1 :] {
682+ if v == "-d" || v == "--background" {
683+ continue
684+ }
685+ cmds = append (cmds , v )
686+ }
687+
688+ cmdLine := strings .Join (cmds , " " )
689+
690+ regKeyPath := "SOFTWARE\\ WOW6432Node\\ WinFsp\\ Services\\ juicefs"
691+ k , err := registry .OpenKey (registry .LOCAL_MACHINE , regKeyPath , registry .ALL_ACCESS )
692+ if err != nil {
693+ if err == syscall .ERROR_FILE_NOT_FOUND || err == syscall .ERROR_PATH_NOT_FOUND {
694+ logger .Info ("Registry key not found, create it" )
695+ k , _ , err = registry .CreateKey (registry .LOCAL_MACHINE , regKeyPath , registry .ALL_ACCESS )
696+ if err != nil {
697+ return fmt .Errorf ("Failed to create registry key: %s" , err )
698+ }
699+ } else {
700+ return fmt .Errorf ("Failed to open registry key: %s" , err )
701+ }
702+ }
703+ defer k .Close ()
704+
705+ err = k .SetStringValue ("CommandLine" , cmdLine )
706+ if err != nil {
707+ return fmt .Errorf ("Failed to set registry key: %s" , err )
708+ }
709+
710+ securityDescriptor := "D:P(A;;RPWPLC;;;WD)"
711+ err = k .SetStringValue ("Security" , securityDescriptor )
712+ if err != nil {
713+ return fmt .Errorf ("Failed to set registry key: %s" , err )
714+ }
715+
716+ filePath , err := os .Executable ()
717+ if err != nil {
718+ return fmt .Errorf ("Failed to get current file path: %s" , err )
719+ }
720+
721+ err = k .SetStringValue ("Executable" , filePath )
722+ if err != nil {
723+ return fmt .Errorf ("Failed to set registry key: %s" , err )
724+ }
725+
726+ err = k .SetDWordValue ("JobControl" , 1 )
727+ if err != nil {
728+ return fmt .Errorf ("Failed to set registry key: %s" , err )
729+ }
730+
731+ logger .Debug ("Starting juicefs service." )
732+ cmd := exec .Command ("net" , "use" , mountpoint , "\\ \\ juicefs\\ " + name )
733+ err = cmd .Run ()
734+ if err != nil {
735+ return fmt .Errorf ("Failed to mount juicefs: %s" , err )
736+ }
737+
738+ logger .Info ("Juicefs system service started successfully." )
739+ return nil
740+ }
0 commit comments