J'utilise C# pour l'application WinForms dans VS2010 et je devais créer un répertoire dans lequel le chemin était trop grand pour les méthodes .NET (limite de 248 caractères, je crois) et fonctionnait à travers les suggestions de google pour utiliser le Unicode Win32 CreateDirectory(). Je l'avais d'abord essayé d'appeler à l'aide d'Unicode et passé paramètres, mais après plusieurs tentatives infructueuses, j'ai réduit le code et je EXACTEMENT en utilisant le code trouvé ici:Aide en utilisant PInvoke CreateDirectory() en C#
http://www.pinvoke.net/default.aspx/Structures/SECURITY_ATTRIBUTES.html
Je reçois toujours la même erreur:
System.AccessViolationException a été interceptée Message = Tentative de lecture ou d'écriture de la mémoire protégée. C'est souvent une indication que l'autre mémoire est corrompue.
Certes, je ne sais rien à propos de l'appel des fonctions Win32, je suis vraiment juste en train de tirer ce que je peux trouver en ligne et en essayant d'apprendre. Quelqu'un peut-il me dire ce que je fais mal? Suppression du code non essentiel pour la question, j'ai:
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);
}
}
}
MISE À JOUR: en utilisant la suggestion de Hans, je l'ai fait que cela fonctionne au niveau local. Cependant, lorsque je tente de créer un répertoire en utilisant une adresse UNC, comme en passant:
path = @"\\mydomain.com\foo\bar\newfolder"
-je obtenir maintenant:
System.ComponentModel.Win32Exception a été capturé message = Le nom de fichier, nom de répertoire, ou la syntaxe d'étiquette de volume est incorrecte
J'ai vérifié que \\ mydomain.com \ foo \ bar \ existe.
SOLUTION:
En utilisant le code de Hans et une modification mineure pour vérifier si elle est un chemin UNC (référence: http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx, sous "Longueur maximale du chemin Limitation"):
string UnicodePath = (path.StartsWith(@"\\")) ? @"\\?\UNC\" + (path.Remove(0, 2)) : @"\\?\" + path;
if (!CreateDirectory(UnicodePath, IntPtr.Zero))
throw new System.ComponentModel.Win32Exception();
question rapide: Avez-vous essayé de changer dans la racine du lecteur C, puis de définir path = "Test"? Cela fait longtemps que j'ai travaillé avec l'API Win32 dans la capacité, mais je crois me rappeler que l'API Win32 ne fonctionne que sur les composants de chemin, pas sur le chemin complet. – DevSolo