winapif#

Win32 api call Error GetShortPathName in f#


I can get this code to run in the interactive environment but it crashes when I run the code from debugger or from the .exe file.

The error:

FatalExecutionEngineError was detected! The runtime has encountered a fatal error. The address of the error was at 0x6c9781b0, on thread 0x1104. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.

Using .net 4.5

open System.IO
open System.Runtime.InteropServices
open System.Text

[<DllImport("kernel32.dll",CharSet = CharSet.Auto, SetLastError=true)>]
extern uint32 GetShortPathName(
    [<MarshalAs(UnmanagedType.LPWStr)>] string longpath, 
    [<MarshalAs(UnmanagedType.LPWStr)>] StringBuilder shortpath, 
    [<MarshalAs(UnmanagedType.U4)>] uint32  item)

let MakeShortName(longPath : string) =
    let sb =  StringBuilder()
    let currPath = longPath
    let item = 1024u

   // let blah = ""
    //win32 assigns shortPath
    let blah32 = GetShortPathName(currPath, sb, item)

    sb.ToString()

[<EntryPoint>]
let main argv = 

    let path = @"C:\dev\shortName\shortName"
    let shorty = MakeShortName path
    printfn "%s" shorty 
    let x = System.Console.ReadKey()
    
    0

Interactive env:

$ (me alt+entering the above two functions)

val GetShortPathName : string * StringBuilder * uint32 -> uint32
val MakeShortName : string -> string

$ MakeShortName @"C:\dev\shortName\shortName";;
val it : string = "C:\dev\SHORTN~1\SHORTN~1"

Solution

  • Fixed it.

    I just suck @ win 32

    Removed marshals

    See solution:

    open System.IO
    open System.Runtime.InteropServices
    open System.Text
    
    [<DllImport("kernel32.dll",CharSet = CharSet.Auto, SetLastError=true)>]
    extern int GetShortPathName(
        string longpath, 
        StringBuilder shortpath, 
        int  item)
    
    let MakeShortName(longPath : string) =
        let sb =  StringBuilder()
        let currPath = longPath
        let item = 1024
    
       // let blah = ""
    //win32 assigns shortPath
        let blah32 = GetShortPathName(currPath, sb, item)
    
        sb.ToString()
    
    [<EntryPoint>]
    let main argv = 
    
    let path = @"C:\dev\shortName\shortName"
    let shorty = MakeShortName path
    printfn "%s" shorty 
    let x = System.Console.ReadKey()
    
    0