Eu criei um aplicativo que baixa todas as bibliotecas de documentos em um site SP, mas em um ponto ele me deu este erro (eu tentei procurar no google mas não consegui encontrar nada, agora se alguém souber de algum truque para resolver este problema, responda caso contrário, obrigado para olhar para ele)
System.IO.PathTooLongException: o caminho especificado, o nome do arquivo ou ambos são muito longos. O nome completo do arquivo deve ter menos de 260 caracteres e o nome do diretório deve ter menos de 248 caracteres. em System.IO.Path.NormalizePathFast (String path, Boolean fullCheck) em System.IO.Path.GetFullPathInternal (String path) em System.IO.FileStream.Init (String path, modo FileMode, acesso FileAccess, direitos Int32, Boolean useRights , Compartilhamento FileShare, Int32 bufferSize, opções FileOptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) em System.IO.FileStream..ctor (String path, modo FileMode, acesso FileAccess, compartilhamento FileShare, Int32 bufferSize, opções FileOptions) em System. IO.File.Create (String caminho)
atinge o limite de string, o código é fornecido abaixo,
#region Downloading Schemes
private void btnDownload_Click(object sender, EventArgs e)
{
TreeNode currentNode = tvWebs.SelectedNode;
SPObjectData objectData = (SPObjectData)currentNode.Tag;
try
{
CreateLoggingFile();
using (SPWeb TopLevelWeb = objectData.Web)
{
if(TopLevelWeb != null)
dwnEachWeb(TopLevelWeb, TopLevelWeb.Title, tbDirectory.Text);
}
}
catch (Exception ex)
{
Trace.WriteLine(string.Format("Exception caught when tried to pass TopLevelWeb:{1}, Title = {2}, object data to (dwnEachWeb_method), Exception: {0}", ex.ToString(), objectData.Web, objectData.Title));
}
finally
{
CloseLoggingFile();
}
}
private void dwnEachWeb(SPWeb TopLevelWeb, string FolderName, string CurrentDirectory)
{
if (TopLevelWeb != null)
{
if (TopLevelWeb.Webs != null)
{
CurrentDirectory = CurrentDirectory + "\\" + TopLevelWeb.Title;
CreateFolder(CurrentDirectory);
foreach (SPWeb ChildWeb in TopLevelWeb.Webs)
{
dwnEachWeb(ChildWeb, ChildWeb.Title, CurrentDirectory);
ChildWeb.Dispose();
}
dwnEachList(TopLevelWeb, CurrentDirectory);
//dwnEachList(TopLevelWeb, FolderName, CurrentDirectory);
}
}
}
private void dwnEachList(SPWeb oWeb, string CurrentDirectory)
{
foreach (SPList oList in oWeb.Lists)
{
if (oList is SPDocumentLibrary && !oList.Hidden)
{
dwnEachFile(oList.RootFolder, CurrentDirectory);
}
}
}
private void dwnEachFile(SPFolder oFolder, string CurrentDirectory)
{
if (oFolder.Files.Count != 0)
{
CurrentDirectory = CurrentDirectory + "\\" + oFolder.Name;
CreateFolder(CurrentDirectory);
foreach (SPFile ofile in oFolder.Files)
{
if (CreateDirectoryStructure(CurrentDirectory, ofile.Url))
{
var filepath = System.IO.Path.Combine(CurrentDirectory, ofile.Url);
byte[] binFile = ofile.OpenBinary();
System.IO.FileStream fstream = System.IO.File.Create(filepath);
fstream.Write(binFile, 0, binFile.Length);
fstream.Close();
}
}
}
}
//creating directory where files will be download
private bool CreateDirectoryStructure(string baseFolder, string filepath)
{
if (!Directory.Exists(baseFolder)) return false;
var paths = filepath.Split('/');
for (var i = 0; i < paths.Length - 1; i++)
{
baseFolder = System.IO.Path.Combine(baseFolder, paths[i]);
Directory.CreateDirectory(baseFolder);
}
return true;
}
//creating folders
private bool CreateFolder(string CurrentDirectory)
{
if (!Directory.Exists(CurrentDirectory))
{
Directory.CreateDirectory(CurrentDirectory);
}
return true;
}
//shorting string
#endregion
Respostas:
Como a causa do erro é óbvia, aqui estão algumas informações que devem ajudá-lo a resolver o problema:
Consulte este artigo da MS sobre como nomear arquivos, caminhos e namespaces
Aqui está uma citação do link:
E algumas soluções alternativas (retiradas dos comentários):
Existem maneiras de resolver os vários problemas. A ideia básica das soluções listadas abaixo é sempre a mesma: Reduza o comprimento do caminho para ter
path-length + name-length < MAX_PATH
. Você pode:fonte
Starting in Windows 10, version 1607, MAX_PATH limitations have been removed from common Win32 file and directory functions.
mas você deve ativá-lo e definir uma chave de registro para ativá-lo.A solução que funcionou para mim foi editar a chave do registro para permitir o comportamento de caminho longo, definindo o valor como 1. Este é um novo recurso opcional para Windows 10
HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Type: REG_DWORD)
Eu obtive essa solução de uma seção nomeada do artigo que @james-hill postou.
https://docs.microsoft.com/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
fonte
<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings xmlns:ws2="https://schemas.microsoft.com/SMI/2016/WindowsSettings"> <ws2:longPathAware>true</ws2:longPathAware> </windowsSettings> </application>
para mim no Visual Studio 2019, esse segundo requisito não era necessário após reiniciar o Visual Studio.Existe uma biblioteca chamada Zeta Long Paths que fornece uma API .NET para trabalhar com caminhos longos.
Aqui está um bom artigo que aborda esse problema para .NET e PowerShell: " .NET, PowerShell Path too Long Exception e um .NET PowerShell Robocopy Clone "
fonte
Você pode criar um link simbólico com um diretório mais curto. Primeiro abra a linha de comando, por exemplo, por
Shift + RightClick
na pasta desejada com um caminho mais curto (você pode ter que executá-lo como administrador).Em seguida, digite com caminhos relativos ou absolutos:
Em seguida, inicie a solução a partir do caminho mais curto. A vantagem aqui é: você não precisa mover nada.
fonte
No Windows 8.1, usando. NET 3.5, tive um problema semelhante.
Embora o nome do meu arquivo tivesse apenas 239 caracteres, quando fui instanciar um objeto FileInfo apenas com o nome do arquivo (sem caminho), ocorreu uma exceção do tipo System. IO.PathTooLongException
Resolvi o problema reduzindo o nome do arquivo para 204 caracteres (extensão incluída).
fonte
Se você estiver tendo um problema com seus arquivos bin devido a um longo caminho, no Visual Studio 2015 você pode ir para a página de propriedades do projeto ofensivo e alterar o diretório de saída relativo para um mais curto.
Por exemplo, bin \ debug \ torna-se C: \ _ bins \ MyProject \
fonte
O que funcionou para mim foi mover meu projeto como estava na área de trabalho (C: \ Users \ lachezar.l \ Desktop \ MyFolder) para (C: \ 0 \ MyFolder) que, como você pode ver, usa um caminho mais curto e reduzi-lo resolveu o problema.
fonte
Pela minha experiência, não recomendarei minha resposta abaixo para nenhum aplicativo da Web voltado ao público.
Se você precisar dele para suas ferramentas internas ou para testes, recomendo compartilhá-lo em sua própria máquina.
Isso criará um diretório compartilhado como \\ {PCName} \ {YourSharedRootDirectory} Isso pode ser definitivamente muito menos do que seu caminho completo, espero, para mim eu poderia reduzir para 30 caracteres de cerca de 290 caracteres. :)
fonte
Sem mencionar até agora e uma atualização, há uma biblioteca muito bem estabelecida para lidar com caminhos que são muito longos. AlphaFS é uma biblioteca .NET que fornece funcionalidade de sistema de arquivos Win32 mais completa para a plataforma .NET do que as classes System.IO padrão. A deficiência mais notável do .NET System.IO padrão é a falta de suporte de recursos NTFS avançados, mais notavelmente suporte de caminho de comprimento estendido (por exemplo, caminhos de arquivo / diretório com mais de 260 caracteres).
fonte
A melhor resposta que posso encontrar está em um dos comentários aqui. Adicionando-o à resposta para que alguém não perca o comentário e com certeza tente fazer isso. Ele corrigiu o problema para mim.
Precisamos mapear a pasta de solução para uma unidade usando o comando "subst" no prompt de comando - por exemplo, subst z:
E então abra a solução desta unidade (z neste caso). Isso encurtaria o caminho o máximo possível e resolveria o problema de nomes de arquivo longos.
fonte
isso também pode ser a solução. Algumas vezes também ocorre quando você mantém seu projeto de desenvolvimento muito profundo, o que significa que pode ser possível que o diretório do projeto tenha muitos diretórios, portanto, não faça muitos diretórios mantê-lo em uma pasta simples dentro do unidades. Por exemplo - eu também estava recebendo este erro quando meu projeto foi mantido assim -
D: \ Sharad \ LatestWorkings \ GenericSurveyApplication020120 \ GenericSurveyApplication \ GenericSurveyApplication
então simplesmente colei meu projeto dentro
D: \ Sharad \ LatestWorkings \ GenericSurveyApplication
E o problema foi resolvido.
fonte