@@ -17,7 +17,7 @@ import (
17
17
)
18
18
19
19
const (
20
- serviceName = "discordfix_zapret "
20
+ serviceName = "zapret_by_ankddev "
21
21
clearScreenSequence = "\033 [2J\033 [H\033 [3J"
22
22
defaultTermHeight = 24
23
23
enterAltScreen = "\033 [?1049h"
@@ -60,67 +60,90 @@ func (sm *ServiceManager) runPowershellCommand(command string) (string, error) {
60
60
}
61
61
62
62
func (sm * ServiceManager ) removeService () error {
63
- fmt .Println ("=== Deleting existing service ===" )
64
-
65
- // Stop service
66
- fmt .Printf ("► Stopping service '%s'...\n " , sm .serviceName )
67
- _ , err := sm .runPowershellCommand (fmt .Sprintf ("Start-Process 'sc.exe' -ArgumentList 'stop %s' -Verb RunAs" , sm .serviceName ))
68
- if err != nil {
69
- fmt .Printf ("%s⚠ Error while stopping service: %v%s\n " , colorRed , err , colorReset )
70
- } else {
71
- fmt .Printf ("%s✓ Service stopped successfully.%s\n " , colorGreen , colorReset )
72
- }
73
-
74
- // Terminate process
75
- fmt .Println ("► Shutting down process 'winws.exe'..." )
76
- _ , err = sm .runPowershellCommand ("Start-Process 'powershell' -ArgumentList 'Stop-Process -Name \" winws\" -Force' -Verb RunAs" )
63
+ fmt .Println ("=== Removing existing service using nssm remove ===" )
64
+ nssmPath := filepath .Join ("bin" , "nssm.exe" )
65
+
66
+ // Attempt to stop the service; ignore errors.
67
+ stopCmd := exec .Command (nssmPath , "stop" , sm .serviceName )
68
+ stopCmd .Stdout = os .Stdout
69
+ stopCmd .Stderr = os .Stderr
70
+ _ = stopCmd .Run ()
71
+ time .Sleep (2 * time .Second )
72
+
73
+ // Attempt service removal.
74
+ removeCmd := exec .Command (nssmPath , "remove" , sm .serviceName , "confirm" )
75
+ removeCmd .Stdout = nil
76
+ removeCmd .Stderr = nil
77
+ err := removeCmd .Run ()
77
78
if err != nil {
78
- fmt .Printf ("%s⚠ Error while terminating process: %v%s\n " , colorRed , err , colorReset )
79
- } else {
80
- fmt .Printf ("%s✓ Process terminated successfully.%s\n " , colorGreen , colorReset )
81
- }
82
-
83
- // Delete service
84
- fmt .Printf ("► Deleting service '%s'...\n " , sm .serviceName )
85
- _ , err = sm .runPowershellCommand (fmt .Sprintf ("Start-Process 'sc.exe' -ArgumentList 'delete %s' -Verb RunAs" , sm .serviceName ))
86
- if err != nil {
87
- fmt .Printf ("%s⚠ Error while deleting service: %v%s\n " , colorRed , err , colorReset )
79
+ errMsg := err .Error ()
80
+ // If error indicates the service is not present or exit status 3, ignore it.
81
+ if strings .Contains (errMsg , "Указанная служба не установлена" ) ||
82
+ strings .Contains (strings .ToLower (errMsg ), "not found" ) ||
83
+ strings .Contains (errMsg , "marked for deletion" ) ||
84
+ strings .Contains (errMsg , "can't open service" ) ||
85
+ strings .Contains (errMsg , "exit status 3" ) {
86
+ fmt .Println ("Service not found or already marked for deletion; continuing..." )
87
+ err = nil
88
+ } else {
89
+ fmt .Printf ("%s⚠ Error while removing service via nssm: %v%s\n " , colorRed , err , colorReset )
90
+ return err
91
+ }
88
92
} else {
89
- fmt .Printf ("%s✓ Service deleted successfully.%s\n " , colorGreen , colorReset )
93
+ fmt .Printf ("%s✓ Service removed successfully via nssm .%s\n " , colorGreen , colorReset )
90
94
}
91
-
95
+ // Allow extra time for Windows to complete deletion.
96
+ time .Sleep (3 * time .Second )
92
97
return nil
93
98
}
94
99
95
100
func (sm * ServiceManager ) installService (batFilePath string ) error {
96
- // First remove existing service
97
- err := sm .removeService ()
98
- if err != nil {
99
- return err
100
- }
101
+ // Remove the service and wait until it's fully gone.
102
+ _ = sm .removeService ()
103
+ nssmPath := filepath .Join ("bin" , "nssm.exe" )
104
+ _ = exec .Command (nssmPath , "status" , sm .serviceName ).Run ()
101
105
102
106
fmt .Println ("=== Installing new service ===" )
103
107
fmt .Printf ("► Installing file as service: %s\n " , batFilePath )
104
108
105
- // Create service
106
- createCmd := fmt .Sprintf (
107
- `$process = Start-Process 'sc.exe' -ArgumentList 'create %s binPath= "cmd.exe /c \"%s\"" start= auto' -Verb RunAs -PassThru; $process.WaitForExit(); Write-Output $process.ExitCode` ,
108
- sm .serviceName ,
109
- batFilePath ,
110
- )
109
+ _ = exec .Command (nssmPath , "install" , sm .serviceName , "cmd.exe" , "/c" , batFilePath ).Run ()
111
110
112
- _ , err = sm .runPowershellCommand (createCmd )
113
- if err != nil {
114
- fmt .Printf ("%s⚠ Error while creating service: %v%s\n " , colorRed , err , colorReset )
115
- return err
116
- }
111
+ time .Sleep (3 * time .Second )
112
+
113
+ // Configure NSSM to ignore exit code 1 to avoid SERVICE_PAUSED issues.
114
+ setExitCmd := exec .Command (nssmPath , "set" , sm .serviceName , "AppExit" , "1" , "Ignore" )
115
+ setExitCmd .Stdout = os .Stdout
116
+ setExitCmd .Stderr = os .Stderr
117
+ _ = setExitCmd .Run ()
117
118
118
- // Start service
119
+ // Set AppRestartDelay to 5000 milliseconds.
120
+ setDelayCmd := exec .Command (nssmPath , "set" , sm .serviceName , "AppRestartDelay" , "5000" )
121
+ setDelayCmd .Stdout = os .Stdout
122
+ setDelayCmd .Stderr = os .Stderr
123
+ _ = setDelayCmd .Run ()
124
+
125
+ // Start the service.
119
126
fmt .Println ("► Starting service..." )
120
- _ , err = sm .runPowershellCommand (fmt .Sprintf ("Start-Process 'sc.exe' -ArgumentList 'start %s' -Verb RunAs" , sm .serviceName ))
127
+ startCmd := exec .Command (nssmPath , "start" , sm .serviceName )
128
+ startCmd .Stdout = os .Stdout
129
+ startCmd .Stderr = os .Stderr
130
+ err := startCmd .Run ()
121
131
if err != nil {
122
- fmt .Printf ("%s⚠ Error while starting service: %v%s\n " , colorRed , err , colorReset )
123
- return err
132
+ errMsg := strings .ToLower (err .Error ())
133
+ if strings .Contains (errMsg , "service_paused" ) {
134
+ fmt .Println ("Service is paused; attempting restart via nssm restart..." )
135
+ restartCmd := exec .Command (nssmPath , "restart" , sm .serviceName )
136
+ restartCmd .Stdout = os .Stdout
137
+ restartCmd .Stderr = os .Stderr
138
+ err = restartCmd .Run ()
139
+ if err != nil {
140
+ fmt .Printf ("%s⚠ Error while restarting service via nssm: %v%s\n " , colorRed , err , colorReset )
141
+ return err
142
+ }
143
+ } else {
144
+ fmt .Printf ("%s⚠ Error while starting service via nssm: %v%s\n " , colorRed , err , colorReset )
145
+ return err
146
+ }
124
147
}
125
148
126
149
fmt .Printf ("%s✓ Service started successfully.%s\n " , colorGreen , colorReset )
@@ -348,46 +371,3 @@ func max(a, b int) int {
348
371
}
349
372
return b
350
373
}
351
-
352
- func (sm * ServiceManager ) createService () error {
353
- fmt .Println ("=== Creating service ===" )
354
-
355
- // Get absolute path to executable
356
- exePath , err := sm .getExecutablePath ()
357
- if err != nil {
358
- return err
359
- }
360
-
361
- // Create service with auto-start
362
- _ , err = sm .runPowershellCommand (fmt .Sprintf ("Start-Process 'sc.exe' -ArgumentList 'create %s start= auto binPath= \" %s\" ' -Verb RunAs" , sm .serviceName , exePath ))
363
- if err != nil {
364
- return fmt .Errorf ("error creating service: %v" , err )
365
- }
366
- fmt .Printf ("%s✓ Service created successfully.%s\n " , colorGreen , colorReset )
367
-
368
- // Set description
369
- _ , err = sm .runPowershellCommand (fmt .Sprintf ("Start-Process 'sc.exe' -ArgumentList 'description %s \" Service for bypassing DPI blocks\" ' -Verb RunAs" , sm .serviceName ))
370
- if err != nil {
371
- fmt .Printf ("%s⚠ Error setting service description: %v%s\n " , colorRed , err , colorReset )
372
- } else {
373
- fmt .Printf ("%s✓ Service description set.%s\n " , colorGreen , colorReset )
374
- }
375
-
376
- // Configure service recovery options
377
- _ , err = sm .runPowershellCommand (fmt .Sprintf ("Start-Process 'sc.exe' -ArgumentList 'failure %s reset= 0 actions= restart/60000' -Verb RunAs" , sm .serviceName ))
378
- if err != nil {
379
- fmt .Printf ("%s⚠ Error setting service recovery options: %v%s\n " , colorRed , err , colorReset )
380
- } else {
381
- fmt .Printf ("%s✓ Service recovery options set.%s\n " , colorGreen , colorReset )
382
- }
383
-
384
- return nil
385
- }
386
-
387
- func (sm * ServiceManager ) getExecutablePath () (string , error ) {
388
- currentDir , err := os .Getwd ()
389
- if err != nil {
390
- return "" , err
391
- }
392
- return filepath .Join (currentDir , "bin" , "winws.exe" ), nil
393
- }
0 commit comments