Thursday 18 July 2019

Marshal gethrforexception e


Descobri que às vezes em IO operações comum IOException é lançada. Eu posso usar o método Marshal. GetHRForException (Exception e) (encontrado aqui) para determinar o código de erro específico. Depois disso, eu quero voltar a lançar uma exceção, usando meu código de erro específico do aplicativo, para dar ao usuário algumas dicas sobre o que deu errado. Mas não consegui encontrar a lista de possíveis valores HResult para IOException. Mais uma coisa que eu estou preso com é que para diferentes códigos HResult causa raiz pode ser o mesmo - por exemplo, 0x8007052E e 0x80070569 - ambos correspondem a Falha de logon: nome de usuário desconhecido ou senha incorreta. Tentei pesquisar algo como IOException HResult valores, mas não havia nada de especial para o mapeamento IOException HResult com humanos-legível erro (como este ou este). Eu também vi a pergunta aqui, que é muito semelhante, mas ainda não há solução. Então, onde está a documentação sobre os valores IOException HRESULTS Usando Marshal. GetHRForException () você envolveu o código de erro do Windows em um código de erro HResult. Para uma IOException sempre será o número de erro do Windows 0x80070000. O 8 significa erro, o 7 significa que ele veio do Windows. Você poderia simplesmente usar amp 0xffff para recuperar o código de erro original novamente. Converta o resultado de volta para decimal e você terá muitos lugares para descobrir o que significa o código de erro. Eu, pessoalmente, sempre usar o arquivo de cabeçalho WinError. h SDK. Depende da versão do VS que você tem, a maioria dos programadores vai encontrá-lo de volta no C: Arquivos de Programas (x86) Microsoft SDKsWindowsv7.1AInclude diretório. Você também tem um utilitário acessível disponível, execute errlook. exe a linha de comando do Visual Studio. Uma boa maneira de tê-lo prontamente disponível é adicionando-o ao menu Ferramentas. Usar Ferramentas Ferramentas Externas, botão Adicionar, pesquisa de Erro de Título, Comando C: Arquivos de Programas (x86) Microsoft Visual Studio 12.0Common7Toolserrlook. exe. Ajustar o caminho conforme necessário para corresponder à sua versão VS. Você também vai descobrir que os códigos de erro não são os mesmos. 0x80070569 amp 0xffff 0x569 1385. Procurar WinError. h para esse código de erro produz ERRORLOGONTYPENOTGRANTED, Falha de início de sessão: o utilizador não foi concedido o tipo de início de sessão solicitado neste computador. O tipo de erros de IOException que você pode obter não são de qualquer maneira restritos. O Windows não tem especificações de exceção, somente os códigos de erro mais comuns estão listados na documentação do MSDN para uma função winapi particular. Muito parecido com as exceções. NET. Um mal necessário, muitos códigos de erro IOException são gerados por drivers que não foram escritos pela Microsoft. Respondeu Sep 9 14 at 8: 57Eu tenho algum código IO que lê um fluxo dentro de um try..catch. Ele captura IOException e chama System. Runtime. InteropServices. Marshal. GetHRForException () dentro do catch, em uma tentativa de tomar ações diferentes com base no HResult. Algo como isto: Mas executando este código no ASP. NET com o trustmedium, eu recebo esta exceção: Algumas perguntas: Acho que a exceção está ocorrendo porque GetHRForException chama em código não gerenciado, o que não é permitido na confiança média. Corrigir Esta exceção está sendo lançada, não no momento da execução de GetHRForException, mas no momento em que o método está sendo JITed - Correto (O stacktrace mostra meu método, mas tenho certeza de que uma exceção de IO não ocorreu) Existe uma maneira para mim variar o comportamento em um ambiente de confiança parcial, para que eu não chamar o GetHRForException (código não gerenciado) onde não é permitido Em outras palavras, como posso permitir que o JIT para ter sucesso na compilação, enquanto também Avaliando em tempo de execução se o código deve chamar GetHRForException () Algo como isto: Eu acho que há um mecanismo de tempo de execução para testar se as permissões estão disponíveis, mas havent sido capaz de encontrá-lo. EDIT. É este artigo de blog a resposta ShawnFa da Microsoft diz que você não pode fazer uma tentativa. Catch (SecurityException) em torno de um método protegido por um LinkDemand. Se MethodA () chama MethodB (), e MethodB () é marcado com LinkDemand para confiança total, em seguida, o LinkDemand é verificado com MethodA é Jited. Portanto, para evitar a SecurityException, preciso extrair Marshal. GetHRForException em um método separado. É isso correto Aplicado ao meu código, MethodA () pode ser o código que chama Read e, em seguida, na captura tenta chamar GetHRForException (). GetHRForException é MethodB (). O LinkDemand é avaliado quando MethodA () é JITd. (Este LinkDemand falha no meu cenário de médio-confiança ASP. NET). Se eu mover o GetHRForException em um novo método, MethodC (), e chamar condicionalmente MethodC () somente após uma permissão imperativa. Demand () é bem-sucedida, teoricamente eu deveria ser capaz de evitar a SecurityException no tempo JIT, porque MethodC () será JITd somente após a permissão. Demain () tiver êxito. Pediu Jul 12 09 at 14:20 O método necessário é SecurityPermission. IsUnrestricted (). Retorna um verdadeiro ou falso indicando se a permissão é permitida ou não. Ele não exige uma permissão, como faz SecurityPermission. Demand (). Eu uso IsUnresticted com SecurityPermissionFlag. UnmanagedCode para ver se o assembly é permitido chamar código não gerenciado e, em seguida, chamar o código não gerenciado somente se permitido. Há uma torção adicional. O compilador JIT, ao compilar um método, verifica para LinkAcessos de CodeAccessPermission em qualquer método chamado my o método a ser compilado. Marshal. GetHRForException () é marcado com um LinkDemand. Assim, meu método que chama Marshal. GetHRForException () irá lançar uma excepção de segurança uncatchable no momento da compilação JIT, quando executado em um ambiente restrito, como ASP. NET com confiança média. Portanto, nunca devemos JIT o método que chama Marshal. GetHRForException () nesse caso, o que significa que eu preciso para quebrar Marshal. GetHRForException () em um método separado no meu código que é chamado (e assim JITted) apenas quando UnmanagedCode é Sem restrições. Heres algum código de exemplo: respondeu Jul 20 09 at 17:56 Sim - confiança médio não permitirá chamadas em código não gerenciado. O único nível de confiança que o permite é a confiança total. Depende. As demandas de CAS podem ocorrer em tempo de execução, mas o ambiente de hospedagem também pode ir em um vagar e procurar coisas que não podem fazer. Você pode testar para ver se você pode fazer uma chamada para código não gerenciado usando uma demanda CAS com uma instância de SecurityPermission. O código para fazer uma demanda CAS parece com isso respondido Jul 12 09 at 14:32 OK, esta é a grande informação. Isso abrange a parte b da Q3. Mas e sobre a parte a Como faço para obter a compilação JIT para ter sucesso Posso marcar o meu método com um atributo de segurança ou. Lembre-se, minha teoria é que o erro SecurityPermission não está acontecendo em tempo de execução, ele está acontecendo durante JIT - e eu acho que você confirmou que isso é possível. Então a questão é, como eu escrevo o código para permitir que o JIT compile. Ndash Cheeso Jul 12 09 at 15:50 Deve estar acontecendo em tempo de execução, caso contrário, o assembly wouldn39t mesmo carregar - e para que isso aconteça o assembly precisa ser marcado como exigindo a permissão. Mesmo então isso é provavelmente uma verificação de tempo de execução, como acontecerá na carga de montagem, que poderia estar em tempo de execução. Ndash blowdart Jul 12 09 at 16:24 Diferentes tipos de verificação, as demandas de link são atributos em um método, e são de fato verificadas no tempo JIT. Ele é muito usado pela própria estrutura e é raro vê-lo fora da fonte CLR. O que eu demonstro é uma exigência imperativa, não um declarativa como um SecurityPermission (SecurityAction. LinkDemand, Irrestrito true) ndash blowdart 12 de julho 09 às 18: 55Allowing uma exceção para propagar fora do método produz um comportamento incorreto. (Na verdade, o Common Language Runtime não passar uma exceção para um cliente COM chamar um método tal através de uma v-table.) Desde que eu tenha removido todos os atributos PreserveSig de todos os meus métodos de interface e mudaram-se para uma base de exceção completamente Abordagem para a minha biblioteca, isso seria ruim. Em meus objetos COM, eu uso quotthrowquot todo o tempo para enviar de volta erros ao chamador (ambos gerenciados e não gerenciados) e eu ainda não vi um problema. Eu lanço uma COMException, eo HRESULT acaba na chamada hr. O que é mais, o cliente (não gerenciado) pode recuperar a interface IErrorInfo para receber o texto que eu jogar juntamente com o código de erro. São estes documentos antigos que não reembolsaram sido atualizados para refletir o comportamento atual Talvez Im mal-entendido o que ele está tentando me dizer Ou há alguma pegadinha horrível esperando para me morder na, umm, futuro sexta-feira, julho 20, 2007 02:44 Respostas Ok , Eu poderia ter exagerado o quotsinquot pouco aqui. Eu me concentrei muito em deixar exceções C escape fora da chamada de método COM. O que na verdade era um pecado nos dias não gerenciados, há muito tempo para mim. O fato de que ele funciona é bastante convincente evidência de que o wrapper CCW está pegando COMException e gerando o valor de retorno HRESULT a partir disso. É provavelmente maior do que isso, Id imagine que pega Exceção e chama Marshal. GetHRForException método automaticamente. Teria que, não há nenhuma maneira que um cliente COM poderia pegar uma exceção gerenciada. Id dizer que você é bom para ir, desculpe a confusão. A documentação pode ser um pouco mais apertado aqui. Sábado, 21 de julho de 2007 21:27 Todas as respostas Sim, você está cometendo um grande pecado. Você está esperando o cliente COM para capturar a exceção gerenciada. Isso vai falhar miseravelmente quando o cliente não é um aplicativo gerenciado e irá encerrar o cliente. COMException é somente para uso pelo run-time. Você deve retornar falhas por meio do valor de retorno HRESULT. Eles, por sua vez tipicamente gerar exceções no cliente (como COMException em um aplicativo gerenciado). Estou surpreso sua abordagem funciona em tudo. Alguns clientes COM instalam um manipulador de exceção SEH para interceptar exceções assíncronas (divisão por zero, estouro de pilha, acesso à memória inválido, coisas assim). Talvez ele funciona porque esse manipulador intercepta o COMException. Mas isso é um detalhe de implementação do cliente. C clientes para um quase nunca fazer isso. Sábado, julho 21, 2007 18:28 lançar nova COMException (quotRemoving não córregos supportedquot. ENotImplemented) O HRESULT que recebo de a chamada c é ENOTIMPL, tal como seria de esperar. Eu vagava através das configurações de c, e encontrou quotEnable c exceptionsquot e eu configurá-lo para quotNo. quot Ainda assim, acabou de voltar do hr eu esperava. Didnt ver qualquer outra coisa que aplicam. E não, eu não estou compilando o programa c com suporte clr. Na verdade, aqui está o conteúdo da janela do quotcommand linequot: / Od / D quotWIN32quot / D quotDEBUGquot / D quotCONSOLEquot / D quotUNICODEquot / D quotUNICODEquot / Gm / RTC1 / MDd / FoquotDebugquot /FdquotDebugvc80.pdbquot / W3 / nologo / c / Wp64 / ZI / TP / errorReport: prompt Apenas suas opções básicas de compilação. Estou executando no Vista, mas não parece que isso deve importar. Talvez isso é algo que mudou ao longo do tempo Ou há alguma outra opção de compilação c Eu deveria desligar Ok, eu poderia ter exagerado o quotsinquot bit aqui. Eu me concentrei muito em deixar exceções C escape fora da chamada de método COM. O que na verdade era um pecado nos dias não gerenciados, há muito tempo para mim. O fato de que ele funciona é bastante convincente evidência de que o wrapper CCW está captando COMException e gerando o valor de retorno HRESULT a partir disso. É provavelmente maior do que isso, Id imagine que pega Exceção e chama Marshal. GetHRForException método automaticamente. Teria que, não há nenhuma maneira que um cliente COM poderia pegar uma exceção gerenciada. Id dizer que você é bom para ir, desculpe a confusão. A documentação pode ser um pouco mais apertado aqui. Sábado, 21 de julho de 2007 21:27 Ok, eu estava preocupado. Eu tinha puxado para fora centenas de linhas do código do quotif SUCCEEDEDquot e suprimido PreserveSig das centenas dos métodos. Ter que colocar tudo de volta foi. Assustador Obrigado por me deixar passar este passado. Sábado, 21 de julho de 2007 21h50 Microsoft está conduzindo uma pesquisa on-line para entender sua opinião sobre o site da Msdn. Se você optar por participar, a pesquisa on-line será apresentada a você quando você deixar o site Msdn. Você gostaria de participar

No comments:

Post a Comment