본문 바로가기
개발/WIN32-MFC

[ WIN ] RunAsUserOrAdmin

by -=HaeJuK=- 2024. 4. 22.
반응형
class cRunProc
{
	DECLARE_NO_SELF_CLASS( cRunProc );

public:
	enum class eRunOption {
		eAsUser,
		eAsAdmin
	};

	static bool RunAsAdmin( const std::wstring& _ssPath, const std::wstring& _ssParameters, DWORD _nWaitMilliseconds )
	{
		SHELLEXECUTEINFO sei = { sizeof( sei ) };
		sei.lpVerb = L"runas";
		sei.lpFile = _ssPath.c_str();
		sei.lpParameters = _ssParameters.c_str();
		sei.hwnd = NULL;
		sei.nShow = SW_NORMAL;

		if( FALSE == ShellExecuteEx( &sei ) ) 
		{
			DWORD dwError = GetLastError();
			if( dwError == ERROR_CANCELLED ) 
			{
				std::wcout << L"User cancelled the operation." << std::endl;
			}
			else 
			{
				std::wcout << L"An error occurred: " << dwError << std::endl;
			}
			return false;
		}

		if( sei.hProcess != NULL ) 
		{
			WaitForSingleObject( sei.hProcess, _nWaitMilliseconds );
			CloseHandle( sei.hProcess );
		}
		return true;
	}

	static bool RunAsUser( const std::wstring& _ssUsername, const std::wstring& _ssDomain, const std::wstring& _ssPassword, 
		const std::wstring& _ssApplication, const std::wstring& _ssParameters, DWORD _nWaitMilliseconds )
	{
		STARTUPINFOW si = { sizeof( si ) };
		PROCESS_INFORMATION pi;
		std::wstring ssCommandLine = _ssApplication + L" " + _ssParameters;
		if( !CreateProcessWithLogonW( _ssUsername.c_str(), _ssDomain.c_str(), _ssPassword.c_str(), LOGON_WITH_PROFILE, NULL, ssCommandLine.data(), CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi ) )
		{
			std::wcerr << L"CreateProcessWithLogonW failed with error: " << GetLastError() << std::endl;
			return false;
		}

		WaitForSingleObject( pi.hProcess, _nWaitMilliseconds );
		CloseHandle( pi.hProcess );
		CloseHandle( pi.hThread );
		return true;
	}

	static void ExecuteProcess( const std::wstring& _ssPath, eRunOption _eOption, const std::wstring& _ssParameters, int _nWaitSeconds = 0 )
	{
		DWORD nWaitMilliseconds = (_nWaitSeconds > 0) ? _nWaitSeconds * 1000 : INFINITE;
		bool bResult = false;

		switch( _eOption )
		{
		case eRunOption::eAsAdmin:
			bResult = RunAsAdmin( _ssPath, _ssParameters, nWaitMilliseconds );
			break;
		case eRunOption::eAsUser:
			bResult = RunAsUser( L"username", L"domain", L"password", _ssPath, _ssParameters, _nWaitSeconds );
			break;
		}

		if( bResult )
		{
			std::wcout << L"Process executed successfully." << std::endl;
		}
		else
		{
			std::wcout << L"Failed to execute process." << std::endl;
		}
	}
};
#include "cRunProc.h"
int Test() 
{
	std::wstring path = L"C:\\Path\\To\\YourApplication.exe";
	std::wstring parameters = L"\"Argument With Spaces\" \"Another Argument\"";
	cRunProc::ExecuteProcess( path, eRunOption::eAsAdmin, parameters, 10 );  // Run as admin and wait 10 seconds
	return 0;
}
반응형