GetLastError在SystemParametersInfo中返回错误2
GetLastError returns error 2 in SystemParametersInfo
#include <iostream>
#include <windows.h>
using namespace std;
int main(){
LPWSTR test = L"c:/aizen.png";
int result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, test, SPIF_UPDATEINIFILE);
if(result)
cout << "Wallpaper set!";
else
cout << "Error: " << GetLastError();
cin >> result;
return 0;
}
该代码只是为了更改背景壁纸,但我一直收到错误:2,意思是"找不到文件"。但是,文件就在那里!我使用的是微软visual studio 2010,我尝试过以管理员身份运行,区分大小写,更改斜杠等。我做错了什么?
错误2为File not found
。
首先,确保aizen.png
实际上位于驱动器C:
的根文件夹中(在Vista及更高版本上,这是不可能的,因为非管理员用户通常没有写访问权限(。
如果文件确实存在,那么问题很可能是您没有正确转义反斜杠:
LPWSTR test = L"c:\aizen.png";
问题是将UNICODE字符串LPWSTR
-传递给采用ANSI的API。
几乎所有的Win32 API(所有这些API都接受字符串(都有两个版本,一个以…结尾。。。一个表示ANSI(8位字符(,一个以…结尾。。。W代表Wide char,也就是UNICODE(从技术上讲不是"真正的"UNICODE,但这比在这个回复中得到的更值得(。
如果您在编译时有UNICODE #define
d,那么纯素版本将被#定义为。。。W版本;否则它被#定义为。。。一个版本。看看winuer.h,你会看到:
WINUSERAPI
BOOL
WINAPI
SystemParametersInfoA(
__in UINT uiAction,
__in UINT uiParam,
__inout_opt PVOID pvParam,
__in UINT fWinIni);
WINUSERAPI
BOOL
WINAPI
SystemParametersInfoW(
__in UINT uiAction,
__in UINT uiParam,
__inout_opt PVOID pvParam,
__in UINT fWinIni);
#ifdef UNICODE
#define SystemParametersInfo SystemParametersInfoW
#else
#define SystemParametersInfo SystemParametersInfoA
#endif // !UNICODE
请注意,Windows具有两个SystemParametersInfo函数;W期望宽的LPWSTR,而A期望普通的LPSTR;以及是否定义了UNICODE,选择哪个是"默认"UNICODE。(您总是可以手动添加A或W来显式调用。(
在您的原始代码中可能发生的情况是,因为您没有定义UNICODE,所以最终使用。。。一个版本,它需要一个ANSI字符串,但您传递的是UNICODE字符串,所以它不起作用。
您为使其工作所做的"一点更改"不仅仅是一点:您现在正在将ANSI字符串传递给。。。API的一个版本,所以它工作得很好:
int result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)"c:/aizen.jpg", SPIF_UPDATEINIFILE);
或者,您可以使用LPWSTR:显式调用W版本
int result = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, L"c:\aizen.jpg", SPIF_UPDATEINIFILE);
或者,你可以在应用程序开始时定义UNICODE,使用L"…"字符串和API的普通版本——只需在#include之前在原始应用程序的顶部添加#define UNICODE。(UNICODE通常是在生成文件或编译器设置选项中定义的,而不是在代码中明确定义的,所以如果你是Win32编程的新手,它可能会成为一个令人惊讶的功能。(
请注意,LPWSTR是而不是已弃用;如果说有什么不同的话,那就是相反;自XP以来,Win32的典型做法是全面使用W风格的字符串,因此它实际上是Win32上被认为"不推荐"的普通"…"字符串。(例如,许多COM API只使用宽字符串。(
大多数其他功能对此有一定的保护作用;如果您不小心试图传递一个ANSI字符串,比如SetWindowTextW,您将得到一个编译时错误,因为您传递的LPSTR与函数期望的已导出LPWSTR类型不匹配。但SystemParamtersInfo很棘手;它为数据参数取了一个void*,因此在编译时会接受[most]任何,只有当您在运行时调用该函数时才会出现错误。
--
顺便说一句,这是David Herfernan在你第一次发布时对你的问题的回答中指出的
脑海中浮现出一些可能的原因:
- 您的ANSI/Unicode编码不匹配
这看起来很奇怪,如果你用MinGW c++编译器编译,它实际上会进行一些更改:
int main(){
int result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)"c:/aizen.jpg", SPIF_UPDATEINIFILE);
这是可行的,显然LPWSTR已被弃用。。。Visual Studio可能存在权限问题。以管理员身份运行它,然后重试。
- (C++)分析树以计算返回错误值的简单算术表达式
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 我不断收到 [错误] ID 返回 1 退出状态错误,但看不到问题所在
- C++中函数的向量返回类型引发错误
- 有人知道为什么在开关中使用stoi函数会返回恒定的错误吗
- glad 导致 glfwSwapBuffers 返回错误消息
- 将错误返回给调用方而不是立即在 C++ 中抛出错误是否是一种好的做法
- QNX Momentics: GoogleMock - 返回有价值,在函数中返回 void 错误
- 我的模板类方法返回错误类型?
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 替换WCHAR_T错误返回存储地址
- 错误:void 值未被忽略,因为它应该被忽略,错误:返回语句具有值
- 带有值的递归阶乘错误返回语句,在函数中返回 'void' [-fallowive]
- 存储在静态常量整数 (C++) 中的对数函数的错误返回值
- 更丰富的错误返回消息用于提升::精神::qi 解析
- C++初级逻辑错误-返回0
- 由于进程很多,pthread_create的错误返回代码是 35 错误,我用过pthread_exit应该杀死线程不是吗?
- c++错误处理返回值错误返回
- systememerror:没有异常集的错误返回