mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-21 13:54:15 -07:00
Windows service work, remove old installer... not sure exactly what we're going to use.
This commit is contained in:
parent
6d17993eb6
commit
8a7486577a
7 changed files with 255 additions and 6109 deletions
|
@ -42,20 +42,21 @@
|
|||
// NOTE: If the function fails to install the service, it prints the error
|
||||
// in the standard output stream for users to diagnose the problem.
|
||||
//
|
||||
void InstallService(PSTR pszServiceName,
|
||||
std::string InstallService(PSTR pszServiceName,
|
||||
PSTR pszDisplayName,
|
||||
DWORD dwStartType,
|
||||
PSTR pszDependencies,
|
||||
PSTR pszAccount,
|
||||
PSTR pszPassword)
|
||||
{
|
||||
std::string ret;
|
||||
char szPath[MAX_PATH];
|
||||
SC_HANDLE schSCManager = NULL;
|
||||
SC_HANDLE schService = NULL;
|
||||
|
||||
if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)) == 0)
|
||||
{
|
||||
wprintf(L"GetModuleFileName failed w/err 0x%08lx\n", GetLastError());
|
||||
ret = "GetModuleFileName failed, unable to get path to self";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -64,7 +65,7 @@ void InstallService(PSTR pszServiceName,
|
|||
SC_MANAGER_CREATE_SERVICE);
|
||||
if (schSCManager == NULL)
|
||||
{
|
||||
wprintf(L"OpenSCManager failed w/err 0x%08lx\n", GetLastError());
|
||||
ret = "OpenSCManager failed";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -86,12 +87,10 @@ void InstallService(PSTR pszServiceName,
|
|||
);
|
||||
if (schService == NULL)
|
||||
{
|
||||
wprintf(L"CreateService failed w/err 0x%08lx\n", GetLastError());
|
||||
ret = "CreateService failed";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
wprintf(L"%s is installed.\n", pszServiceName);
|
||||
|
||||
Cleanup:
|
||||
// Centralized cleanup for all allocated resources.
|
||||
if (schSCManager)
|
||||
|
@ -104,6 +103,8 @@ Cleanup:
|
|||
CloseServiceHandle(schService);
|
||||
schService = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,8 +120,9 @@ Cleanup:
|
|||
// NOTE: If the function fails to uninstall the service, it prints the
|
||||
// error in the standard output stream for users to diagnose the problem.
|
||||
//
|
||||
void UninstallService(PSTR pszServiceName)
|
||||
std::string UninstallService(PSTR pszServiceName)
|
||||
{
|
||||
std::string ret;
|
||||
SC_HANDLE schSCManager = NULL;
|
||||
SC_HANDLE schService = NULL;
|
||||
SERVICE_STATUS ssSvcStatus = {};
|
||||
|
@ -129,7 +131,7 @@ void UninstallService(PSTR pszServiceName)
|
|||
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
|
||||
if (schSCManager == NULL)
|
||||
{
|
||||
wprintf(L"OpenSCManager failed w/err 0x%08lx\n", GetLastError());
|
||||
ret = "OpenSCManager failed";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -138,45 +140,32 @@ void UninstallService(PSTR pszServiceName)
|
|||
SERVICE_QUERY_STATUS | DELETE);
|
||||
if (schService == NULL)
|
||||
{
|
||||
wprintf(L"OpenService failed w/err 0x%08lx\n", GetLastError());
|
||||
ret = "OpenService failed (is service installed?)";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Try to stop the service
|
||||
if (ControlService(schService, SERVICE_CONTROL_STOP, &ssSvcStatus))
|
||||
{
|
||||
wprintf(L"Stopping %s.", pszServiceName);
|
||||
Sleep(1000);
|
||||
Sleep(500);
|
||||
|
||||
while (QueryServiceStatus(schService, &ssSvcStatus))
|
||||
{
|
||||
if (ssSvcStatus.dwCurrentState == SERVICE_STOP_PENDING)
|
||||
{
|
||||
wprintf(L".");
|
||||
Sleep(1000);
|
||||
Sleep(500);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
if (ssSvcStatus.dwCurrentState == SERVICE_STOPPED)
|
||||
{
|
||||
wprintf(L"\n%s is stopped.\n", pszServiceName);
|
||||
}
|
||||
else
|
||||
{
|
||||
wprintf(L"\n%s failed to stop.\n", pszServiceName);
|
||||
}
|
||||
}
|
||||
|
||||
// Now remove the service by calling DeleteService.
|
||||
if (!DeleteService(schService))
|
||||
{
|
||||
wprintf(L"DeleteService failed w/err 0x%08lx\n", GetLastError());
|
||||
ret = "DeleteService failed (is service running?)";
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
wprintf(L"%s is removed.\n", pszServiceName);
|
||||
|
||||
Cleanup:
|
||||
// Centralized cleanup for all allocated resources.
|
||||
if (schSCManager)
|
||||
|
@ -189,4 +178,6 @@ Cleanup:
|
|||
CloseServiceHandle(schService);
|
||||
schService = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
//
|
||||
// FUNCTION: InstallService
|
||||
|
@ -38,7 +39,8 @@
|
|||
// NOTE: If the function fails to install the service, it prints the error
|
||||
// in the standard output stream for users to diagnose the problem.
|
||||
//
|
||||
void InstallService(PSTR pszServiceName,
|
||||
// modified for ZT1 to return an error or empty string on success
|
||||
std::string InstallService(PSTR pszServiceName,
|
||||
PSTR pszDisplayName,
|
||||
DWORD dwStartType,
|
||||
PSTR pszDependencies,
|
||||
|
@ -58,4 +60,5 @@ void InstallService(PSTR pszServiceName,
|
|||
// NOTE: If the function fails to uninstall the service, it prints the
|
||||
// error in the standard output stream for users to diagnose the problem.
|
||||
//
|
||||
void UninstallService(PSTR pszServiceName);
|
||||
// Also modified to return rather than print errors
|
||||
std::string UninstallService(PSTR pszServiceName);
|
||||
|
|
|
@ -27,29 +27,81 @@
|
|||
|
||||
#pragma region Includes
|
||||
#include "ZeroTierOneService.h"
|
||||
#include "../../node/Node.hpp"
|
||||
#include "../../node/Defaults.hpp"
|
||||
#include "../../node/Thread.hpp"
|
||||
#pragma endregion
|
||||
|
||||
using namespace ZeroTier;
|
||||
|
||||
ZeroTierOneService::ZeroTierOneService() :
|
||||
CServiceBase(ZT_SERVICE_NAME,TRUE,TRUE,TRUE)
|
||||
CServiceBase(ZT_SERVICE_NAME,TRUE,TRUE,FALSE),
|
||||
_thread(new Thread()),
|
||||
_node((Node *)0)
|
||||
{
|
||||
}
|
||||
|
||||
ZeroTierOneService::~ZeroTierOneService(void)
|
||||
{
|
||||
delete _thread;
|
||||
delete _node;
|
||||
}
|
||||
|
||||
void ZeroTierOneService::threadMain()
|
||||
throw()
|
||||
{
|
||||
try {
|
||||
// Since Windows doesn't auto-restart services, we'll restart the node
|
||||
// on normal termination.
|
||||
for(;;) {
|
||||
switch(_node->run()) {
|
||||
case Node::NODE_NORMAL_TERMINATION:
|
||||
delete _node;
|
||||
_node = new Node(ZT_DEFAULTS.defaultHomePath.c_str(),0,0);
|
||||
break; // restart
|
||||
case Node::NODE_RESTART_FOR_UPGRADE: {
|
||||
} return; // terminate thread
|
||||
case Node::NODE_UNRECOVERABLE_ERROR: {
|
||||
std::string err("unrecoverable error: ");
|
||||
const char *r = _node->reasonForTermination;
|
||||
if (r)
|
||||
err.append(r);
|
||||
else err.append("(unknown error)");
|
||||
WriteEventLogEntry(const_cast <PSTR>(err.c_str()),EVENTLOG_ERROR_TYPE);
|
||||
} return; // terminate thread
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch ( ... ) {
|
||||
WriteEventLogEntry("unexpected exception in Node::run() or during restart",EVENTLOG_ERROR_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroTierOneService::OnStart(DWORD dwArgc, LPSTR *lpszArgv)
|
||||
{
|
||||
try {
|
||||
_node = new Node(ZT_DEFAULTS.defaultHomePath.c_str(),0,0);
|
||||
*_thread = Thread::start(this);
|
||||
} catch ( ... ) {
|
||||
// shouldn't happen unless something weird occurs like out of memory...
|
||||
throw (DWORD)ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroTierOneService::OnStop()
|
||||
{
|
||||
Node *n = _node;
|
||||
_node = (Node *)0;
|
||||
if (n) {
|
||||
n->terminate(Node::NODE_NORMAL_TERMINATION,"Service Shutdown");
|
||||
Thread::join(*_thread);
|
||||
delete n;
|
||||
}
|
||||
}
|
||||
|
||||
void ZeroTierOneService::OnPause()
|
||||
{
|
||||
}
|
||||
|
||||
void ZeroTierOneService::OnContinue()
|
||||
void ZeroTierOneService::OnShutdown()
|
||||
{
|
||||
// make sure it's stopped
|
||||
OnStop();
|
||||
}
|
||||
|
|
|
@ -36,15 +36,29 @@
|
|||
#define ZT_SERVICE_ACCOUNT "NT AUTHORITY\\LocalService"
|
||||
#define ZT_SERVICE_PASSWORD NULL
|
||||
|
||||
namespace ZeroTier {
|
||||
class Node;
|
||||
class Thread;
|
||||
} // namespace ZeroTier
|
||||
|
||||
class ZeroTierOneService : public CServiceBase
|
||||
{
|
||||
public:
|
||||
ZeroTierOneService();
|
||||
virtual ~ZeroTierOneService(void);
|
||||
|
||||
/**
|
||||
* Thread main method; do not call elsewhere
|
||||
*/
|
||||
void threadMain()
|
||||
throw();
|
||||
|
||||
protected:
|
||||
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
|
||||
virtual void OnStop();
|
||||
virtual void OnPause();
|
||||
virtual void OnContinue();
|
||||
virtual void OnShutdown();
|
||||
|
||||
private:
|
||||
ZeroTier::Node *volatile _node;
|
||||
ZeroTier::Thread *volatile _thread;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,37 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<!-- Select a Product Configuration -->
|
||||
<InstallShieldProductConfiguration>Express</InstallShieldProductConfiguration>
|
||||
<!-- Select a Visual Studio Configuration / InstallShield Release -->
|
||||
<Configuration>Debug</Configuration>
|
||||
<InstallShieldRelease>$(Configuration)</InstallShieldRelease>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- The InstallShieldProject item selects the project to build -->
|
||||
<InstallShieldProject Include="$(MSBuildProjectDirectory)\$(MSBuildProjectName).isl"/>
|
||||
<!-- The InstallShieldReleaseFlags sets Release Flags -->
|
||||
<!--<InstallShieldReleaseFlags Include=""/>-->
|
||||
<!-- The InstallShieldMergeModulePath specifies what directories are
|
||||
searched for Merge Modules -->
|
||||
<!--<InstallShieldMergeModulePath Include=""/>-->
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- The ProjectReference items refer to any Visual Studio solutions you want to automatically probe for Project Output Groups. -->
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- The TaggedOutputs items allow you to explicitly add extra files to output groups. Each item must include both Name and OutputGroup, as well as TargetPath metadata values. -->
|
||||
<!--<TaggedOutputs Include="C:\My Test Exe.exe">
|
||||
<Name>My Test Project</Name>
|
||||
<OutputGroup>Primary output</OutputGroup>
|
||||
<TargetPath>My Test Exe.exe</TargetPath>
|
||||
</TaggedOutputs> -->
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\InstallShield\2013Limited\InstallShield.targets"/>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ZeroTierOneService\ZeroTierOneService.csproj">
|
||||
<Name>ZeroTierOneService</Name>
|
||||
<Project>{63D28112-9A56-42FA-9C3E-EF6C58AF09B3}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Add table
Add a link
Reference in a new issue