Открытие 64-битных файлов Windows - PullRequest
2 голосов
/ 01 августа 2011

Я пытаюсь использовать диалоговое окно, чтобы открыть файл в моей программе. Это прекрасно работает в 32-битной системе, но когда я пытаюсь использовать его в 64-битной системе, он не может открыть файл. Я понял, что если файл, который пытается открыть, находится в том же каталоге, что и моя программа, он работает нормально. Однако попытка открыть файл из другой папки не работает вообще.

Итак, я попытался скопировать файл в папку программы. Это также отлично работает на 32-битной, но не работает на 64-битной системе. Есть мысли почему?

char cwdl[500];
getcwd(cwdl,500);
string mystring = string(cwdl);

CFileDialog fileDlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, "All Files (*.*)|*.*||", this);
fileDlg.m_ofn.lpstrTitle = "Select New File";
if( fileDlg.DoModal() == IDOK)
{

    CString newFile= fileDlg.GetFileName();
    mystring+="\\"+newFile;
    const char * newLoc = mystring.c_str(); 
    CopyFile(newFile,newLoc,true);

это всего лишь фрагмент кода.

Ответы [ 2 ]

1 голос
/ 03 августа 2011

UAC и перенаправление файловой системы связаны, но различаются.

Контроль учетных записей пользователей - это защита, основанная на разрешениях, для предотвращения несанкционированного изменения вашей файловой системы или запуска приложений, которые могут повлиять на других пользователей. Подсказка позволяет вам переопределить безопасность, временно предоставив привилегии администратора, если это было вашим намерением.

Перенаправление файловой системы обеспечивает обратную совместимость с 32-битными приложениями благодаря наличию зеркальных 32-битных системных папок и реестра. Фактически, если действие приводит к тому, что UAC не запускает перенаправление, в этом случае он всегда будет пытаться использовать 64-битную версию файла. Если вы не укажете каталог перенаправления явно или не запустите 32-битное приложение с правами администратора для обхода UAC.

Хорошо, это говорит о том, что вы используете относительный путь, поэтому он будет искать файл в текущем каталоге для процесса. Если он скомпилирован как 32-разрядный процесс, выполняющийся в системах с разными архитектурами, он может не работать должным образом из-за вышеупомянутого перенаправления.

Вы можете использовать GetCurrentDirectory Windows API, чтобы увидеть, какой каталог использует текущий процесс, и убедиться, что он соответствует вашим ожиданиям. Если нет, у вас есть несколько вариантов.

  • Самый простой способ - использовать полные пути к файлам.
  • У вас также может быть две сборки, одна из которых предназначена для каждой архитектуры, на которой вы собираетесь развернуть. В конце концов, если вы работаете в 64-битной системе, вы также можете развернуть 64-битные приложения.
  • Более сложным вариантом будет создание подкласса CFileDialog и отключение перенаправления путем вызова Wow64DisableWow64FsRedirection в конструкторе и Wow64RevertWow64FsRedirection в десктрукторе. Однако это должен быть системный параметр, поэтому вы можете столкнуться с новыми проблемами, принудительно установив 32-битное приложение в 64-битных окнах.

Вероятно, существует множество других вариантов, так как обычно существует много способов снять шкуру с кошки. Однако первым шагом является установка некоторого кода отладки и проверка или устранение перенаправления как виновника с GetCurrentDirectory

0 голосов
/ 01 сентября 2013

Может быть, это только я, но я вижу странный результат: в 64-битном режиме первые четыре байта буфера, используемого для хранения местоположения пути, заполнены нулями.

char wk[_MAX_PATH];
char *ret = _getcwd(wk, _MAX_PATH);  // wk = "\0\0\0\0C:\\MyFolder\\..."
                                     // ret = "C:\\MyFolder\\..."

Возвращаемое значение OTOH является правильным. «ret» указывает на wk + 4;

В 32-битном режиме начальных нулей нет, путь начинается с первого байта. Примечание: это многобайтовое приложение, а не Unicode.

Я использую Visual Studio 2010 (10.0.40219.1 SP1Rel).

В любом случае, если вы получите тот же результат, это объяснит, почему ваш пример не работает. Вы должны сказать (только в 64-битном режиме):

string mystring = string(cwdl + 4);   // 64-bit only

Странно или что?

Редактировать: Кажется, проблема с выравниванием. Работает нормально, если _getcwd находится в отдельной функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...