gpt4 book ai didi

c# - 帮助在C#中使用PInvoke CreateDirectory()

转载 作者:行者123 更新时间:2023-12-05 01:48:55 30 4
gpt4 key购买 nike

我在 VS2010 中将 C# 用于 WinForms 应用程序,我需要创建一个目录,其中的路径对于 .NET 方法来说太大(我相信 248 个字符限制),并遇到了来自谷歌的建议以使用 Unicode Win32 创建目录()。我最初尝试使用 Unicode 调用它并传递参数,但在几次尝试失败后,我减少了代码并使用了完全在这里找到的代码:

http://www.pinvoke.net/default.aspx/Structures/SECURITY_ATTRIBUTES.html

我仍然遇到同样的错误:

System.AccessViolationException 被捕获 Message=试图读取或写入 protected 内存。这通常表明其他内存已损坏。

不可否认,我对调用 Win32 函数一无所知,我真的只是在网上找到我能找到的东西并尝试学习。谁能告诉我我做错了什么?删除问题的非必要代码,我有:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Text;

namespace RFCGenerator
{

[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}

public class RFC
{

[DllImport("kernel32.dll")]
static extern bool CreateDirectory(string lpPathName, SECURITY_ATTRIBUTES lpSecurityAttributes);

protected void CopyDirectory(Uri Source, Uri Destination)
{

SECURITY_ATTRIBUTES lpSecurityAttributes = new SECURITY_ATTRIBUTES();
DirectorySecurity security = new DirectorySecurity();
lpSecurityAttributes.nLength = Marshal.SizeOf(lpSecurityAttributes);
byte[] src = security.GetSecurityDescriptorBinaryForm();
IntPtr dest = Marshal.AllocHGlobal(src.Length);
Marshal.Copy(src, 0, dest, src.Length);
lpSecurityAttributes.lpSecurityDescriptor = dest;
string path = @"C:\Test";
CreateDirectory(path, lpSecurityAttributes);
}
}
}

更新:根据 Hans 的建议,我确实让它在本地工作。但是,当我尝试使用 UNC 地址创建目录时,例如传入:

 path = @"\\mydomain.com\foo\bar\newfolder"

我现在得到:

System.ComponentModel.Win32Exception 被捕获 Message=文件名、目录名或卷标语法不正确

我已验证\\mydomain.com\foo\bar\确实存在。

解决方案:

使用 Hans 的代码和一个小的修改来检查它是否是 UNC 路径(引用:http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx,在“最大路径长度限制”下):

string UnicodePath = (path.StartsWith(@"\\")) ? @"\\?\UNC\" + (path.Remove(0, 2)) : @"\\?\" + path;
if (!CreateDirectory(UnicodePath, IntPtr.Zero))
throw new System.ComponentModel.Win32Exception();

最佳答案

您没有使用 Unicode 版本,它需要 [DllImport] 声明中的 CharSet = CharSet.Unicode。此外,创建具有长名称的目录与安全属性无关。您必须在名称前加上 @"\\?\"。因此:

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool CreateDirectory(string lpPathName, IntPtr lpSecurityAttributes);
...
if (!CreateDirectory(@"\\?\" + path, IntPtr.Zero))
throw new Win32Exception();

关于c# - 帮助在C#中使用PInvoke CreateDirectory(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3576657/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com