我的存在函数说该文件存在,但winapi函数说它不存在

Tom*_*ica 0 winapi image file

我复制了应该更改桌面壁纸的代码.我的程序中有这个常数:

const char * image_name = "button_out.gif";
Run Code Online (Sandbox Code Playgroud)

之后,我使用Magick++以下方法在磁盘上写入图像:

image.write(image_name);
Run Code Online (Sandbox Code Playgroud)

该图像出现在程序的工作目录中.如果我直接从资源管理器运行程序,工作目录等于程序位置.

图像和图像生成器

因为代码打印0x80070002 - File not found错误我在开头添加了一个exists函数:

#include <sys/stat.h>
bool exists(const char* name) {
  struct stat buffer;   
  return (stat (name, &buffer) == 0); 
}
void  SetWallpaper(LPCWSTR file){
  if(!exists((const char* )file)) {
    wcout << "The file "<<file<<" does not exist!" << endl;  
  return;
  ... actually try to set a wallpaper ...
}
Run Code Online (Sandbox Code Playgroud)

但是,不打印错误,代码继续进行.

现在的问题是:

  1. 我存在的功能是否正常工作?
  2. Windows在哪里寻找该图像?

完整代码将Magick ++生成的图像设置为背景,以防我错过了与此问题相关的内容.

Jas*_*n C 5

问题1:字符串转换

您的主要问题是您尝试使用LPCWSTR(a const wchar_t *)并const char *可互换使用.我在您的来源中看到了许多问题,特别是:

  • 你从一开始const char * image_name.
  • 然后你把它投到一个LPCWSTR传递给SetWallpaper.这基本上保证SetWallpaper会失败,因为desktop->SetWallpaper无法处理非宽字符串.
  • 然后你把它扔回去const char *传递给stat()via exists().这应该在你的情况下工作(因为原来的串真的是char *),但不正确的,因为你的字符串参数SetWallpaper所谓正确的LPCWSTR.

您需要选择一种字符串格式(宽字符与Windows术语"ANSI")并坚持使用一致的API.

最简单的选择可能只是让您的大部分代码保持不变,但修改SetWallpaper为在需要时采取const char *并转换为宽字符串(为此您可以使用mbstowcs).所以,例如:

void  SetWallpaper(const char * file){  // <- Use a const char* parameter.
   ...

   // Convert to a wide-character string to pass to COM: 
   wchar_t wcfile[MAX_PATH + 1];
   mbstowcs(wcfile, file, sizeof(wcfile) / sizeof(wchar_t));

   // Pass the converted wide-character string:
   desktop->SetWallpaper(wcfile, 0);

   ...
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是在整个过程中使用宽字符串,即:

  • LPCWSTR image_name = L"button_out.gif";
  • 修改exists()以取代LPCWSTR并使用_wstat().
  • 使用所有其他API函数的宽字符版本.

但是,我不确定它将如何与ImageMagick API交互,后者可能没有广泛的字符支持.所以这取决于你.选择最容易实现的方法,但要确保一致.一般规则是不要在LPCWSTR和之间施放const char * ; 如果您遇到需要将其中一个更换为另一个的情况,则无法转换,您必须转换(通过mbstowcswcstombs).

问题2:SetWallpaper默认目录不是当前工作目录

此时,您的字符串用法将保持一致.现在你已经解决了这个问题,如果SetWallpaper失败了exists(),那么SetWallpaper就没有找到你认为的地方.正如您在评论中发现的那样SetWallpaper,默认情况下会在桌面上查找.在这种情况下,虽然我没有测试它,你可以通过传递绝对路径来解决这个问题SetWallpaper.为此,您可以使用GetFullPathName确定给定相对路径的绝对文件名.但请记住,与字符串类型保持一致.

另外,如果stat()仍然失败,那么问题是,要么你的工作目录是不是你认为它是,或者你的文件名不是你认为它是.为此,您需要执行以下测试:

  • 在检查文件是否存在的位置打印当前工作目录,验证它是否正确.
  • 检查文件名是否存在时打印文件名,验证其是否正确.

一旦你解决了上述所有问题,你应该好好去.