Попробуйте использовать Winapi :: findFirstFile на сервере - PullRequest
5 голосов
/ 28 ноября 2011

У меня проблема при попытке запустить Winapi::findFirstFile на сервере. Я уже пытался скопировать метод в классе WinapiServer и изменить некоторые строки, например:

server static container findFirstFile(str filename)
{
    InteropPermission interopPerm;
    Binary data;
    DLL _winApiDLL;
    DLLFunction _findFirstFile;
    ;

    interopPerm = new InteropPermission(InteropKind::DllInterop);
    interopPerm.assert();

    data = new Binary(592); // size of WIN32_FIND_DATA when sizeof(TCHAR)==2
    _winApiDLL = new DLL(#KernelDLL);
    _findFirstFile = new DLLFunction(_winApiDLL, 'FindFirstFileW');

    _findFirstFile.returns(ExtTypes::DWord);

    _findFirstFile.arg(ExtTypes::WString,ExtTypes::Pointer);

    return [_findFirstFile.call(filename, data),data.wString(#offset44)];
}

Но теперь у меня другая ошибка Функция 'FindFirstFileW' в библиотеке DLL 'KERNEL32' выдает исключение.

Это потому, что я выполняю метод на сервере x64. Кто-нибудь с идеей для решения этой проблемы?

Ответы [ 3 ]

6 голосов
/ 29 ноября 2011

Вот пример кода, который работал для меня как на стороне клиента, так и на стороне сервера. Он использует пространства имен .NET для получения списка файлов в заданном пути к папке для заданного шаблона.

Вы можете изменить это, чтобы создать собственную версию FindFirstFile на стороне сервера.

X ++ Код

static container findMatchingFiles(
        str _folderPath
    ,   str _filePattern   = '*.*')
{
    System.IO.DirectoryInfo     directory;
    System.IO.FileInfo[]        files;
    System.IO.FileInfo          file;
    InteropPermission           permission;

    str         fileName;
    counter     filesCount;
    counter     loop;
    container   mathchingFiles;
    ;

    permission  = new InteropPermission(InteropKind::ClrInterop);
    permission.assert();

    directory   = new System.IO.DirectoryInfo(_folderPath);
    files       = directory.GetFiles(_filePattern);
    filesCount  = files.get_Length();

    for (loop = 0; loop < filesCount; loop++)
    {
        file            = files.GetValue(loop);
        fileName        = file.get_FullName();
        mathchingFiles  = conins(mathchingFiles, conlen(mathchingFiles) + 1, fileName);
    }

    CodeAccessPermission::revertAssert();

    return mathchingFiles;
}

Тестовое задание

Чтобы проверить приведенный выше код, я создал следующие файлы примеров по пути C:\temp\Files\

List of files

Я поместил вышеупомянутый метод в учебный класс с именем Tutorial_WinApiServer . Затем создал задание с именем fetchFiles со следующим кодом.

static void fetchFiles(Args _args)
{
    container   files;
    counter     loop;
    str         fileName;
    ;

    files = Tutorial_WinApiServer::findMatchingFiles(@'C:\temp\Files', '*.txt');

    for (loop = 1; loop <= conlen(files); loop++)
    {
        fileName = conpeek(files, loop);
        info(fileName);
    }
}

Выполнение задания дало следующий вывод.

Job Output 1

После изменения шаблона файла на F *. * задание выдает следующий вывод.

Job Output 2

Надеюсь, это поможет.

0 голосов
/ 22 октября 2015

Я обнаружил, что классы .NET ожидают System.String вместо str. Ссылаясь на:

directory   = new System.IO.DirectoryInfo(_folderPath);

При компиляции CIL я получаю:

Не удается создать запись в информации компилятора (TmpCompilerOutput). Путь: \ Classes \\, Предупреждение: прокси не найден. Тип FileIOPermission найден в стеке. Этот код в классе:, Метод:.

Мое решение - назначить _folderPath для System.String.

0 голосов
/ 28 ноября 2011

Может быть, лучше использовать .NET Framework?

http://greg.agiletortoise.com/2007/04/02/dynamics-ax-making-net-calls-from-inside-ax/

Проверьте, сделал ли это кто-то другой для вас.

...