5

我可以让这段代码在交互式环境中运行,但是当我从调试器或 .exe 文件运行代码时它会崩溃

忘记错误:检测到 FatalExecutionEngineError!运行时遇到致命错误。错误地址位于线程 0x1104 上的 0x6c9781b0。错误代码为 0xc0000005。此错误可能是 CLR 中的错​​误或用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括 COM 互操作或 PInvoke 的用户封送错误,这可能会损坏堆栈。

使用.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

交互式环境


$ (me alt+进入上面两个函数)

val GetShortPathName : 字符串 * StringBuilder * uint32 -> uint32 val MakeShortName : 字符串 -> 字符串

$ MakeShortName @"C:\dev\shortName\shortName";; 验证它:字符串 = "C:\dev\SHORTN~1\SHORTN~1"

4

2 回答 2

4

修复。

我只是吸@win 32

删除了元帅

查看解决方案:

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
于 2012-05-24T19:12:01.393 回答
0

Win32 函数可能需要最大大小的预分配缓冲区。对我来说,这段代码修复了崩溃:

let MakeShortName(longPath : string) =
    let maxSize = uint32 <| longPath.Length + 16
    let sb =  new StringBuilder("", int32 maxSize)
    let len = GetShortPathName(longPath, sb, maxSize)
    sb.ToString(0, int32 len)
于 2018-03-19T18:53:01.677 回答