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

使用CredWriteW在Windows存储凭据显示为中文的问题求助

排查思路与修复方案:CredWriteW添加凭据显示中文乱码

首先,你遇到的问题核心是宽字符API与ANSI字符串的编码不匹配,这是Windows编程里很容易踩的经典坑之一。

排查步骤

  • 确认API字符版本匹配:Windows API分A(ANSI)和W(宽字符/UTF-16)两个版本,CredWriteW要求所有字符串参数(TargetName、UserName等)必须是宽字符类型。你用(LPWSTR)"testaccount"这种强制转换,本质是把单字节的ASCII序列直接当作双字节的UTF-16解析,必然出现乱码(也就是你看到的中文)。
  • 检查结构体成员类型:查看CREDENTIALW的定义,TargetName、UserName都是LPWSTR类型,你传入的char*和它类型完全不匹配,这是问题的根源。
  • 对比手动添加场景:手动在凭据管理器添加时,系统会正确处理输入的字符串编码(默认是宽字符),所以不会出现乱码,这也侧面验证了是代码里的编码转换逻辑出错。

修复方案

你可以选择以下两种方案之一解决问题:

方案1:改用ANSI版本的API

直接使用CredWriteA和CREDENTIALA结构体,适配你当前的char*字符串:

#include <iostream>
#include "windows.h"
#include "wincred.h"
#pragma hdrstop
using namespace std;

int main() {
    const char* password = "testpass";
    CREDENTIALA creds = { 0 };  // 改用ANSI版本结构体
    creds.Type = CRED_TYPE_GENERIC;
    creds.TargetName = "testaccount";  // 直接使用char*,无需强制转换
    creds.CredentialBlobSize = strlen(password) + 1;
    creds.CredentialBlob = (LPBYTE)password;
    creds.Persist = CRED_PERSIST_LOCAL_MACHINE;
    creds.UserName = "testuser";  // 同样使用char*

    BOOL result = CredWriteA(&creds, 0);  // 调用ANSI版本API
    if (result != TRUE) {
        cout << "Some error occurred, error code: " << GetLastError() << endl;
    } else {
        cout << "Stored the password successfully" << endl;
    }
    return 0;
}

方案2:正确使用宽字符版本的API

将所有字符串改为宽字符类型(用L""前缀,或者通过MultiByteToWideChar转换ANSI字符串),严格匹配CredWriteW的要求:

#include <iostream>
#include "windows.h"
#include "wincred.h"
#pragma hdrstop
using namespace std;

int main() {
    const wchar_t* password = L"testpass";  // 使用宽字符密码
    CREDENTIALW creds = { 0 };
    creds.Type = CRED_TYPE_GENERIC;
    creds.TargetName = L"testaccount";  // 直接用宽字符字符串
    creds.CredentialBlobSize = wcslen(password) * sizeof(wchar_t) + sizeof(wchar_t);  // 正确计算宽字符字节长度
    creds.CredentialBlob = (LPBYTE)password;
    creds.Persist = CRED_PERSIST_LOCAL_MACHINE;
    creds.UserName = L"testuser";  // 宽字符用户名

    BOOL result = CredWriteW(&creds, 0);
    if (result != TRUE) {
        cout << "Some error occurred, error code: " << GetLastError() << endl;
    } else {
        cout << "Stored the password successfully" << endl;
    }
    return 0;
}

额外建议:添加GetLastError()的输出,当CredWrite调用失败时可以获取具体错误码,帮助快速定位其他潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:15:25