尝试使用在服务器上运行的Winapi :: findFirstFile

时间:2011-11-28 17:53:49

标签: axapta dynamics-ax-2009 ax

尝试在服务器上运行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)];
}

但现在我又出现了另一种错误 库DLL'KERNEL32'上的'FindFirstFileW'函数抛出异常。

这是因为我在x64服务器上执行该方法。 有想法解决这个问题的人吗?

3 个答案:

答案 0 :(得分:6)

以下是在客户端和服务器端都为我工作的示例代码。它使用.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

希望有所帮助。

答案 1 :(得分:0)

使用.NET框架可能更好吗?

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

检查其他人是否已为您完成此操作。

答案 2 :(得分:0)

我发现.NET类需要System.String而不是str。参考:

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

编译CIL时我得到:

  

无法在编译器信息(TmpCompilerOutput)中创建记录。   路径:\ Classes \\,警告:未找到代理。类型   在堆栈上找到FileIOPermission。这个代码在Class:中,   方法:。

我的解决方案是将_folderPath分配给System.String。