编程开启远程桌面

如何使用编程的方法开启远程桌面:

一、使用注册表,程序中自然可以使用修改注册表的方法

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\

fDenyTSConnection (REG_DWORD) 从1改为0

1、表示禁用

0、表示启用

但这种方式有些限制,比如修改注册表需要管理员权限,修改后重启远程计算机等,还需要将远程桌面添加到防火墙例外。

 

二、使用wmi 脚本(交合时的方法)

查找当前设定:

wmic RDToggle get AllowTSConnections

设置Terminal Services 设定

wmic RDToggle where servername=”ServerName" call SetAllowTSConnections 1

 

远程计算机的设定:

wmic /node:"RemoteServer" /user:"domain\AdminUser" /password:"password"
RDToggle where servername="RemoteServer" get AllowTSConnections

开启远程计算机的设定:

wmic /node:"RemoteServer" /user:"domain\AdminUser" /password:"password"
RDToggle where servername="RemoteServer" call SetAllowTSConnections 1

wmic PATH win32_terminalservicesetting WHERE (__Class!="") CALL
SetAllowTSConnections 1

 

三、使用VC++

1) Header

You need to add the following references and #include statements to compile correctly.

#define _WIN32_DCOM
#include
using namespace std;
#include
# pragma comment(lib, "wbemuuid.lib")
2) Initialize COM

Because WMI is based on COM technology, you must perform calls to the CoInitializeExand CoInitializeSecurity functions to access WMI.

// Initialize COM.
hr =  CoInitializeEx(0, COINIT_MULTITHREADED);
if (SUCCEEDED(hr))
{
    // Initialize Security
    hr =  CoInitializeSecurity(
        NULL,
        -1,      // COM negotiates service
        NULL,    // Authentication services
        NULL,    // Reserved
        RPC_C_AUTHN_LEVEL_PKT_PRIVACY,    // authentication
        RPC_C_IMP_LEVEL_IMPERSONATE,  // Impersonation
        NULL,             // Authentication info
        EOAC_NONE,        // Additional capabilities
        NULL              // Reserved
        );
}

Note: To connect to the \root\CIMV2\TerminalServices namespace, the authentication level must include packet privacy. For C/C++ calls, this is an authentication level of RPC_C_AUTHN_LEVEL_PKT_PRIVACY.

3) Create a connection to a WMI namespace

By definition, WMI runs in a different process than your application. Therefore, you must create a connection between your application and WMI.

Note: To connect to a remote computer, for example Computer_B, use the following parameters:

_bstr_t(L"\\COMPUTER_B\ROOT\\CIMV2") // WMI namespace
_bstr_t(L"DOMAIN\\MyUserName") // User name
_bstr_t(L"MyPassword") // User password

Here is the main code:

IWbemLocator *pLocator = NULL;
if (SUCCEEDED(hr))
{
    // Obtain the initial locator to Windows Management
    // on a particular host computer.
    hr = CoCreateInstance(
        CLSID_WbemLocator,
        0,
        CLSCTX_INPROC_SERVER,
        IID_IWbemLocator, (LPVOID *) &pLocator);
}

IWbemServices *pNamespace = NULL;
_bstr_t sNamespace(L"ROOT\\CIMV2");
if (SUCCEEDED(hr))
{
    // Connect to the root\cimv2 namespace with the
    // current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hr = pLocator->ConnectServer(
        sNamespace,               // WMI namespace
        NULL,                       // User name
        NULL,                       // User password
        0,                            // Locale
        NULL,                       // Security flags
        0,                            // Authority
        0,                            // Context object
        &pNamespace     // IWbemServices proxy
        );
}

if(SUCCEEDED(hr))
    wprintf(L"Connected to %s WMI namespace.\n", static_cast(sNamespace));

Note: The code above works for Win2k3/XP, for Vista, just update the namespace from "root/cimv2" to "root/cimv2/TerminalServices".

4) Set the security levels on the WMI connection

To use the connection you create to WMI, you must set the impersonation and authentication levels for your application.

if (SUCCEEDED(hr))
{
    // Set the IWbemServices proxy so that impersonation
    // of the user (client) occurs.
    hr = CoSetProxyBlanket(
        pNamespace,                   // the proxy to set
        RPC_C_AUTHN_WINNT,            // authentication service
        RPC_C_AUTHZ_NONE,             // authorization service
        NULL,                         // Server principal name
        RPC_C_AUTHN_LEVEL_PKT_PRIVACY,       // authentication level
        RPC_C_IMP_LEVEL_IMPERSONATE,  // impersonation level
        NULL,                         // client identity
        EOAC_NONE                     // proxy capabilities
        );
}
5) Make the WMI Request

Locate Win32_TerminalServiceSettings using IWbemServices.

IEnumWbemClassObject* pEnumerator = NULL;
if(SUCCEEDED(hr))
{
    hr = pNamespace->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_TerminalServiceSetting"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);
}
6) Check and Update TerminalServiceSettings

Check the current value of AllowTSConnection flag and call SetAllowTSConnection.

IWbemClassObject * pObject = NULL;
ULONG uReturn = 0;
while (pEnumerator)
{
    hr = pEnumerator->Next(WBEM_INFINITE, 1,
        &pObject, &uReturn);

    if(0 == uReturn)
    {
        break;
    }

    if(SUCCEEDED(hr))
    {
        // Get the current Value of AllowTSConnections
        VARIANT v;
        hr = pObject->Get(L"AllowTSConnections",0,&v,0,0);

        if (SUCCEEDED(hr) && (V_VT(&v) == VT_I4))
        {
            wprintf(L"AllowTSConnections = %d.\n", V_I4(&v));
        }
        else
        {
            wprintf(L"Error in getting specified object\n");
        }
        VariantClear(&v);
    }

    if(SUCCEEDED(hr))
    {
        // Call the method SetAllowTSConnections(1)
        _bstr_t sMethodName = L"SetAllowTSConnections";
        _bstr_t sClassName = L"Win32_TerminalServiceSetting";

        IWbemClassObject* pClass = NULL;
        hr = pNamespace->GetObject(sClassName, 0, NULL, &pClass, NULL);

        IWbemClassObject* pInParamsDefinition = NULL;
        hr = pClass->GetMethod(sMethodName, 0, &pInParamsDefinition, NULL);

        IWbemClassObject* pClassInstance = NULL;
        hr = pInParamsDefinition->SpawnInstance(0, &pClassInstance);

        // Create the values for the in parameters
        VARIANT v;
        V_VT(&v) = VT_I4;
        V_I4(&v) = 1;

        // Store the value for the in parameters
        hr = pClassInstance->Put(L"AllowTSConnections", 0, &v, 0);

        // Get the context from which to execute the method
        CIMTYPE pType;
        LONG pFlavor;
        VARIANT var;
        hr = pObject->Get(L"__PATH", 0, &var, &pType, &pFlavor);

        // Execute Method
        IWbemClassObject* pOutParams = NULL;
        hr = pNamespace->ExecMethod(var.bstrVal, sMethodName, 0,
                 NULL, pClassInstance, &pOutParams, NULL);

        if (SUCCEEDED(hr))
        {
            wprintf(L"SetAllowTSConnections(%d) OK.\n", V_I4(&v));
        }
        else
        {
            wprintf(L"SetAllowTSConnections(%d) FAILED.\n", V_I4(&v));
        }

        VariantClear(&v);
        VariantClear(&var);
    }
7) Cleanup and shutdown

Destroy all COM pointers and shut down your application correctly.

if(pLocator != NULL)
    pLocator->Release();
if(pNamespace != NULL)
    pNamespace->Release();
CoUninitialize();

Conclusion

Enabling Remote Desktop locally or remotely is of great use for administrators or to automate installers (NSIS for instance). But it needs to be done properly (not just with the registry settings). WMI is the best way to achieve this and you I have described how to achieve this in VC++. You can find attached the full .cpp file of the example I will probably be discussing here about a plugin for NSIS if people are interrested.

 

 

 原文地址:

 http://www.vedivi.com/support/blog/71-how-to-enable-remote-desktop-programmatically.html 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值