Try to use Winapi::findFirstFile running on server

ⅰ亾dé卋堺 提交于 2019-12-06 03:55:59

问题


I have a problem trying to run Winapi::findFirstFile running on server. I havve already tried copying the method on the class WinapiServer, and changing some lines, like this:

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)];
}

But now I have another kind of error The function 'FindFirstFileW' on the library DLL 'KERNEL32' throws an exception.

This is because I'm executing the method on a x64 server. Anyone with an idea for solving this problem?


回答1:


Here is a sample code that has worked for me in both client side as well as server side. It uses .NET namespaces to fetch the list of files in a given folder path for a given pattern.

You can modify this to create your own server side version of FindFirstFile method.

X++ Code

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;
}

Test job

To test the above code, I created the following sample files in the path C:\temp\Files\

I placed the above mentioned method in a sample class named Tutorial_WinApiServer. Then, created a job named fetchFiles with the following code.

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);
    }
}

Executing the job gave the following output.

After changing the file pattern to F*.*, the job produced the following output.

Hope that helps.




回答2:


Maybe it's better to use the .NET framework?

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

Check if someone else has done this for you.




回答3:


I've found that .NET classes expect a System.String instead of a str. Refering to:

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

When compiling the CIL I get:

Cannot create a record in Compiler information (TmpCompilerOutput). Path: \Classes\\, Warning: No proxy found. Type FileIOPermission found on the stack. This code in Class: , Method: .

My solution is to assign _folderPath to a System.String.



来源:https://stackoverflow.com/questions/8300111/try-to-use-winapifindfirstfile-running-on-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!