我在visual c ++中有win32 API应用程序。我想在Application Common Data Directory中创建一个目录。我有生成以下错误的代码。我还尝试在字符串末尾添加'\ 0',但出现同样的错误。
调试断言失败! 表达式:(L“String不是NULL终止”&& 0);
代码:
TCHAR AppDir [MAX_PATH]; TCHAR SetPath [MAX_PATH];
ITEMIDLIST * pidl; HRESULT hRes = SHGetSpecialFolderLocation(NULL,CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE,& pidl); if(hRes == NOERROR) { SHGetPathFromIDList(pidl,AppDir); }
strcpy_s(的setpath,APPDIR);
:: strcat_s(的setpath, “\键盘记录程序”); :: SHCreateDirectoryExW(HWND,(LPCWSTR)的setpath,NULL);
:: strcat_s(的setpath, “\快照”); :: SHCreateDirectoryExW(HWND,(LPCWSTR)的setpath,NULL);
答案 0 :(得分:1)
你的大问题是对SHCreateDirectoryExW的调用中的(LPCWSTR)强制转换 - 这些强制转换显式阻止编译器告诉你错误是什么。
一般规则我希望更多的c ++程序员理解,不要强制转换。除非你理解为什么。永远不要强制“修复”编译器错误: - 99%的时间你没有修复错误,你只是隐藏它。
从头开始分析代码:
使用TCHAR意味着您正在编写可以定位UNICODE(文本存储在16位WCHAR字段中)或ANSI构建(其中文本存储在8位CHAR字段中)的代码。 strxxx_s
函数中的str前缀表示您使用的字符串函数只处理8位字符串。然而,Shell上的W函数是Windows API宣传函数期望UNICODE字符串的方式。
要“纠正”你的程序,你需要选择(a)目标ANSI,(b)目标UNICODE,或(c)两者都取决于编译器设置并适当地重写它。 'both'选项将写成:
TCHAR AppDir[MAX_PATH];
TCHAR SetPath[MAX_PATH];
ITEMIDLIST* pidl;
HRESULT hRes = SHGetSpecialFolderLocation( NULL, CSIDL_COMMON_APPDATA|CSIDL_FLAG_CREATE ,&pidl );
SHGetPathFromIDList(pidl, AppDir);
_tcscpy_s(SetPath,AppDir);
_tcscat_s(SetPath,_T("\Keylogger"));
SHCreateDirectoryEx(hWnd,SetPath,NULL);
_tcscat_s(SetPath,_T("\SnapShot"));
SHCreateDirectoryEx(hWnd,SetPath,NULL);
我们放弃了(错误的)类型转换。将strxxx_s
函数替换为_tcsxxx_s
版本。并在_T()
宏中包装了字符串文字,确保在定义_UNICODE
时它们是宽字符串,否则为正常的ansi字符串。
答案 1 :(得分:0)
您似乎正在混合使用单字节和单字符串函数。
strcpy_s
和strcat_s
用于单字节字符串
SHCreateDirectoryExW
用于unicode宽字符串。
尝试使用SHCreateDirectoryEx。