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

为何GetLastError返回2?Rust调用CreateFileW创建文件失败排查

解决Rust调用CreateFileW返回错误码2的问题

错误码2对应Windows系统的ERROR_FILE_NOT_FOUND(文件未找到),你的代码存在两处核心问题导致该错误:


1. 字符串转换逻辑错误

CreateFileW要求传入UTF-16编码的宽字符字符串(LPCWSTR本质是*const u16),但你用CString处理字符串——CString是用于生成UTF-8/多字节的C风格字符串,强制转成*const u16会导致系统无法正确解析文件名,最终触发文件未找到错误。

2. 文件创建模式参数错误

你使用了OPEN_EXISTING作为dwCreationDisposition参数,该参数的作用是仅打开已存在的文件,如果目标文件不存在,调用必然失败并返回错误码2。若要创建新文件,需根据需求选择以下参数:

  • CREATE_NEW:仅当文件不存在时创建,存在则返回错误
  • CREATE_ALWAYS:无论文件是否存在都创建(存在则覆盖)
  • OPEN_ALWAYS:文件存在则打开,不存在则创建

修正后的代码

createfile.rs

use winapi::shared::minwindef::DWORD;
use winapi::um::winnt;
use winapi::um::errhandlingapi;
use winapi::ctypes::*;
use winapi::um::minwinbase::*;
use winapi::um::fileapi;
use winapi::um::handleapi;
use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;

// 打印系统错误码
fn print_last_error() {
    unsafe {
        let err_code = errhandlingapi::GetLastError();
        println!("错误码: {}", err_code);
    }
}

// 正确将Rust字符串转换为Windows宽字符指针
fn to_lpcwstr(s: &str) -> *const u16 {
    OsStr::new(s)
        .encode_wide()
        .chain(std::iter::once(0)) // 必须添加宽字符串终止符
        .collect::<Vec<_>>()
        .as_ptr()
}

fn main() {
    unsafe {
        let name = to_lpcwstr("file.rs");
        let access: DWORD = winnt::GENERIC_WRITE;
        let share_mode = winnt::FILE_SHARE_DELETE | winnt::FILE_SHARE_READ | winnt::FILE_SHARE_WRITE;
        let security_attrs = std::ptr::null_mut();
        // 使用CREATE_ALWAYS实现"存在则覆盖,不存在则创建"
        let disposition = fileapi::CREATE_ALWAYS;
        let attrs = winnt::FILE_ATTRIBUTE_NORMAL;
        let template_handle = std::ptr::null_mut();

        let handle = fileapi::CreateFileW(
            name,
            access,
            share_mode,
            security_attrs,
            disposition,
            attrs,
            template_handle,
        );

        if handle == handleapi::INVALID_HANDLE_VALUE {
            print_last_error();
        } else {
            println!("文件创建成功");
            // 必须关闭文件句柄,避免资源泄漏
            handleapi::CloseHandle(handle);
        }
    }
}

Cargo.toml

[package]
name = "createfile"
version = "0.1.0"
edition = "2021"

[dependencies]
winapi = { version = "0.3.9", features = ["fileapi", "errhandlingapi", "handleapi"] }

额外注意事项

  • 转换字符串时必须添加宽字符终止符0,这是Windows API对宽字符串的强制要求
  • 调用CreateFileW后必须检查返回值是否为INVALID_HANDLE_VALUE,只有此时调用GetLastError才能得到有效错误信息
  • 文件操作完成后务必调用CloseHandle关闭句柄,防止系统资源泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:48:14