You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CredentialCache存储RDP凭证失败,求技术解决方案

问题分析

你用CredentialCache类的思路从根上错了——这个类是用来给当前.NET应用内部缓存网络请求凭证的,根本不会把凭证写入Windows系统的「凭证管理器」。代码没报错只是因为语法合法,但完全没触及系统凭证存储的逻辑。

另外你最初尝试的TERMSRV//RemoteMachine格式,其实是Windows凭证管理器中RDP凭证的目标名称格式,但CredentialCache的Uri参数不支持这种格式,所以会报错。

正确实现方式

要把RDP凭证写入系统凭证管理器,需要调用Windows原生的凭据管理API,下面提供两种可行方案:

方案1:直接使用P/Invoke调用Windows API

不需要额外依赖,直接通过平台调用实现:

using System;
using System.Runtime.InteropServices;

public class RdpCredentialManager
{
    // 定义Windows凭据API所需的结构体和常量
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct CREDENTIAL
    {
        public int Flags;
        public int Type;
        public string TargetName;
        public string Comment;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
        public int CredentialBlobSize;
        public IntPtr CredentialBlob;
        public int Persist;
        public int AttributeCount;
        public IntPtr Attributes;
        public string TargetAlias;
        public string UserName;
    }

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool CredWrite([In] ref CREDENTIAL credential, [In] int flags);

    /// <summary>
    /// 写入RDP凭证到系统凭证管理器
    /// </summary>
    /// <param name="remoteMachine">远程机器名/IP</param>
    /// <param name="username">用户名(格式:domain\user 或 user)</param>
    /// <param name="password">密码</param>
    /// <returns>是否成功</returns>
    public static bool AddRdpCredential(string remoteMachine, string username, string password)
    {
        var credential = new CREDENTIAL
        {
            Type = 1, // CRED_TYPE_GENERIC
            TargetName = $"TERMSRV/{remoteMachine}", // RDP凭证的目标名称固定以TERMSRV/开头
            UserName = username,
            Persist = 2, // CRED_PERSIST_LOCAL:本地持久化,重启后保留
            CredentialBlobSize = password.Length * 2,
            CredentialBlob = Marshal.StringToHGlobalUni(password)
        };

        bool result = CredWrite(ref credential, 0);
        Marshal.FreeHGlobal(credential.CredentialBlob); // 释放非托管内存
        return result;
    }
}

// 使用示例
// RdpCredentialManager.AddRdpCredential("RemoteMachine", @"domain\username", "password");

方案2:使用第三方NuGet包简化操作

如果不想写复杂的P/Invoke代码,可以使用CredentialManagement这个NuGet包:

  1. 安装NuGet包:Install-Package CredentialManagement
  2. 编写代码:
using CredentialManagement;

// 写入RDP凭证
using (var credential = new Credential())
{
    credential.Target = $"TERMSRV/RemoteMachine";
    credential.Username = @"domain\username";
    credential.Password = "password";
    credential.Type = CredentialType.Generic;
    credential.PersistanceType = PersistanceType.LocalComputer;
    credential.Save();
}
关键注意事项
  • RDP凭证在系统凭证管理器中的目标名称必须是TERMSRV/[远程机器名/IP],这是Windows的固定规则
  • 普通本地凭证写入不需要管理员权限,若写入企业级凭证可能需要对应权限
  • 验证写入结果可打开「控制面板→用户账户→凭据管理器→Windows凭据」查看

内容的提问来源于stack exchange,提问作者Iunknown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 05:13:17