AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79369963
Accepted
Zeek Joseph
Zeek Joseph
Asked: 2025-01-20 07:35:27 +0800 CST2025-01-20 07:35:27 +0800 CST 2025-01-20 07:35:27 +0800 CST

Ponto e vírgula do Windows no caminho

  • 772

Estou trabalhando em um programa do Windows que adiciona valores à variável de ambiente PATH . A variável PATH é delimitada por ponto e vírgula ( ;), e qualquer caminho de pasta válido pode ser incluído. No entanto, ;é válido em caminhos de pasta, então caminhos contendo ponto e vírgula devem ser colocados entre aspas duplas ao serem adicionados ao caminho:

C:\Program Files (x86);"C:\;My Folder";C:\Program Files

Para evitar esse problema com ponto e vírgula, meu programa envolve todos os caminhos entre aspas duplas. No entanto, alguém me informou recentemente que o Powershell não funciona com valores entre aspas na variável PATH, pois ele trata as aspas como caracteres comuns:

Observei como o PowerShell manipula a variável Path (com base neste código: PowerShell/PowerShell@16176ef/src/System.Management.Automation/engine/CommandDiscovery.cs#L1187-L1240). Pelo que posso perceber, o PowerShell não remove aspas duplas - ele apenas divide os caminhos sempre que vê um ponto e vírgula.

Então, o valor PATH C:\Program Files (x86);"C:\;My Folder";C:\Program Filesé interpretado incorretamente assim (se entendi corretamente o que está acontecendo):

C:\Program Files (x86)
"C:\
My Folder"
C:\Program Files

Aqui está um vídeo demonstrando o comportamento (isso só ocorre com o Powershell, não com o cmd): https://www.mediafire.com/file/aih2ky9fz07x5w0/powershellpathwithsemicolonsbug.mp4/file

Qual é a melhor maneira para meu programa lidar com isso? E, mais urgentemente, por que o Powershell não funciona com valores PATH que têm aspas (embora o CMD faça)? Editar o valor do caminho para incluir ponto e vírgula usando o modo manual - Edit the system environment variables -> Path -> Edit- faz com que o Windows envolva automaticamente os caminhos necessários entre aspas, quebrando o Powershell. Então, isso não é um problema com meu programa ou situação - é um problema inerente com a forma como o Powershell processa o PATH.

Esse comportamento é intencional no Powershell? E há uma solução alternativa, ou terei que chegar a um acordo A. Envolvendo caminhos que contêm ponto e vírgula entre aspas e permitindo que esse comportamento de bug ocorra ou B. não permitindo ponto e vírgula em PATH?

windows
  • 2 2 respostas
  • 99 Views

2 respostas

  • Voted
  1. Best Answer
    mklement0
    2025-01-21T06:04:30+08:002025-01-21T06:04:30+08:00

    A resposta útil do iRon mostra como você pode analisar o $env:PATHvalor manualmente de uma maneira que respeite entradas entre aspas duplas.


    Quanto às suas perguntas :

    Esse comportamento é intencional no PowerShell?

    Não creio que seja, e pode-se dizer que é um bug , conforme discutido no problema #24002 do GitHub ; citando este comentário (meu):

    De fato, o PowerShell não suporta "..."entradas -enclosed em $env:PATHinvocação direta (veja abaixo), enquanto que cmd.exeo faz.
    Observe que shells compatíveis com POSIX, como o bash, como o PowerShell, também não suportam "..."entradas -enclosed.

    Pode-se argumentar que os shells compatíveis com PowerShell e POSIX deveriam oferecer suporte "..."a entradas delimitadas por - ou oferecer suporte a uma maneira de escapar o caractere separador de entrada (o que acontece ;no Windows e :em plataformas do tipo Unix), mas não oferecem.

    Por outro lado, quando você usa Start-Process, assim como a [System.Diagnostics.Process]API com UseShellExecute = $true, que é equivalente, "..."entradas delimitadas por - SÃO reconhecidas.

    Isso pode se resumir a diferenças entre duas funções WinAPI:

    • CreateProcess()conforme usado na invocação direta e com UseShellExecute = $false(o padrão) em .NET (Core) vs.
    • ShellExecuteEx()conforme usado Start-Processpor padrão e com UseShellExecute = $true.

    Dado que a invocação direta em cmd.exe(em oposição ao uso do startcomando interno) presumivelmente também usa CreateProcess(), pode haver lógica personalizada em cmd.exepara interpretar %PATH%.


    Existe uma solução alternativa ?

    Supondo que a criação de nomes de arquivo curtos (8.3) esteja ativada (é por padrão), você pode aproveitar o fato de que um nome de arquivo que contém ; sempre tem um nome curto gerado para ele, mesmo que tenha 8 ou menos caracteres no nome base e uma extensão com 3 ou menos caracteres e que o nome curto resultante tem a garantia de não conter ;ou espaços; por exemplo:

    # -> e.g., 'C:\M_YFOL~1'
    $shortFolderPath = 
      (New-Object -ComObject Scripting.FileSystemObject).GetFolder("C:\;My Folder").ShortPath
    

    Em outras palavras:

    • Substitua as $env:PATHentradas que exigem "..."fechamento para desambiguação devido a serem incorporadas ;por suas versões curtas (8.3)...

    • ... e remova as aspas duplas ao redor delas.

    Observe que os nomes específicos do 8.3 podem variar dependendo da presença de outras pastas com nomes longos semelhantes, portanto, eles devem ser determinados em cada máquina.

    • 4
  2. iRon
    2025-01-20T17:51:52+08:002025-01-20T17:51:52+08:00

    " O Powershell não funciona com valores entre aspas na variável PATH, pois trata as aspas como caracteres comuns: "

    Até onde eu sei, o PowerShell não tem nenhum comando nativo (ou variável automatizada) que retorne uma lista de caminhos do caminho do ambiente para você. Ou seja, você tem que fazer o script disso você mesmo.

    Se você pegar o caminho mais fácil e apenas dividir o caminho do ambiente como $env:Path -split ';'você pode realmente acabar com problemas onde você tem um caminho literal que contém um ponto e vírgula. Isso significa que você tem que inventar uma maneira mais inteligente de dividir seu caminho ou usar um conversor/analisador existente.
    Sabendo que o ConvertFrom-Csvcmdlet está muito próximo do que você quer fazer, você pode considerar usar isso:

    ($Env:Path | ConvertFrom-Csv -Delimiter ';' -Header (0..99)).PSObject.Properties.Value
    C:\Program Files (x86)
    C:\;My Folder
    C:\Program Files
    

    Explicação

    • $Env:Pathcontém uma única string com todos os caminhos do ambiente unidos por ponto e vírgula ( ;)
    • ConvertFrom-Csv -Delimiter ';'divide o caminho do ambiente usando o ponto e vírgula como delimitador e também cuida dos valores entre aspas e espaços ao redor do delimitador.
      • -Header (0..99)define um cabeçalho numérico (de 0até 99) para cada valor
    • ConvertFrom-Csvretorna um PSCustomObject, para recuperar todas as suas propriedades você usa a propriedade ocultaPSObject :.PSObject.Properties
      • Embora haja muitos cabeçalhos com valores vazios usando a enumeração de acesso de membro do PowerShell , adicionar a .Valuepropriedade simplesmente retornará todos os valores que não são $Null. Observe que isso é construído em uma ConvertFrom-Csvinconsistência onde as últimas células vazias na última linha do csvarquivo são consideradas $Null(em vez de uma string vazia), veja: #17702
    • 3

relate perguntas

  • C++ ReadFile inteiramente, onde tamanho> 2 GB (Win64)

  • BSOD do Windows Palo Alto Cortex XDR com verificação de bug 0x139

  • Não consigo importar pacotes locais no meu projeto go

  • O KERNEL32.DLL é sempre o terceiro módulo carregado em um processo do Windows?

  • Qual é o problema neste código Rust inseguro para que funcione no Windows, mas não no Ubuntu?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve