2011-11-28 7 views
5

Ho un problema nel tentativo di eseguire Winapi::findFirstFile in esecuzione sul server. Ho havve già provato a copiare il metodo sul WinapiServer di classe, e cambiando alcune linee, in questo modo:Prova ad utilizzare Winapi :: findFirstFile in esecuzione sul server

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

Ma ora ho un altro tipo di errore La funzione 'FindFirstFileW' sulla DLL library 'KERNEL32' lancia un'eccezione

Questo perché sto eseguendo il metodo su un server x64. Chiunque abbia un'idea per risolvere questo problema?

+0

Hai specificato l'esatto messaggio di errore dal registro delle informazioni? –

+0

Che eccezione lancia? Forse AX lancia, dato che WinAPI non lancia eccezioni, restituisce i codici di errore. Prova 'WinAPIServer :: getLastError()' per ottenere il codice di errore –

risposta

6

Ecco un esempio di codice che ha funzionato per me sia lato client che lato server. Utilizza gli spazi dei nomi .NET per recuperare l'elenco di file in un determinato percorso della cartella per un dato motivo.

È possibile modificare questo per creare la propria versione lato server di FindFirstFile metodo.

X ++ Codice

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

lavoro di prova

Per verificare il codice di cui sopra, ho creato i seguenti file di esempio nel percorso C:\temp\Files\

List of files

Ho inserito il metodo sopra indicato in una classe di esempio denominata Tutorial_WinApiServer. Quindi, ha creato un lavoro denominato fetchFiles con il seguente codice.

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

L'esecuzione del lavoro ha dato il seguente output.

Job Output 1

Dopo aver cambiato il modello di file per F *. *, il lavoro ha prodotto il seguente risultato.

Job Output 2

Speranza che aiuta.

0

Ho trovato che le classi .NET si aspettano un System.String invece di uno str.Facendo riferimento a:

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

Quando si compila il CIL ottengo:

Non è possibile creare un record in informazioni Compiler (TmpCompilerOutput). Percorso: \ Classes \\, Avviso: nessun proxy trovato. Digitare FileIOPermission trovato nello stack. Questo codice in Classe:, Metodo:.

La mia soluzione è assegnare _folderPath a un System.String.