2017-02-02 7 views
1

Я пытаюсь записать файл во временную папку, но он не выполняется должным образом. Когда я позже перейду в код для вызова этого, он ссылается на правильное местоположение, но говорит, что его не существует. Любые идеи относительно того, что я делаю неправильно?Как записать во временную папку

 ofstream fout("%TEMP%\\test.bat"); 
     fout << "cd C:\\Users\\jrowler\\Documents" << endl; 
     //Some more fout commands to write to bat 
     fout.close(); 
     wchar_t cmdline[] = L"cmd.exe /C %TEMP%\\test.bat"; 

if (!CreateProcess(NULL, cmdline, NULL, NULL, false, CREATE_UNICODE_ENVIRONMENT, 
     (LPVOID)env.c_str(), NULL, &si, &pi)) 
    { 
     std::cout << GetLastError(); 
     abort(); 
    } 

Все работает, если я не пытаюсь использовать папку TEMP. Если бы я хотел поставить его на рабочий стол, он отлично работает. Любые идеи, почему переменная среды работает неправильно при создании, но при попытке создать процесс она дает мне ошибку, которая ссылается на правильное местоположение, заданное переменной окружения.

+6

'fstream' ничего не знает о расширении переменных среды Windows. Вы захотите захватить переменную и сделать это сами. https://msdn.microsoft.com/en-us/library/windows/desktop/ms683188(v=vs.85).aspx –

+0

Есть ли что-нибудь еще, что я могу предоставить, чтобы ответить на этот вопрос? – Jeff

+0

нет, это было потрясающе! извините за задержку принятия! –

ответ

8

Как указано выше, ниндзя указывает, что вы можете использовать translate the environment variable, если вы решите использовать переменную окружения.

Кроме того, существуют другие методы для специальных папок. Фактически, временная папка имеет специальную функцию - GetTempPath().

DWORD const bufferSize = ::GetTempPath(0u, nullptr) + 1u; // get the necessary buffer size 
ASSERT(bufferSize); 

wchar_t* buffer = new wchar_t[bufferSize]; 
std::memset(buffer, 0x00, bufferSize); 
VERIFY(::GetTempPath(bufferSize, &buffer[0u])); 
// [ perform various logic ] 
delete[] buffer; 

Для других специальных папок вы можете использовать API-интерфейс Shell.

SHGetFolderPath() и SHGetKnownFolderPath() хорошо работают в различных версиях окон, где может находиться целевая папка. И есть tremendous number of folders.

wchar_t folder[MAX_PATH+1]; 
int const folderId = ... // <-- defined in Shlobj.h 

HRESULT const hr = ::SHGetFolderPath(nullptr, folderId, nullptr, SHGFP_TYPE_CURRENT, folder); 
if (S_OK != hr) 
{ 
    TRACE("ERROR: Unable to get folder path."); 
    return false; 
} 

// [ perform various logic ] 

wchar_t* folder = nullptr; 
KNOWNFOLDERID const folderId = ... // <-- defined in KnownFolder.h 
HRESULT const hr = ::SHGetKnownFolderPath(folderId, 0u, nullptr, &folder); 
if (S_OK != hr) 
{ 
    TRACE("ERROR: Unable to get folder path."); 
    return false; 
} 

// [ perform various logic ] 
::CoTaskMemFree(folder); 

EDIT: Существует пример специально для creating and using a temp file.

EDIT2: Обратите внимание, что TEMP/TMP environment variables may be slightly different on various systems. Однако они должны быть одинаковыми. Посмотрите раздел «примечания» GetTempPath(), чтобы узнать, как определяется путь.

+1

О, WinAPI, ты такой уродлив. –

+0

@GillBates: Как бы вы его улучшили? Не допускается обман. Для вашей улучшенной версии нужен интерфейс C. – IInspectable

+0

Поскольку вы используете C++, нет никаких оснований идти с ручным управлением памятью или ручным обнулением буфера. Просто используйте 'std :: vector buffer (bufferSize);' и получите все это бесплатно (включая потенциальную безопасность исключений). – IInspectable

 Смежные вопросы

  • Нет связанных вопросов^_^