检查Steam是否正在运行且用户是否已登录

时间:2016-04-15 14:11:44

标签: c# steam

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

我甚至不需要代码示例,我只需要提示正确的方向以及从哪里开始。我听说过Steam本身的OpenID实现,但我不知道它是不是一个合适的起点。

感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

我知道这是一个有点老问题,但我偶然发现它自己寻找答案。我已经找到了一种方法,虽然它是在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);
    }
}

答案 1 :(得分:0)

I assume you're using this for a game, if I am correct you need the steamworks sdk from valve. The only way you can get the official SDK is by passing the greenlight process on steam. You can however use this, https://steamworks.github.io/ . Hope this helps you.