Gethrforexception exemplo de aplicação


Eu 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 o 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 demanda imperativa, não declarativa como um SecurityPermission (SecurityAction. LinkDemand, Unrestricted true) ndash blowdart Jul 12 09 às 18: 55Quiz: Gotcha com exceções e HRESULTs Bem, tanto ENOINTERFACE e EPOINTER HRESULT são mapeados para um InvalidCast Exceção por ThrowExceptionForHR. Uma vez que uma exceção InvalidCast é lançada, o mesmo HRESULT será retornado de GetHRForException (they8217re a mesma exceção nesse ponto). A razão que 0x8004002 é exibida ambas as vezes é que o objeto de erro não está sendo redefinido entre os dois try / catch blocos. Antes da primeira tentativa / captura o objeto de erro associado com o segmento lógico está vazio, após o try / catch o objeto de erro object8217s HRESULT é definido como 0x8004002. Agora, o segundo try / catch bloco é executado e GetErrorInfo () é executado para definir o valor COMException. HRESULT para o valor do objeto de erro (que já está definido como 0x8004002), portanto, o valor COMException. HRESULT é definido como 0x8004002. Deixe-me ver se consigo apresentar um exemplo8230 Bem, consegui demonstrar por que isso está acontecendo (veja o código abaixo). Eu inseri uma chamada para criar uma nova instância do Excel. ApplicationClass no Excel COM Server. Qualquer chamada de apartamento cruzado que utiliza um proxy-stub ou qualquer chamada COM dentro de um apartamento que utiliza o ciclo de mensagem COM (STA) irá limpar o objecto de informações de erro. Portanto, a chamada para o objeto COM do Excel entre as exceções capturadas limpará o objeto de informações de erro: classe Class1 const int ENOINTERFACE desmarcado (int 0x80004002) const int EPOINTER desmarcado (int 0x80004003) private Excel. Application ExcelApplication null Muito bom Observações, todos Normalmente, ENOINTERFACE é mapeado para InvalidCastException e EPOINTER é mapeado para NullReferenceException. Mas como Fernando apontou, ambas as exceções lançadas neste exemplo são InvalidCastException. Isso explica por que GetHRForException retorna ENOINTERFACE em ambos os casos, mas por que obter uma InvalidCastException duas vezes O ThrowExceptionForHR método lança uma exceção cujo tipo corresponde ao valor de entrada HRESULT (ou uma COMException contendo o HRESULT se a entrada HRESULT isn8217t na tabela de mapeamento CLR8217s) . Mas ele faz mais do que apenas isso: ele chama o Win32 GetErrorInfo API para tentar recuperar um objeto de erro disponível no segmento atual. Ele usa essas informações para dar a exceção uma mensagem de erro personalizada, origem e assim por diante. ThrowExceptionForHR também tem uma sobrecarga com um segundo parâmetro System. IntPtr que representa um ponteiro para uma interface IErrorInfo, para que você possa passar essas informações diretamente. Passar IntPtr. Zero significa que você quer que a API aja como a sobrecarga de um único parâmetro (e chamada GetErrorInfo), e passando -1 desabilita a recuperação de informações extras completamente. O GetHRForException método recupera o valor HRESULT para qualquer exceção gerenciada. Este é o valor da propriedade protegida de excepção, que normalmente você não pode acessar diretamente. Mas esse método tem um efeito colateral: ele chama o Win32 SetErrorInfo API, passando o CCW para exceção (que implementa IErrorInfo adequadamente). Ele faz isso para tornar mais fácil imitar o comportamento marshaler8217s ao expor manualmente uma exceção como um HRESULT e IErrorInfo para COM. Neste exemplo, a primeira chamada para GetHRForException faz com que o CLR para chamar SetErrorInfo com o inválido InvalidCastException objeto. Devido a isso, a segunda chamada para ThrowExceptionForHR pega essas informações quando ele chama GetErrorInfo, como Phil apontou. A razão isso afeta o tipo da exceção lançada 8211 apesar do fato de que IErrorInfo doesn8217t tem um mecanismo para recuperar um HRESULT 8211 é que o CLR pode detectar quando o objeto de erro recuperado de SetErrorInfo originou como uma exceção gerenciada e apenas reutilizar essa exceção original. Tudo isso significa que não importa o que HRESULT é passado para o método ThrowExceptionForHR pela segunda vez (enquanto it8217s uma falha HRESULT), a exceção lançada é sempre um InvalidCastException. Para obter o comportamento que you8217d normalmente espera, você pode usar a sobrecarga de ThrowExceptionForHR que ignora IErrorInfo: using System using System. Runtime. InteropServices classe pública Question int int ENOINTERFACE unchecked (int 0x80004002) const int EPOINTER unchecked ((int) 0x80004003) Public static void Main () try Marshal. ThrowExceptionForHR (ENOINTERFACE) catch (exceção ex) Console. WriteLine (quot0x quot, Marshal. GetHRForException (ex)) Este novo código é impresso: Phil perguntou por que Marshal. GetLastWin32Error sempre retornou 0 não importa onde ele Inserido. That8217s porque GetLastError / SetLastError é um mecanismo separado de GetErrorInfo / SetErrorInfo. O mecanismo anterior nunca está envolvido aqui. E, sim, o código gerenciado nunca deve chamar GetLastError diretamente. Veja: blogs. gotdotnet / anathan / PermaLink. aspx / 6d021f27-72c8-4420-b6ad-1c5f0690bde8 Lamento que meu guestion não esteja relacionado ao assunto. Gostaria de saber que como posso obter informações de uma página, por exemplo, obter o código html de uma página especial no meu ASP ou ASP. NET apllication e usá-lo em meu application. for exaple eu obter o código html quotanysite quot e Em seguida, usar esse código em minha página por programming. I8217ve visto bastante pessoas perguntando sobre isso, então eu pensei que deveria falar sobre isso no meu blog. Eles vêem a estranha primeira chance de TypeLoadException acontecer em seu aplicativo, mas ele doesn8217t parece nunca causar qualquer problema (app doesn8217t falhar) e tudo ainda parece funcionar 8216fine8217. Isso parece acontecer principalmente se você tiver um problema, mas eu não tenho certeza de que isso é o que eu acho. Tempo. It8217s um grande conceito logicamente mas difícil de agarrar uma vez que você começa a pensar sobre como o fluxo real do código vai (e todo o inferno solta uma vez que você começa a depurar o It8217s mais fácil de explicar isso em um E vamos dizer que você tem uma função de exportação em sua DLL nativa: void WINAPI MyFunction (comptrtltIMyInterfacegt ptr) E o DllImport seria algo como isto: DllImport (quotmydll. dllquot) void MyFunction (IMyInterface ptr) Tudo parece ser perfeitamente válido, exceto Que há a ver muitas pessoas informando que eles estão vendo estranho p / invocar problemas quando mudaram o seu código para VS 2017. Normalmente, eles têm P / Invoke assim: DllImport (quotWin32Project2.dllquot, PreserveSig true, CharSet CharSet. Unicode) static extern int MyPInvoke (seqüência de caracteres ret) Se você anexar um depurador nativo (ou habilitar a depuração nativa), com os símbolos corretos (public symbol8230 January 24, 2017 2 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 Começar pela primeira vez, olhando para um pequeno snippet de código: if (Marshal. GetHRForException (myException) ESMECOMERROR) DoSomething () Isso parece perfeitamente bem, certo Não realmente. Acontece que esta API é realmente mal nomeado, e ele realmente faz mais do que apenas recuperar o HR do objeto de exceção. Usando esta API incorretamente poderia lhe dar alguns problemas estranhos Aprendi esse truque de depuração de um colega há alguns dias, quando estamos depurando um bug juntos e eu Não posso esperar para compartilhá-lo. Conceitualmente, é realmente uma idéia simples, mas é muito útil. Vamos dizer que você está depurando um acidente. Você sabe que o bug é provavelmente na função Eu recentemente tenho Samsung Focus, mas ele não é reconhecido pelo Software Zune que diz Nenhum dispositivo conectado, mesmo que o meu telefone fez soar um som Quando ele se conecta ao meu computador e software zune fez pop-up. Passar meia hora procurando soluções e eu corro para este artigo: microsoft / windows / en-us / howto / wp7 / básico / the-zune-software-doesnt-reconhecer-my-phone. aspx Um of8230 21 de dezembro de 2018 1 x2605 X2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 O que é 0x8013XXXX Ocasionalmente você pode executar em HRESULTs misterioso retornado de. NET que começa com 0x8013, por exemplo, 0x80131522. Infelizmente, a pesquisa de erro enviada com o Visual Studio não funciona realmente com aqueles HRESULTs estranhos. O que são eles Acontece que eles são de fato, definidos por. NET / CLR nos arquivos de cabeçalho. Todas essas falhas / success8230 17 de dezembro de 2018 0 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605 x2605

Comments