0

我需要使用已签名 RDP文件的 remoteapplicationcmdline 属性为 RemoteApp 指定命令行参数。

但是,在 RDP 文件签名后,我无法更改 remoteapplicationcmdline 的值。如果我从 signscope 中删除 remoteapplicationcmdline,则无法指定任何参数。

这与 Chupkb 在Technet上提出的问题相同。

我可能可以按照 Naraen 在这个问题上的建议做,但在我这样做之前,我希望有一个更简单的方法。

4

1 回答 1

4

我最终采取的方法是从前一页(可能是登录页)收集命令行参数,然后在下一页上动态创建一个 rdp 文件,对其进行签名,并将内容嵌入到 html 页面上的 javascript 中。下面的代码是 ASP.NET 和 c#,但它也应该是其他语言的一个很好的起点。

首先,html(注意 LaunchRemoteApp() 中的 <%= RdpFileContents %> :

<html>
<head>
    <title>RD Web Access</title>

    <script type="text/javascript" language="javascript">
        var g_workspace = null;

        var workspaceID = "[RemoteAppMachineName]";
        var domainUserName = "[RemoteAppMachineName]\\[RemoteAppUserName]";

        // This is the certificate's thumbprint.
        var rdpCertificates = "04b83503a710cad89f25d3e15a48245f490773c4";
        var machineType = "public";

        function onAutoDisconnect() {
            var workspace = null;

            if (workspaceID != null && workspaceID != "") {
                try {
                    workspace = GetWorkspaceObject();
                    workspace.ClearWorkspaceCredential(workspaceID);
                }
                catch (objException) {
                    workspace = null;
                }
            }
        }

        function onUserDisconnect() {
            var workspace = null;

            try {
                workspace = GetWorkspaceObject();
                workspace.DisconnectWorkspace(workspaceID);
            }
            catch (objException) {
                workspace = null;
            }
        }

        function onAuthenticated() {
            var workspace = null;
            var isOnAuthenticatedCalled = false;

            if (workspaceID != null && workspaceID != "") {
                try {
                    workspace = GetWorkspaceObject();
                    workspace.StartWorkspace(workspaceID, domainUserName, password, rdpCertificates, 1200000, 0);

                    var countUnauthenticatedCredentials = true;
                    var isWorkspaceCredentialSpecified = workspace.IsWorkspaceCredentialSpecified(workspaceID, countUnauthenticatedCredentials);

                    if (isWorkspaceCredentialSpecified) {
                        isOnAuthenticatedCalled = true;
                        workspace.OnAuthenticated(workspaceID, domainUserName);
                    }

                    setTimeout("onAutoDisconnect()", 1200000);
                }
                catch (objException) {
                    workspace = null;
                    var errorCode = (objException.number & 0xFFFF);

                    if (isOnAuthenticatedCalled) {
                        if (errorCode == 183) { 
                            // 183 = ERROR_ALREADY_EXISTS.
                        }
                        else if (errorCode == 1168) { 
                            // 1168 = ERROR_NOT_FOUND.
                        }
                    }
                }
            }
        }

        function GetWorkspaceObject() {
            var objClientShell = null;

            if (g_workspace == null) {
                objClientShell = new ActiveXObject("MsRdpWebAccess.MsRdpClientShell");
                g_workspace = objClientShell.MsRdpWorkspace;
            }

            return g_workspace;
        }

        function LaunchRemoteApp() {
            var msRdpClientShell = document.all.MsRdpClient;

            msRdpClientShell.PublicMode = true;
            msRdpClientShell.RdpFileContents = <%= RDPContents %>;

            try {
            msRdpClientShell.Launch();
            }
            catch (e) {
               throw e;
            }
        }
    </script>
</head>
<body onload="onAuthenticated();">
    <form name="form1" method="post" action="default.aspx" id="form1">
        <object name="MsRdpClient" width="0" height="0" id="MsRdpClient" classid="CLSID:6A5B0C7C-5CCB-4F10-A043-B8DE007E1952" type="application/x-oleobject"></object>
        <a href="javascript:LaunchRemoteApp();">YourAppName</a>
    </form>
</body>
</html>

然后我创建了一个包含所有正确内容的模板 RDP 文件。请注意,remoteapplicationcmdline 值具有一些虚拟命令行参数(FirstName、LastName、CustomerID)。您将在代码中根据需要替换这些内容。

redirectclipboard:i:0
redirectposdevices:i:0
redirectprinters:i:0
redirectcomports:i:0
redirectsmartcards:i:0
devicestoredirect:s:
drivestoredirect:s:
redirectdrives:i:0
session bpp:i:32
prompt for credentials:i:0
span monitors:i:0
use multimon:i:0
remoteapplicationmode:i:1
server port:i:3389
allow font smoothing:i:1
promptcredentialonce:i:1
authentication level:i:2
gatewayusagemethod:i:2
gatewayprofileusagemethod:i:0
gatewaycredentialssource:i:0
full address:s:[RemoteAppMachineName]
alternate shell:s:||[YourAppName]
remoteapplicationprogram:s:||[YourAppName]
gatewayhostname:s:
remoteapplicationname:s:[YourAppName]
remoteapplicationcmdline:s:/FirstName:{0} /LastName:{1} /CustomerID:{2}
Workspace Id:s:[RemoteAppMachineName]

然后在后面的代码中,我加载模板 rdp 文件,替换命令行参数,写入临时 rdp 文件,签署临时 rdp 文件,并将生成的内容嵌入到 <%= RdpFileContents %> 的 javascript

private string GetRDPContents()
{
    FileInfo fileInfo = new FileInfo(Path.Combine(Server.MapPath("~"), "Template.rdp"));

    string[] unsignedRDPContents = File.ReadAllLines(fileInfo.FullName);

    for (int i = 0; i < unsignedRDPContents.Length; i++)
    {
        if (unsignedRDPContents[i].IndexOf("remoteapplicationcmdline") != -1)
        unsignedRDPContents[i] = String.Format(unsignedRDPContents[i], FirstName, LastName, CustomerID);
    }

    string tempFileName = Path.Combine(Server.MapPath("~"), Guid.NewGuid().ToString() + ".rdp");
    File.WriteAllLines(tempFileName, unsignedRDPContents);

    InvokeRDPSign(tempFileName, certificateThumbprint);

    string[] signedRDPContents = File.ReadAllLines(tempFileName);

    File.Delete(tempFileName);

    // This escape function is identical to the javascript escape function.
    return String.Format("unescape('{0}')", Microsoft.JScript.GlobalObject.escape(String.Join("\r\n", signedRDPContents)));
}

// This is the certificate's thumbprint.
private const string certificateThumbprint = "04a85503a810cad89f25d3f14c48245f499773c4";
private void InvokeRDPSign(string fileName, string certificateThumbPrint)
{
    Process rdpSign = new Process();
    rdpSign.StartInfo.FileName = "rdpsign.exe";

    rdpSign.StartInfo.Arguments = String.Format("/sha1 {0} \"{1}\"", certificateThumbPrint, fileName);
    rdpSign.StartInfo.UseShellExecute = false;
    rdpSign.StartInfo.RedirectStandardOutput = true;
    rdpSign.StartInfo.RedirectStandardInput = true;
    rdpSign.StartInfo.RedirectStandardError = true;

    rdpSign.StartInfo.WorkingDirectory = Server.MapPath("~");
    rdpSign.Start();

    string signingOutput = rdpSign.StandardOutput.ReadToEnd();
    rdpSign.WaitForExit();
    int exitCode = rdpSign.ExitCode;
}

最终的 javascript看起来像这样:

function LaunchRemoteApp() {
    var msRdpClientShell = document.all.MsRdpClient;

    msRdpClientShell.PublicMode = true;
    msRdpClientShell.RdpFileContents = unescape('redirectclipboard%3Ai%3A0%0D%0A%0D%0Aredirectposdevices%3Ai%3A0%0D%0A%0D%0Aredirectprinters%3Ai%3A0%0D%0A%0D%0Aredirectcomports%3Ai%3A0%0D%0A%0D%0Aredirectsmartcards%3Ai%3A0%0D%0A%0D%0Adevicestoredirect%3As%3A%0D%0A%0D%0Adrivestoredirect%3As%3A%0D%0A%0D%0Aredirectdrives%3Ai%3A0%0D%0A%0D%0Asession%20bpp%3Ai%3A32%0D%0A%0D%0Aprompt%20for%20credentials%3Ai%3A0%0D%0A%0D%0Aspan%20monitors%3Ai%3A0%0D%0A%0D%0Ause%20multimon%3Ai%3A0%0D%0A%0D%0Aremoteapplicationmode%3Ai%3A1%0D%0A%0D%0Aserver%20port%3Ai%3A3389%0D%0A%0D%0Aallow%20font%20smoothing%3Ai%3A1%0D%0A%0D%0Apromptcredentialonce%3Ai%3A1%0D%0A%0D%0Aauthentication%20level%3Ai%3A2%0D%0A%0D%0Agatewayusagemethod%3Ai%3A2%0D%0A%0D%0Agatewayprofileusagemethod%3Ai%3A0%0D%0A%0D%0Agatewaycredentialssource%3Ai%3A0%0D%0A%0D%0Afull%20address%3As%3A[YourMachineName]%0D%0A%0D%0Aalternate%20shell%3As%3A%7C%7C[YourAppName]%0D%0A%0D%0Aremoteapplicationprogram%3As%3A%7C%7C[YourAppName]%0D%0A%0D%0Agatewayhostname%3As%3A%0D%0A%0D%0Aremoteapplicationname%3As%3A[YourAppName]%0D%0A%0D%0Aremoteapplicationcmdline%3As%3A/FirstName%3AJon%20/LastName%3ADoe%20/CustomerID%3A7921385%0D%0A%0D%0Aworkspace%20id%3As%3A[YourMachineName]%0D%0A%0D%0Aalternate%20full%20address%3As%3A[YourMachineName]%0D%0A%0D%0Asignscope%3As%3AFull%20Address%2CAlternate%20Full%20Address%2CServer%20Port%2CGatewayHostname%2CGatewayUsageMethod%2CGatewayProfileUsageMethod%2CGatewayCredentialsSource%2CPromptCredentialOnce%2CAlternate%20Shell%2CRemoteApplicationProgram%2CRemoteApplicationMode%2CRemoteApplicationName%2CRemoteApplicationCmdLine%2CPrompt%20For%20Credentials%2CAuthentication%20Level%2CRedirectDrives%2CRedirectPrinters%2CRedirectCOMPorts%2CRedirectSmartCards%2CRedirectPOSDevices%2CRedirectClipboard%2CDevicesToRedirect%2CDrivesToRedirect%0D%0A%0D%0Asignature%3As%3AAQABAAEAAADgEgAAMIIS3AYJKoZIhvcNAQcCoIISzTCCEskCAQExCzAJBgUrDgMC%20%20GgUAMAsGCSqGSIb3DQEHAaCCEQMwggPFMIICraADAgECAhACrFwmagtAm48LefKu%20%20RiV3MA0GCSqGSIb3DQEBBQUAMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdp%20%20Q2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRp%20%20Z2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAw%20%20WhcNMzExMTEwMDAwMDAwWjBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNl%20%20cnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdp%20%20Q2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMIIBIjANBgkqhkiG9w0BAQEF%20%20AAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/lgT/JzSVJtnEqw9WUNGeiChyw%20%20X2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC90qlUxI47vNJbXGRfmO2q6Zf%20%20w6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+ceg1v01yCT2+OjhQW3cxG42z%20%20xyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5XIneGUpX1S7mXRxTLH6YzRoG%20%20FqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS8Xk5iKICEXwnZreIt3jyygqo%20%20OKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhLywIDAQABo2MwYTAOBgNVHQ8B%20%20Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUsT7DaQP4v0cB1Jgm%20%20GggC72NkK8MwHwYDVR0jBBgwFoAUsT7DaQP4v0cB1JgmGggC72NkK8MwDQYJKoZI%20%20hvcNAQEFBQADggEBABwaBpfc15yfPIhmBghXIdshR/gqZ6q/GDJ2QBBXwYrzetkR%20%20ZY41+p78RbWe2UwxS7iR6EMsjrN4ztvjU3lx1uUhlAHaVYeaJGT2imbM3pw3zag0%20%20sWmbI8ieeCIrcEPjVUcxYRnvWMWFL04w9qAxFiPI5+JlFjPLvxoboD34yl6LMYtg%20%20CIktDAZcUrfE+QqY0RVfnxK+fDZjOL1EpH/kJisKxJdpDemM4sAQV7jIdhKRVfJI%20%20adi8KgJbD0TUIDHb9LpwJl2QYJ68SxcJL7TLHkNoyQcnwdJc9+ohuWgSnDycv578%20%20gFybY83sR6olJ2egN/MAgn1U16n46S4To3foH0owggZYMIIFQKADAgECAhAKXxFN%20%20A1sXkRfS79QDjD87MA0GCSqGSIb3DQEBBQUAMGwxCzAJBgNVBAYTAlVTMRUwEwYD%20%20VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzAp%20%20BgNVBAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwHhcNMDgw%20%20NDAyMTIwMDAwWhcNMjIwNDAzMDAwMDAwWjBmMQswCQYDVQQGEwJVUzEVMBMGA1UE%20%20ChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSUwIwYD%20%20VQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBDQS0zMIIBIjANBgkqhkiG9w0B%20%20AQEFAAOCAQ8AMIIBCgKCAQEAv2EKKRAfXv40N1EI+B77Iu1hvgsNcExQYyZ1FblB%20%20iJe28KAVuwhg4ELoBSkQhzaKKGWo7zEHdG02ly8oRmYExyp5JnqZ1Y7DbU+gXq28%20%20PZHCWXteNmzAU88ACDI+EGRYEBNpxwzunEJRAPkFRO4kznof7YwRvRKo8xX0HHox%20%20aQEbp+ZdwJpsfgme51JEShA6I+SbtgOvqJy0W5/US62SjM61ESqqNxiNtMK42FwG%20%20jPj/I701XtR8Pn6DDpGWBZjDsh/jyGXrqXtdoCzM/DzZbe3M+ktDjMnUuKVhHLJA%20%20tigS37n4X/7TssnvPbQeS3wcTJk2nj3r7KdoXh3fZ25e+wIDAQABo4IC+jCCAvYw%20%20DgYDVR0PAQH/BAQDAgGGMIIBxgYDVR0gBIIBvTCCAbkwggG1BgtghkgBhv1sAQMA%20%20AjCCAaQwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1j%20%20cHMtcmVwb3NpdG9yeS5odG0wggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAA%20%20dQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAA%20%20YwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8A%20%20ZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4A%20%20ZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUA%20%20ZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwA%20%20aQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQA%20%20IABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wEgYDVR0T%20%20AQH/BAgwBgEB/wIBADA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6%20%20Ly9vY3NwLmRpZ2ljZXJ0LmNvbTCBjwYDVR0fBIGHMIGEMECgPqA8hjpodHRwOi8v%20%20Y3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0Eu%20%20Y3JsMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdo%20%20QXNzdXJhbmNlRVZSb290Q0EuY3JsMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSYJhoI%20%20Au9jZCvDMB0GA1UdDgQWBBRQ6nOJ2yn7EI+e5QEg1N55mUiD9zANBgkqhkiG9w0B%20%20AQUFAAOCAQEAHuKlSJ5s21M4D++mGiqs4gND7Zq8Po51G/D9LiJZrBPAYeLn+umZ%20%20zYcJdVQov0Zg3L5RLJLzG5F8MQhw4je5wVuovaMLAPsaFf0DrVhqxcckmUhHRjEe%20%20ku+0X040x5C/McH4sYSG0JwBqt+KVgbOOukOrpd0XddxmkJ0X96NQ3ze6VXtaQDL%20%20BeB6YWEz0RlN+QjuoDnFJTW3K8QPst3xpbcOJMQmKI15d/Uv8Fe6fAfU4fzNWjBX%20%20foYQR90xH9f8osK/MHxdJKro+a5fanTCzmuzRtghvinUjl4V1kJK5zJvpLFrUYNY%20%20vj9tx/vaAyHLahYZTgrwrYTKXZSzWnb3YTCCBtowggXCoAMCAQICEA8mTuUj65Gh%20%20pZUfZncYkKUwDQYJKoZIhvcNAQEFBQAwZjELMAkGA1UEBhMCVVMxFTATBgNVBAoT%20%20DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTElMCMGA1UE%20%20AxMcRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2UgQ0EtMzAeFw0xMjAxMTEwMDAwMDBa%20%20Fw0xMzAxMTUxMjAwMDBaMIGBMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFjAU%20%20BgNVBAcTDUFtZXJpY2FuIEZvcmsxFzAVBgNVBAoTDkNlcnRpcG9ydCwgSW5jMQ8w%20%20DQYDVQQLEwZJVCBPcHMxIzAhBgNVBAMTGnd3dy5jZXJ0aXBvcnRzb2x1dGlvbnMu%20%20bmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnVQMQG4UrUIHOrLi%20%20dl4tk3n+WJ5qYt7L9uW0qqGjLN2m7G0hJ8kFiuzBzZJ+HwuSV1SMomBBPR3pdZP6%20%205w/41+Che1Mo1yw5eu3L8UgANSFsUaRw+3DZesCxnWOsW1AZB2lQ7fxfQH3ZZZiA%20%20/ONBIiWBNEos8rZk/Rme+mN0LwrzpQJMCoQCJqFCuix9w4ZXC9qRX72BkWNJGRHt%20%20pnhYIePkuSDN3mrK8SWuU3FMX6aHe0rDr/81skzFptPJXWcarjYF3nNgvlY5luPw%20%20iKZwj/viVtYa3m8ClkgCBJSwjNIMjRsmVuKA2fqrxnnfikwXszzDp4Jwpmt4pRJF%20%200RlspQIDAQABo4IDZjCCA2IwHwYDVR0jBBgwFoAUUOpzidsp+xCPnuUBINTeeZlI%20%20g/cwHQYDVR0OBBYEFMfKlt05WQQBtb5oJ/hY81x2XkznMD0GA1UdEQQ2MDSCGnd3%20%20dy5jZXJ0aXBvcnRzb2x1dGlvbnMubmV0ghZjZXJ0aXBvcnRzb2x1dGlvbnMubmV0%20%20MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw%20%20XwYDVR0fBFgwVjApoCegJYYjaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL2NhMy1n%20%20My5jcmwwKaAnoCWGI2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9jYTMtZzMuY3Js%20%20MIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgBhv1sAQEwggGkMDoGCCsGAQUFBwIB%20%20Fi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRt%20%20MIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABo%20%20AGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0%20%20AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBn%20%20AGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBs%20%20AHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABp%20%20AGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABh%20%20AHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABi%20%20AHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMHsGCCsGAQUFBwEBBG8wbTAkBggrBgEF%20%20BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEUGCCsGAQUFBzAChjlodHRw%20%20Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlQ0Et%20%20My5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAS0sxic3EpcQ/%20%20p8ROF68Y6jpAb8RzESB5vN2YJgEljSBf53wQ090F+c8+VMZfFEw2jlsILu6vHTlw%20%20LC6ZPvwn9DvBvEAF3KZHe0Hv+2SFgdK8UgCSc2qgS8Kry/F/TlzSCe2fBjRPMwzg%20%20FdSd62d5QmneyaJ4bjyA+leyl+aLAUke4XLJM1qiPPmOE+R2Pb/97XADUW4kdbGt%20%207bvAsacHW0XQSgyU4w3QozSw0ot88y9lM2tWX9XtffTNsAW8GiGDR2q94ZzGulxn%20%20VMk1usccLy4rtzDs66y1NZjm8bknYdEOWhsod+A/4HGHgL/Z3febiyhTaIyp9hMY%20%20x0xLArDbcjGCAaEwggGdAgEBMHowZjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERp%20%20Z2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTElMCMGA1UEAxMc%20%20RGlnaUNlcnQgSGlnaCBBc3N1cmFuY2UgQ0EtMwIQDyZO5SPrkaGllR9mdxiQpTAJ%20%20BgUrDgMCGgUAMA0GCSqGSIb3DQEBAQUABIIBAJGNkWq+QeMYRPJZG3+Kwen96uy3%20%208V+6iE5pnGAFzrBPuN1BhvmkhiSDKLcT4ZSI07PNAsuZFLFz7g8yAuVWyWkfCJkn%20%20TAzj7kFCZBUP82ousA+Pp0VMdmfKjKfqOlJKPMpNJ6AKSHT1aAw4N2ZuzhnddZ/I%20%20HzrOoIJ9McvrMzGQSmhA4MefBg1ppqbudo1QCvVfOdwWg5KijHKIkVOe9BI8Dyic%20%20+cLu3iJ1jF3IMwMQb2Q4JX/FgIFMy9Hf12uhx9HP0JnR2sp5AnwfAGqPj2RSCmoA%20%20Px1XJxuea7WjMBnfTCUuQjuD/hfYdyTmj95G2nuZZM2Za4438JWPMPMW5ro%3D%20%20%0D%0A');

    try {
        msRdpClientShell.Launch();
    }
    catch (e) {
        throw e;
    }
}

我试图自己逃避 rdp 内容,但永远无法让它工作。如果您无法访问 Microsoft.JScript.GlobalObject.escape() 函数,您可以自己尝试。以下是我所知道的一些字符实体引用:

替换:用 %3A
替换 | 用 %7C
替换 \r\n 用 %0D%0A
用 %20 替换空格
行后没有多余的空格。

于 2012-02-14T18:10:09.490 回答