2016-04-15 205 views
-2

简而言之,我想检查Steam是否正在运行并且用户已登录。我只能找到关于web-api的文档,这将是启动I认为。检查Steam是否正在运行并且用户已登录

我甚至不需要代码示例,我只需要提示正确的方向以及从何处开始。我听说Steam中有一个OpenID实现,但我不知道它是否是正确的开始。

任何帮助表示赞赏!

+0

Im肯定登录表单的过程不同于主之一。所以只需检查是否正确运行。如果没有,请检查窗口名称。你也可以检查是否有连接到蒸汽服务器。我希望你试图达到的目标是合法的。 – C4u

+0

我可以确保它当然是合法的。这将是一个Arma 3发射器,它将检查先决条件以正确启动游戏。 – chris579

+0

@ C4ud3x非法行为如何从了解蒸汽运行的基本信息以及登录进来的任何其他法律事件中受益。 – Jacobr365

回答

1

我知道这是一个稍微老的问题,但我偶然发现它自己寻找答案。我已经找到了一种方法来实现它,尽管它是用C++编写的,但它完全可以转换为C#。

伪代码

string SteamExePath = RegistryKey("HKEY_CURRENT_USER\\SOFTWARE\\Valve\\Steam\\SteamExe"); 
while RegistryKey("HKEY_CURRENT_USER\\SOFTWARE\\Valve\\Steam\\ActiveProcess\\ActiveUser") == 0 
{ 
    RegisterForRegistryChange("HKEY_CURRENT_USER\\SOFTWARE\\Valve\\Steam\\ActiveProcess"); 

    StartProcess(SteamExePath); 

    WaitForRegistryChange(); 
} 

C++代码

Util.h

#pragma once 

#include <memory> 
#include <string> 

#include "Shared.h" 

#define EXCEPTION(message, ...) throw std::runtime_error(Shared::stringFormat(Shared::stringFormat("%s: %s", __FUNCTION__, message), __VA_ARGS__)); 
#define EXCEPTION_LAST_ERROR(message, ...) throw std::runtime_error(Shared::stringFormat(Shared::stringFormat("%s: %s\nSystem error code: %u", __FUNCTION__, message, GetLastError()), __VA_ARGS__)); 
#define EXCEPTION_LAST_ERROR2(message, lastError, ...) throw std::runtime_error(Shared::stringFormat(Shared::stringFormat("%s: %s\nSystem error code: %u", __FUNCTION__, message, lastError), __VA_ARGS__)); 

namespace Shared 
{ 
    template<typename ... Args> 
    std::string stringFormat(const std::string &format, Args ...args) 
    { 
     size_t size = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; 
     std::unique_ptr<char[]> buf(new char[size]); 
     std::snprintf(buf.get(), size, format.c_str(), args...); 

     return std::string(buf.get(), buf.get() + size - 1); 
    } 

    template<typename ... Args> 
    std::wstring stringFormat(const std::wstring &format, Args ...args) 
    { 
     size_t size = std::swprintf(nullptr, 0, format.c_str(), args...) + 1; 
     std::unique_ptr<wchar_t[]> buf(new wchar_t[size]); 
     std::swprintf(buf.get(), size, format.c_str(), args...); 

     return std::wstring(buf.get(), buf.get() + size - 1); 
    } 

    void getExecutionPath(std::wstring &path); 
} 

Process.h

#pragma once 

#include <Windows.h> 
#include <string> 

namespace Shared 
{ 
    class Process 
    { 
     public: 
      Process(
       const std::wstring &path, 
       const std::wstring &arguments, 
       LPSECURITY_ATTRIBUTES processAttributes, 
       LPSECURITY_ATTRIBUTES threadAttributes, 
       bool inheritHandles, 
       DWORD creationFlags, 
       LPVOID environment, 
       const std::wstring &currentDirectory, 
       const STARTUPINFOEXW &startupInfo); 
      Process(
       const std::wstring &&path, 
       const std::wstring &&arguments, 
       LPSECURITY_ATTRIBUTES processAttributes, 
       LPSECURITY_ATTRIBUTES threadAttributes, 
       bool inheritHandles, 
       DWORD creationFlags, 
       LPVOID environment, 
       const std::wstring &&currentDirectory, 
       const STARTUPINFOEXW &startupInfo); 
      Process(
       const std::wstring &&path, 
       const std::wstring &arguments, 
       LPSECURITY_ATTRIBUTES processAttributes, 
       LPSECURITY_ATTRIBUTES threadAttributes, 
       bool inheritHandles, 
       DWORD creationFlags, 
       LPVOID environment, 
       const std::wstring &currentDirectory, 
       const STARTUPINFOEXW &startupInfo); 
      Process(
       const std::wstring &path, 
       const std::wstring &&arguments, 
       LPSECURITY_ATTRIBUTES processAttributes, 
       LPSECURITY_ATTRIBUTES threadAttributes, 
       bool inheritHandles, 
       DWORD creationFlags, 
       LPVOID environment, 
       const std::wstring &currentDirectory, 
       const STARTUPINFOEXW &startupInfo); 
      Process(
       const std::wstring &path, 
       const std::wstring &arguments, 
       LPSECURITY_ATTRIBUTES processAttributes, 
       LPSECURITY_ATTRIBUTES threadAttributes, 
       bool inheritHandles, 
       DWORD creationFlags, 
       LPVOID environment, 
       const std::wstring &&currentDirectory, 
       const STARTUPINFOEXW &startupInfo); 
      Process(
       const std::wstring &&path, 
       const std::wstring &&arguments, 
       LPSECURITY_ATTRIBUTES processAttributes, 
       LPSECURITY_ATTRIBUTES threadAttributes, 
       bool inheritHandles, 
       DWORD creationFlags, 
       LPVOID environment, 
       const std::wstring &currentDirectory, 
       const STARTUPINFOEXW &startupInfo); 
      Process(
       const std::wstring &path, 
       const std::wstring &&arguments, 
       LPSECURITY_ATTRIBUTES processAttributes, 
       LPSECURITY_ATTRIBUTES threadAttributes, 
       bool inheritHandles, 
       DWORD creationFlags, 
       LPVOID environment, 
       const std::wstring &&currentDirectory, 
       const STARTUPINFOEXW &startupInfo); 
      Process(
       const std::wstring &&path, 
       const std::wstring &arguments, 
       LPSECURITY_ATTRIBUTES processAttributes, 
       LPSECURITY_ATTRIBUTES threadAttributes, 
       bool inheritHandles, 
       DWORD creationFlags, 
       LPVOID environment, 
       const std::wstring &&currentDirectory, 
       const STARTUPINFOEXW &startupInfo); 
      Process(Process &&other); 
      ~Process(); 

      void create(); 
      void terminate(UINT exitCode); 
      bool awaitTermination(DWORD milliseconds, DWORD &exitCode); 
      void resume(); 

      inline bool awaitTermination(DWORD milliseconds) 
      { 
       DWORD exitCode; 

       return awaitTermination(milliseconds, exitCode); 
      } 

      inline bool isCreated() const 
      { 
       return this->created; 
      } 

      inline const std::wstring &getPath() const 
      { 
       return this->path; 
      } 

      inline const std::wstring &getArguments() const 
      { 
       return this->arguments; 
      } 

      inline const LPSECURITY_ATTRIBUTES getProcessAttributes() const 
      { 
       return this->processAttributes; 
      } 

      inline const LPSECURITY_ATTRIBUTES getThreadAttributes() const 
      { 
       return this->threadAttributes; 
      } 

      inline bool getInheritHandles() const 
      { 
       return this->inheritHandles; 
      } 

      inline DWORD getCreationFlags() const 
      { 
       return this->creationFlags; 
      } 

      inline const LPVOID getEnvironment() const 
      { 
       return this->environment; 
      } 

      inline const std::wstring &getCurrentDirectory() const 
      { 
       return this->currentDirectory; 
      } 

      inline const STARTUPINFOEXW &getStartupInfo() const 
      { 
       return this->startupInfo; 
      } 

      inline const PROCESS_INFORMATION &getProcessInformation() const 
      { 
       return this->processInformation; 
      } 

      inline DWORD getProcessId() const 
      { 
       return this->processInformation.dwProcessId; 
      } 

      inline DWORD getThreadId() const 
      { 
       return this->processInformation.dwThreadId; 
      } 

      inline HANDLE getProcessHandle() const 
      { 
       return this->processInformation.hProcess; 
      } 

      inline HANDLE getThreadHandle() const 
      { 
       return this->processInformation.hThread; 
      } 

     private: 
      Process(const Process &other) = delete; 
      Process &operator=(const Process &other) = delete; 
      Process &operator=(const Process &&other) = delete; 

      void init(LPSECURITY_ATTRIBUTES processAttributes, LPSECURITY_ATTRIBUTES threadAttributes); 
      void cleanup(); 

      bool created; 
      std::wstring path; 
      std::wstring arguments; 
      LPSECURITY_ATTRIBUTES processAttributes; 
      LPSECURITY_ATTRIBUTES threadAttributes; 
      bool inheritHandles; 
      DWORD creationFlags; 
      LPVOID environment; 
      std::wstring currentDirectory; 
      STARTUPINFOEXW startupInfo; 
      PROCESS_INFORMATION processInformation; 
    }; 
} 

Process.cpp

#include "stdafx.h" 
#include "Process.h" 

#include "Util.h" 

namespace Shared 
{ 
    Process::Process(
     const std::wstring &path, 
     const std::wstring &arguments, 
     LPSECURITY_ATTRIBUTES processAttributes, 
     LPSECURITY_ATTRIBUTES threadAttributes, 
     bool inheritHandles, 
     DWORD creationFlags, 
     LPVOID environment, 
     const std::wstring &currentDirectory, 
     const STARTUPINFOEXW &startupInfo) : 
     created(false), 
     path(path), 
     arguments(arguments), 
     processAttributes(NULL), 
     threadAttributes(NULL), 
     inheritHandles(inheritHandles), 
     creationFlags(creationFlags), 
     environment(environment), 
     currentDirectory(currentDirectory), 
     startupInfo(startupInfo), 
     processInformation() 
    { 
     init(processAttributes, threadAttributes); 
    } 

    Process::Process(
     const std::wstring &&path, 
     const std::wstring &&arguments, 
     LPSECURITY_ATTRIBUTES processAttributes, 
     LPSECURITY_ATTRIBUTES threadAttributes, 
     bool inheritHandles, 
     DWORD creationFlags, 
     LPVOID environment, 
     const std::wstring &&currentDirectory, 
     const STARTUPINFOEXW &startupInfo) : 
     created(false), 
     path(std::forward<const std::wstring>(path)), 
     arguments(std::forward<const std::wstring>(arguments)), 
     processAttributes(NULL), 
     threadAttributes(NULL), 
     inheritHandles(inheritHandles), 
     creationFlags(creationFlags), 
     environment(environment), 
     currentDirectory(std::forward<const std::wstring>(currentDirectory)), 
     startupInfo(startupInfo), 
     processInformation() 
    { 
     init(processAttributes, threadAttributes); 
    } 

    Process::Process(
     const std::wstring &&path, 
     const std::wstring &arguments, 
     LPSECURITY_ATTRIBUTES processAttributes, 
     LPSECURITY_ATTRIBUTES threadAttributes, 
     bool inheritHandles, 
     DWORD creationFlags, 
     LPVOID environment, 
     const std::wstring &currentDirectory, 
     const STARTUPINFOEXW &startupInfo) : 
     created(false), 
     path(std::forward<const std::wstring>(path)), 
     arguments(arguments), 
     processAttributes(NULL), 
     threadAttributes(NULL), 
     inheritHandles(inheritHandles), 
     creationFlags(creationFlags), 
     environment(environment), 
     currentDirectory(currentDirectory), 
     startupInfo(startupInfo), 
     processInformation() 
    { 
     init(processAttributes, threadAttributes); 
    } 

    Process::Process(
     const std::wstring &path, 
     const std::wstring &&arguments, 
     LPSECURITY_ATTRIBUTES processAttributes, 
     LPSECURITY_ATTRIBUTES threadAttributes, 
     bool inheritHandles, 
     DWORD creationFlags, 
     LPVOID environment, 
     const std::wstring &currentDirectory, 
     const STARTUPINFOEXW &startupInfo) : 
     created(false), 
     path(path), 
     arguments(std::forward<const std::wstring>(arguments)), 
     processAttributes(NULL), 
     threadAttributes(NULL), 
     inheritHandles(inheritHandles), 
     creationFlags(creationFlags), 
     environment(environment), 
     currentDirectory(currentDirectory), 
     startupInfo(startupInfo), 
     processInformation() 
    { 
     init(processAttributes, threadAttributes); 
    } 

    Process::Process(
     const std::wstring &path, 
     const std::wstring &arguments, 
     LPSECURITY_ATTRIBUTES processAttributes, 
     LPSECURITY_ATTRIBUTES threadAttributes, 
     bool inheritHandles, 
     DWORD creationFlags, 
     LPVOID environment, 
     const std::wstring &&currentDirectory, 
     const STARTUPINFOEXW &startupInfo) : 
     created(false), 
     path(path), 
     arguments(arguments), 
     processAttributes(NULL), 
     threadAttributes(NULL), 
     inheritHandles(inheritHandles), 
     creationFlags(creationFlags), 
     environment(environment), 
     currentDirectory(std::forward<const std::wstring>(currentDirectory)), 
     startupInfo(startupInfo), 
     processInformation() 
    { 
     init(processAttributes, threadAttributes); 
    } 

    Process::Process(
     const std::wstring &&path, 
     const std::wstring &&arguments, 
     LPSECURITY_ATTRIBUTES processAttributes, 
     LPSECURITY_ATTRIBUTES threadAttributes, 
     bool inheritHandles, 
     DWORD creationFlags, 
     LPVOID environment, 
     const std::wstring &currentDirectory, 
     const STARTUPINFOEXW &startupInfo) : 
     created(false), 
     path(std::forward<const std::wstring>(path)), 
     arguments(std::forward<const std::wstring>(arguments)), 
     processAttributes(NULL), 
     threadAttributes(NULL), 
     inheritHandles(inheritHandles), 
     creationFlags(creationFlags), 
     environment(environment), 
     currentDirectory(currentDirectory), 
     startupInfo(startupInfo), 
     processInformation() 
    { 
     init(processAttributes, threadAttributes); 
    } 

    Process::Process(
     const std::wstring &path, 
     const std::wstring &&arguments, 
     LPSECURITY_ATTRIBUTES processAttributes, 
     LPSECURITY_ATTRIBUTES threadAttributes, 
     bool inheritHandles, 
     DWORD creationFlags, 
     LPVOID environment, 
     const std::wstring &&currentDirectory, 
     const STARTUPINFOEXW &startupInfo) : 
     created(false), 
     path(path), 
     arguments(std::forward<const std::wstring>(arguments)), 
     processAttributes(NULL), 
     threadAttributes(NULL), 
     inheritHandles(inheritHandles), 
     creationFlags(creationFlags), 
     environment(environment), 
     currentDirectory(std::forward<const std::wstring>(currentDirectory)), 
     startupInfo(startupInfo), 
     processInformation() 
    { 
     init(processAttributes, threadAttributes); 
    } 

    Process::Process(
     const std::wstring &&path, 
     const std::wstring &arguments, 
     LPSECURITY_ATTRIBUTES processAttributes, 
     LPSECURITY_ATTRIBUTES threadAttributes, 
     bool inheritHandles, 
     DWORD creationFlags, 
     LPVOID environment, 
     const std::wstring &&currentDirectory, 
     const STARTUPINFOEXW &startupInfo) : 
     created(false), 
     path(std::forward<const std::wstring>(path)), 
     arguments(arguments), 
     processAttributes(NULL), 
     threadAttributes(NULL), 
     inheritHandles(inheritHandles), 
     creationFlags(creationFlags), 
     environment(environment), 
     currentDirectory(std::forward<const std::wstring>(currentDirectory)), 
     startupInfo(startupInfo), 
     processInformation() 
    { 
     init(processAttributes, threadAttributes); 
    } 

    Process::Process(Process &&other) : 
     created(other.created), 
     path(other.path), 
     arguments(other.arguments), 
     processAttributes(other.processAttributes), 
     threadAttributes(other.threadAttributes), 
     inheritHandles(other.inheritHandles), 
     creationFlags(other.creationFlags), 
     environment(other.environment), 
     currentDirectory(other.currentDirectory), 
     startupInfo(other.startupInfo), 
     processInformation(other.processInformation) 
    { 
     other.processAttributes = NULL; 
     other.threadAttributes = NULL; 
     other.processInformation.hProcess = NULL; 
     other.processInformation.hThread = NULL; 
    } 

    Process::~Process() 
    { 
     if (this->processAttributes != NULL) 
     { 
      delete this->processAttributes->lpSecurityDescriptor; 
     } 

     if (this->threadAttributes != NULL) 
     { 
      delete this->threadAttributes->lpSecurityDescriptor; 
     } 

     delete this->processAttributes; 
     delete this->threadAttributes; 

     if (this->startupInfo.lpAttributeList != NULL) 
     { 
      DeleteProcThreadAttributeList(this->startupInfo.lpAttributeList); 
     } 

     if (this->created) 
     { 
      CloseHandle(this->processInformation.hProcess); 
      CloseHandle(this->processInformation.hThread); 
     } 
    } 

    void Process::create() 
    { 
     if (this->created) 
     { 
      EXCEPTION("Already created"); 
     } 

     wchar_t *arguments = NULL; 
     if (!this->arguments.empty()) 
     { 
      std::size_t argumentsLength = this->arguments.length() + 1; 
      arguments = new wchar_t[argumentsLength]; 
      ZeroMemory(arguments, argumentsLength * sizeof(wchar_t)); 
      wcscpy_s(arguments, argumentsLength, this->arguments.c_str()); 
     } 

     if (CreateProcessW(this->path.empty() ? NULL : this->path.c_str(), arguments, this->processAttributes, this->threadAttributes, this->inheritHandles, this->creationFlags, this->environment, this->currentDirectory.empty() ? NULL : this->currentDirectory.c_str(), reinterpret_cast<LPSTARTUPINFOW>(&this->startupInfo), &this->processInformation) == FALSE) 
     { 
      delete[] arguments; 

      EXCEPTION_LAST_ERROR("Failed CreateProcessW"); 
     } 

     delete[] arguments; 

     this->created = true; 
    } 

    void Process::terminate(UINT exitCode) 
    { 
     if (!this->created) 
     { 
      return; 
     } 

     if (TerminateProcess(this->processInformation.hProcess, exitCode) == FALSE) 
     { 
      EXCEPTION_LAST_ERROR("Failed TerminateProcess"); 
     } 

     cleanup(); 
    } 

    bool Process::awaitTermination(DWORD milliseconds, DWORD &exitCode) 
    { 
     if (!this->created) 
     { 
      EXCEPTION("Process not created"); 
     } 

     DWORD waitResult = WaitForSingleObject(this->processInformation.hProcess, milliseconds); 
     if (waitResult == WAIT_TIMEOUT) 
     { 
      return false; 
     } 
     else if (waitResult == WAIT_OBJECT_0) 
     { 
      DWORD eCode; 
      if (GetExitCodeProcess(this->processInformation.hProcess, &eCode) == FALSE) 
      { 
       EXCEPTION_LAST_ERROR("Failed GetExitCodeProcess"); 
      } 

      cleanup(); 

      exitCode = eCode; 

      return true; 
     } 
     else 
     { 
      EXCEPTION("Failed WaitForSingleObject\nWait result: %u", waitResult); 
     } 
    } 

    void Process::resume() 
    { 
     if (!this->created) 
     { 
      EXCEPTION("Process not created"); 
     } 

     if (ResumeThread(this->processInformation.hThread) == -1) 
     { 
      EXCEPTION_LAST_ERROR("Failed ResumeThread"); 
     } 
    } 

    void Process::init(LPSECURITY_ATTRIBUTES processAttributes, LPSECURITY_ATTRIBUTES threadAttributes) 
    { 
     if (processAttributes != NULL) 
     { 
      PSECURITY_DESCRIPTOR securityDescriptor = NULL; 
      if (processAttributes->lpSecurityDescriptor != NULL) 
      { 
       securityDescriptor = new SECURITY_DESCRIPTOR(); 
       memcpy(securityDescriptor, processAttributes->lpSecurityDescriptor, sizeof(SECURITY_DESCRIPTOR)); 
      } 

      this->processAttributes = new SECURITY_ATTRIBUTES(); 
      memcpy(this->processAttributes, processAttributes, sizeof(SECURITY_ATTRIBUTES)); 
      this->processAttributes->lpSecurityDescriptor = securityDescriptor; 
     } 

     if (threadAttributes != NULL) 
     { 
      PSECURITY_DESCRIPTOR securityDescriptor = NULL; 
      if (threadAttributes->lpSecurityDescriptor != NULL) 
      { 
       securityDescriptor = new SECURITY_DESCRIPTOR(); 
       memcpy(securityDescriptor, threadAttributes->lpSecurityDescriptor, sizeof(SECURITY_DESCRIPTOR)); 
      } 

      this->threadAttributes = new SECURITY_ATTRIBUTES(); 
      memcpy(this->threadAttributes, threadAttributes, sizeof(SECURITY_ATTRIBUTES)); 
      this->threadAttributes->lpSecurityDescriptor = securityDescriptor; 
     } 

     this->creationFlags |= EXTENDED_STARTUPINFO_PRESENT; 

     ZeroMemory(&this->processInformation, sizeof(PROCESS_INFORMATION)); 
    } 

    void Process::cleanup() 
    { 
     if (CloseHandle(this->processInformation.hProcess) == FALSE || CloseHandle(this->processInformation.hThread) == FALSE) 
     { 
      EXCEPTION_LAST_ERROR("Failed CloseHandle"); 
     } 

     ZeroMemory(&this->processInformation, sizeof(PROCESS_INFORMATION)); 

     this->created = false; 
    } 
} 

RegistryKey.h

#pragma once 

#include <Windows.h> 
#include <string> 

namespace Shared 
{ 
    class RegistryKey 
    { 
     public: 
      RegistryKey(HKEY key, const std::wstring &subKey, DWORD options, REGSAM samDesired); 
      RegistryKey(HKEY key, const std::wstring &&subKey, DWORD options, REGSAM samDesired); 
      RegistryKey(RegistryKey &&other); 
      RegistryKey &operator=(RegistryKey &&other); 
      ~RegistryKey(); 

      std::wstring getRegSZ(const std::wstring &subKey, const std::wstring &valueName) const; 
      DWORD getRegDword(const std::wstring &valueName) const; 
      void regNotifyChangeKeyValue(bool watchSubTree, DWORD notifyFilter, HANDLE eventHandle, bool asynchronous) const; 

      inline HKEY getKey() const 
      { 
       return this->key; 
      } 

      inline const std::wstring &getSubKey() const 
      { 
       return this->subKey; 
      } 

      inline DWORD getOptions() const 
      { 
       return this->options; 
      } 

      inline REGSAM getSamDesired() const 
      { 
       return this->samDesired; 
      } 

     private: 
      RegistryKey(const RegistryKey &other) = delete; 
      RegistryKey &operator=(const RegistryKey &other) = delete; 

      void init(); 
      void close(); 

      HKEY keyHandle; 
      HKEY key; 
      std::wstring subKey; 
      DWORD options; 
      REGSAM samDesired; 
    }; 
} 

RegistryKey.cpp

#include "stdafx.h" 
#include "RegistryKey.h" 

#include "Util.h" 

namespace Shared 
{ 
    RegistryKey::RegistryKey(HKEY key, const std::wstring &subKey, DWORD options, REGSAM samDesired) : 
     keyHandle(NULL), 
     key(key), 
     subKey(subKey), 
     options(options), 
     samDesired(samDesired) 
    { 
     init(); 
    } 

    RegistryKey::RegistryKey(HKEY key, const std::wstring &&subKey, DWORD options, REGSAM samDesired) : 
     keyHandle(NULL), 
     key(key), 
     subKey(std::forward<const std::wstring>(subKey)), 
     options(options), 
     samDesired(samDesired) 
    { 
     init(); 
    } 

    RegistryKey::RegistryKey(RegistryKey &&other) : 
     keyHandle(other.keyHandle), 
     key(other.key), 
     subKey(other.subKey), 
     options(other.options), 
     samDesired(other.samDesired) 
    { 
     other.keyHandle = NULL; 
    } 

    RegistryKey &RegistryKey::operator=(RegistryKey &&other) 
    { 
     close(); 

     this->keyHandle = other.keyHandle; 
     this->key = other.key; 
     this->subKey = other.subKey; 
     this->options = other.options; 
     this->samDesired = other.samDesired; 

     other.keyHandle = NULL; 

     return (*this); 
    } 

    RegistryKey::~RegistryKey() 
    { 
     try 
     { 
      close(); 
     } 
     catch (std::runtime_error) 
     { 

     } 
    } 

    std::wstring RegistryKey::getRegSZ(const std::wstring &subKey, const std::wstring &valueName) const 
    { 
     if ((this->samDesired & KEY_QUERY_VALUE) != KEY_QUERY_VALUE) 
     { 
      EXCEPTION("This registry key handle does not have KEY_QUERY_VALUE rights"); 
     } 

     std::size_t bufferSize = MAX_PATH; 
     wchar_t *buffer = new wchar_t[bufferSize]; 
     DWORD bufferByteSize = static_cast<DWORD>(bufferSize * sizeof(wchar_t)); 

     LSTATUS registryGetValueStatus = RegGetValueW(this->keyHandle, subKey.empty() ? NULL : subKey.c_str(), valueName.empty() ? NULL : valueName.c_str(), RRF_RT_REG_SZ, NULL, reinterpret_cast<LPBYTE>(buffer), &bufferByteSize); 

     while (registryGetValueStatus != ERROR_SUCCESS) 
     { 
      delete[] buffer; 

      if (registryGetValueStatus == ERROR_MORE_DATA) 
      { 
       bufferSize *= 2; 
       buffer = new wchar_t[bufferSize]; 
       bufferByteSize = static_cast<DWORD>(bufferSize * sizeof(wchar_t)); 

       registryGetValueStatus = RegGetValueW(this->keyHandle, subKey.empty() ? NULL : subKey.c_str(), valueName.empty() ? NULL : valueName.c_str(), RRF_RT_REG_SZ, NULL, reinterpret_cast<LPBYTE>(buffer), &bufferByteSize); 
      } 
      else 
      { 
       EXCEPTION("Failed RegGetValueW\nLSTATUS: %d", registryGetValueStatus); 
      } 
     } 

     std::wstring arkInstallPath(buffer); 
     delete[] buffer; 

     return arkInstallPath; 
    } 

    DWORD RegistryKey::getRegDword(const std::wstring &valueName) const 
    { 
     if ((this->samDesired & KEY_QUERY_VALUE) != KEY_QUERY_VALUE) 
     { 
      EXCEPTION("This registry key handle does not have KEY_QUERY_VALUE rights"); 
     } 

     DWORD result; 
     DWORD dataSize = sizeof(DWORD); 
     LSTATUS status = RegQueryValueExW(this->keyHandle, valueName.empty() ? NULL : valueName.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&result), &dataSize); 
     if (status != ERROR_SUCCESS) 
     { 
      EXCEPTION("Failed RegQueryValueExW\nLSTATUS: %d", status); 
     } 

     return result; 
    } 

    void RegistryKey::regNotifyChangeKeyValue(bool watchSubTree, DWORD notifyFilter, HANDLE eventHandle, bool asynchronous) const 
    { 
     if ((this->samDesired & KEY_NOTIFY) != KEY_NOTIFY) 
     { 
      EXCEPTION("This registry key handle does not have KEY_NOTIFY rights"); 
     } 

     LSTATUS result = RegNotifyChangeKeyValue(this->keyHandle, watchSubTree ? TRUE : FALSE, notifyFilter, eventHandle, asynchronous ? TRUE : FALSE); 
     if (result != ERROR_SUCCESS) 
     { 
      EXCEPTION("Failed RegNotifyChangeKeyValue\nLSTATUS: %d", result); 
     } 
    } 

    void RegistryKey::init() 
    { 
     LSTATUS registryOpenStatus = RegOpenKeyExW(this->key, this->subKey.empty() ? NULL : this->subKey.c_str(), this->options, this->samDesired, &this->keyHandle); 
     if (registryOpenStatus != ERROR_SUCCESS) 
     { 
      EXCEPTION("Failed RegOpenKeyExW\nLSTATUS: %d", registryOpenStatus); 
     } 
    } 

    void RegistryKey::close() 
    { 
     if (this->keyHandle == NULL) 
     { 
      return; 
     } 

     LSTATUS registryCloseStatus = RegCloseKey(this->keyHandle); 
     if (registryCloseStatus != ERROR_SUCCESS) 
     { 
      EXCEPTION("Failed RegCloseKey\nSystem error code: %d", registryCloseStatus); 
     } 

     this->keyHandle = NULL; 
    } 
} 

SteamClient.h

#pragma once 

#include <Windows.h> 

namespace BattleyeInjector 
{ 
    class SteamClient final 
    { 
     public: 
      SteamClient(); 

      void start(); 
      void startAndAwaitLogin(int maxTryCount); 

     private: 
      DWORD getActiveUserId(); 
    }; 
} 

SteamClient.cpp

#include "stdafx.h" 
#include "SteamClient.h" 

#include <string> 

#include <RegistryKey.h> 
#include <Process.h> 
#include <Util.h> 

namespace BattleyeInjector 
{ 
    static const HKEY STEAM_KEY = HKEY_CURRENT_USER; 

    static const std::wstring STEAM_INSTALL_PATH_SUB_KEY = L"SOFTWARE\\Valve\\Steam"; 
    static const std::wstring STEAM_INSTALL_PATH_KEY_NAME = L"SteamExe"; 

    static const std::wstring STEAM_ACTIVE_PROCESS_SUB_KEY = L"SOFTWARE\\Valve\\Steam\\ActiveProcess"; 
    static const std::wstring STEAM_ACTIVE_USER_KEY_NAME = L"ActiveUser"; 

    SteamClient::SteamClient() 
    { 

    } 

    void SteamClient::start() 
    { 
     Shared::RegistryKey registryKey(STEAM_KEY, STEAM_INSTALL_PATH_SUB_KEY, 0, KEY_READ); 
     const std::wstring steamInstallPath = registryKey.getRegSZ(L"", STEAM_INSTALL_PATH_KEY_NAME); 

     STARTUPINFOEXW startupInfo; 
     ZeroMemory(&startupInfo, sizeof(STARTUPINFOEXW)); 

     startupInfo.StartupInfo.cb = sizeof(STARTUPINFOEXW); 

     Shared::Process steamProcess(steamInstallPath, L"", NULL, NULL, false, 0, NULL, L"", startupInfo); 
     steamProcess.create(); 
    } 

    void SteamClient::startAndAwaitLogin(int maxTryCount) 
    { 
     if (maxTryCount <= 0) 
     { 
      EXCEPTION("maxTryCount is invalid"); 
     } 

     if (getActiveUserId() != 0) 
     { 
      return; 
     } 

     HANDLE eventHandle = CreateEventW(NULL, TRUE, FALSE, NULL); 
     if (eventHandle == NULL) 
     { 
      EXCEPTION_LAST_ERROR("Failed CreateEventW"); 
     } 

     try 
     { 
      Shared::RegistryKey registryKey(STEAM_KEY, STEAM_ACTIVE_PROCESS_SUB_KEY, 0, KEY_READ); 
      for (int x = 0; x < maxTryCount; x++) 
      { 
       registryKey.regNotifyChangeKeyValue(false, REG_NOTIFY_CHANGE_LAST_SET, eventHandle, true); 

       start(); 

       DWORD waitResult = WaitForSingleObject(eventHandle, INFINITE); 
       if (waitResult != WAIT_OBJECT_0) 
       { 
        EXCEPTION("Failed WaitForSingleObject\nWaitResult: %u", waitResult); 
       } 

       if (getActiveUserId() != 0) 
       { 
        return; 
       } 

       if (ResetEvent(eventHandle) == FALSE) 
       { 
        EXCEPTION_LAST_ERROR("Failed ResetEvent"); 
       } 
      } 

      EXCEPTION("Failed await login to steam"); 
     } 
     catch (...) 
     { 
      CloseHandle(eventHandle); 

      throw; 
     } 
    } 

    DWORD SteamClient::getActiveUserId() 
    { 
     Shared::RegistryKey registryKey(STEAM_KEY, STEAM_ACTIVE_PROCESS_SUB_KEY, 0, KEY_READ); 

     return registryKey.getRegDword(STEAM_ACTIVE_USER_KEY_NAME); 
    } 
} 
+0

感谢您的好的答案。我将在几天内看到它,并将其转换为C#并在此处发布结果。 – chris579

+0

@ chris579 np。我正在使用这个游戏不会自动启动蒸汽,如果没有启动蒸汽,只是简单地关闭而没有任何消息。所以我想出了这个解决方案,同时通过注册表嘿嘿。 – Neijwiert

+0

@ chris579今天我遇到了这个解决方案的问题。看起来,有时当Steam退出时,它会将这些注册表值留给它们,而不会将它们重置为0.因此,在使用此功能时请记住这一点。 – Neijwiert

0

我假设你正在使用这个游戏,如果我是正确的,你需要阀门的steamworks sdk。你可以得到官方SDK的唯一方法是通过传递绿灯过程。但是,您可以使用此,https://steamworks.github.io/。希望这可以帮助你。

+0

不是。正如在上面的评论中已经指出的那样,它是一款游戏的外部工具,所以我不会使用我已经找到的steamworks API。不过谢谢你的提示。 – chris579

+0

它不一定用于游戏,您可以将其用于任何c#应用程序。 https://github.com/rlabrecque/Steamworks.NET/tree/master/Standalone当我上次发布时,我没有看到那个分支。 – randomgui

+0

我知道,但对我来说太重了。所有示例都是为Unity编写的,文档非常小。 – chris579