Somente pelo IIS é possível converter uma pasta em aplicação? Mais ou menos. Na versão 7 do IIS já dispõe de módulos que simplificam o processo de criação de site, diretório virtual, pools de aplicação e as aplicações em si. Nesse artigo mostrarei bem rápido como converter uma pasta em uma aplicação.
Crie sua aplicação e adicione, como referência, o binário Microsoft.Web.Administration.dll que fica na pasta C:\Windows\System32\inetsrv . Agora adicione o seguinte código:
using Microsoft.Web.Administration;
private void CriaEntradaIIS(string diretorio)
{
try
{
// Cria a pasta do site
if (!Directory.Exists(diretorio))
Directory.CreateDirectory(diretorio);
// Servidor de Aplicação
ServerManager sm = new ServerManager();
// Captura o site raiz onde irá adicionar a aplicação
Site st = sm.Sites["Default Web Site"];
// Cria a aplicação no diretório criado apontando o caminho, ex: aplicacao
Application app = st.Applications.Add("/aplicacao", diretorio);
app.ApplicationPoolName = "ASP.NET v4.0";
sm.CommitChanges();
// Libera
sm.Dispose();
}
catch (Exception erro)
{
return;
}
}
Se tentar executar dará erro... Antes dê permissão total ao grupo Serviço de Rede (Network Service) à pasta C:\Windows\System32\inetsrv\config . Agora sim irá criar. Para mais exemplos veja nesse post aqui.
Mostrando postagens com marcador windows. Mostrar todas as postagens
Mostrando postagens com marcador windows. Mostrar todas as postagens
Convertendo uma pasta em aplicação no IIS via código (C#)
Postado por
Thiago Marçal
on segunda-feira, 28 de novembro de 2011
/
Marcadores:
application,
diretório virtual,
dll,
iis,
site,
windows
/
Comments: (3)
Scanear um documento com C#
Um dos melhores componentes de scaneamento que já utilizei é o da VintaSoft. Ele não é free, mas pode ser utilizado normalmente. O único empecilho é que, para cada scan que fizer, ele irá solicitar que clique em Evaluate. Quem comprar, vale a pena pois é muito bom e seu suporte sempre está a disposição. Chega de elogios e vamos ao que interessa.
O componente permite tanto utilizar em Windows Form quando Web Form e no site há todos os exemplos necessários. Baixe o componente e instale. Para nosso exemplo, trabalharemos com um Windows Form. Fiz uma pequena aplicação de scanear nota fiscal.
Vá na pasta de instalação do componente, copie o arquivo Vintasoft.Twain.dll para sua aplicação e adicione como referência. No Code-Behind do formulário a ser trabalhado, adicione o seguinte código para inicializar o componente:
using Vintasoft.Twain;
// Carrega o gerenciador de dispositivo
DeviceManager _deviceManager = new DeviceManager();
Device _device;
// Avalia se é um dispositivo útil
if (!_deviceManager.IsTwainAvailable)
{
MessageBox.Show("Não é um dispositivo TWAIN!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
// Abre o gerenciador de dispositivo
_deviceManager.Open();
// Seta o dispositivo corrente
_device = _deviceManager.Devices.Current;
lblDipositivo.Text = _deviceManager.Devices.Current.Info.ProductName;
}
catch (TwainDeviceManagerException ex)
{
MessageBox.Show(ex.Message, "Gerenciador de Dispositivos");
return;
}
Agora, ao clicar no botão Scannear, adicionamos o seguinte método:
private void btnScanear_Click(object sender, EventArgs e)
{
try
{
// Seta as configurações
_device.TransferMode = TransferMode.File;
try
{
_device.ShowUI = false;
_device.ShowIndicators = false;
_device.DisableAfterAcquire = true;
}
catch { }
// Abre o dispositivo
_device.Open();
// Propriedades do scaneamento
try
{
_device.UnitOfMeasure = UnitOfMeasure.Inches;
_device.Resolution = new Resolution(float.Parse(resolucaoX.SelectedItem.ToString()), float.Parse(resolucaoY.SelectedItem.ToString()));
}
catch { }
// Informação sobre o arquivo
_arquivo = "LJ_" + _loja + "_Scan_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".jpg";
_device.FileName = _directoryForImages + _arquivo;
//_device.FileFormat = TwainImageFileFormat.Jpeg;
// Captura a imagem
AcquireModalState acquireModalState = AcquireModalState.None;
do
{
acquireModalState = _device.AcquireModal();
switch (acquireModalState)
{
case AcquireModalState.ImageAcquired:
_device.FileName = _directoryForImages + _arquivo;
//_device.FileFormat = TwainImageFileFormat.Jpeg;
break;
case AcquireModalState.ScanCompleted:
CloseDevice();
break;
case AcquireModalState.ScanCanceled:
CloseDevice();
break;
case AcquireModalState.ScanFailed:
CloseDevice();
break;
case AcquireModalState.UserInterfaceClosed:
CloseDevice();
break;
}
}
while (acquireModalState != AcquireModalState.None);
}
catch (TwainException ex)
{
MessageBox.Show(ex.Message + " - " + ex.StackTrace, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
E outros métodos são necessários adicionar ao form, como:
/// Fecha o dispositivo e a gerência
private void CloseDeviceAndDeviceManager()
{
// Verifica de há dispositivo
if (_device != null)
{
if (_device.State != DeviceState.Closed)
_device.Close();
}
// Fecha a gerência
if (_deviceManager.State != DeviceManagerState.Closed)
_deviceManager.Close();
}
/// Fecha o dispositivo
private void CloseDevice()
{
// Desabilita o serviço
if (_device.State == DeviceState.Enabled)
{
if (!_device.ShowUI)
_device.Disable();
}
// Fecha
if (_device.State == DeviceState.Opened)
_device.Close();
}
/// Ao fechar o formulário, libera o uso
private void Scan_FormClosing(object sender, FormClosingEventArgs e)
{
if (_device != null)
{
// Verifica se está em uso
if (_device.State == DeviceState.Transferring ||
_device.State == DeviceState.TransferReady)
{
// Envia a solicitação de cancelamento
_device.CancelTransfer();
// Aguarda finalizar
e.Cancel = true;
MessageBox.Show("O dispositivo está em uso! Aguarde alguns instantes enquanto é solicitado a liberação do scanner.", "Informação");
return;
}
}
// Fecha o dispositivo e a gerência
CloseDeviceAndDeviceManager();
}
Pronto! O scaneamento é realizado e é gerado um arquivo JPG. Reparem que está comentado o atributo _device.FileFormat porque nem todo scanner dá a possibilidade de configuração. Alguns aceitam e outros não. Se utilizar alguma configuração que o scanner não suporta, deve aparecer a mensagem: "Failed to get/get to capability". Então você precisa deixar apenas as configurações que o scanner suporte.
Bons scans!
O componente permite tanto utilizar em Windows Form quando Web Form e no site há todos os exemplos necessários. Baixe o componente e instale. Para nosso exemplo, trabalharemos com um Windows Form. Fiz uma pequena aplicação de scanear nota fiscal.
Vá na pasta de instalação do componente, copie o arquivo Vintasoft.Twain.dll para sua aplicação e adicione como referência. No Code-Behind do formulário a ser trabalhado, adicione o seguinte código para inicializar o componente:
using Vintasoft.Twain;
// Carrega o gerenciador de dispositivo
DeviceManager _deviceManager = new DeviceManager();
Device _device;
// Avalia se é um dispositivo útil
if (!_deviceManager.IsTwainAvailable)
{
MessageBox.Show("Não é um dispositivo TWAIN!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
// Abre o gerenciador de dispositivo
_deviceManager.Open();
// Seta o dispositivo corrente
_device = _deviceManager.Devices.Current;
lblDipositivo.Text = _deviceManager.Devices.Current.Info.ProductName;
}
catch (TwainDeviceManagerException ex)
{
MessageBox.Show(ex.Message, "Gerenciador de Dispositivos");
return;
}
Agora, ao clicar no botão Scannear, adicionamos o seguinte método:
private void btnScanear_Click(object sender, EventArgs e)
{
try
{
// Seta as configurações
_device.TransferMode = TransferMode.File;
try
{
_device.ShowUI = false;
_device.ShowIndicators = false;
_device.DisableAfterAcquire = true;
}
catch { }
// Abre o dispositivo
_device.Open();
// Propriedades do scaneamento
try
{
_device.UnitOfMeasure = UnitOfMeasure.Inches;
_device.Resolution = new Resolution(float.Parse(resolucaoX.SelectedItem.ToString()), float.Parse(resolucaoY.SelectedItem.ToString()));
}
catch { }
// Informação sobre o arquivo
_arquivo = "LJ_" + _loja + "_Scan_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".jpg";
_device.FileName = _directoryForImages + _arquivo;
//_device.FileFormat = TwainImageFileFormat.Jpeg;
// Captura a imagem
AcquireModalState acquireModalState = AcquireModalState.None;
do
{
acquireModalState = _device.AcquireModal();
switch (acquireModalState)
{
case AcquireModalState.ImageAcquired:
_device.FileName = _directoryForImages + _arquivo;
//_device.FileFormat = TwainImageFileFormat.Jpeg;
break;
case AcquireModalState.ScanCompleted:
CloseDevice();
break;
case AcquireModalState.ScanCanceled:
CloseDevice();
break;
case AcquireModalState.ScanFailed:
CloseDevice();
break;
case AcquireModalState.UserInterfaceClosed:
CloseDevice();
break;
}
}
while (acquireModalState != AcquireModalState.None);
}
catch (TwainException ex)
{
MessageBox.Show(ex.Message + " - " + ex.StackTrace, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
E outros métodos são necessários adicionar ao form, como:
private void CloseDeviceAndDeviceManager()
{
// Verifica de há dispositivo
if (_device != null)
{
if (_device.State != DeviceState.Closed)
_device.Close();
}
// Fecha a gerência
if (_deviceManager.State != DeviceManagerState.Closed)
_deviceManager.Close();
}
private void CloseDevice()
{
// Desabilita o serviço
if (_device.State == DeviceState.Enabled)
{
if (!_device.ShowUI)
_device.Disable();
}
// Fecha
if (_device.State == DeviceState.Opened)
_device.Close();
}
private void Scan_FormClosing(object sender, FormClosingEventArgs e)
{
if (_device != null)
{
// Verifica se está em uso
if (_device.State == DeviceState.Transferring ||
_device.State == DeviceState.TransferReady)
{
// Envia a solicitação de cancelamento
_device.CancelTransfer();
// Aguarda finalizar
e.Cancel = true;
MessageBox.Show("O dispositivo está em uso! Aguarde alguns instantes enquanto é solicitado a liberação do scanner.", "Informação");
return;
}
}
// Fecha o dispositivo e a gerência
CloseDeviceAndDeviceManager();
}
Pronto! O scaneamento é realizado e é gerado um arquivo JPG. Reparem que está comentado o atributo _device.FileFormat porque nem todo scanner dá a possibilidade de configuração. Alguns aceitam e outros não. Se utilizar alguma configuração que o scanner não suporta, deve aparecer a mensagem: "Failed to get/get to capability". Então você precisa deixar apenas as configurações que o scanner suporte.
Bons scans!
Adicionando uma página de cadastro de usuários (Hotspot) em ASP.NET no Mikrotik
Cada projeto que pego, é uma aventura nova a ser encarada! Dessa vez me adentrei no universo de Linux, rede, SSH, infra e tudo o que é direito. Quem não conhece, a Mikrotik é uma empresa de grande referência no que tange em equipamentos para redes de computadores. Seu principal destaque é o RouterOS que é sistema operacional que torna o roteador um poderoso gerente de rede. Dentro do Mikrotik (irei me referenciar sempre dessa forma generalizando como um produto), há o HotSpot. Com ele pode-se gerenciar quem irá autenticar na rede para usar a internet (ou apenas a intranet), banda usada, taxa de transferência e outras funcionalidades por usuário ou de forma geral. Um exemplo de uso desse sistema é de quando você vai a uma rede corporativa onde precisa autenticar-se para usar a internet... é isso!
Qual é o objetivo desse artigo então? A princípio é apenas obter as páginas originais de hotspot do Mikrotik, colocar um redirecionador para uma página externa, criar uma página externa de cadastro de usuário (para que possa acessar a rede) e fazer funcionar. Não ensinarei como configurar ou criar o hotspot. Pela net há vários tutoriais muito bons sobre o assunto e também não é de minha área. Recomendo fortemente o fórum da Under-Linux que lá o pessoal manja muito no assunto.
Nesse artigo usei o Mikrotik MKBR100 que é bem fácil de usar: basta plugar o cabo de rede da internet, do servidor e da energia. Pronto!
Para acessar seu SO, deve-se utilizar o Winbox como se fosse um daqueles players de máquina virtual ou OpenSSH. Vamos lá colocar a mão na massa!
Conecte o cabo de rede de seu PC (ou servidor) na porta (interface) ether2 do Mikrotik. Agora conecte outro cabo na ether1 para os outros computadores da rede (ou roteador simples). Porquê na ether1? Estou considerando que o hotspot está configurado para monitorar essa interface enquanto a ether2 será utilizado para que o servidor de comunique com o aparelho. Seria algo do tipo:
Vá em IP > Address no Mikrotik para que sejam configuradas as interfaces e sejam endereçados conforme os exemplos abaixo:
Somente através de IP que será possível enviar os arquivos do hotspot. Se ficar conectando, via MAC, pelo Winbox, você terá a mensagem de erro: "router has been disconnected" (logo, conecte-se usando a ether2 - 192.168.88.2). E outra coisa é: se não seguir o esquema acima, outros erros você terá, como:
could not connect to ... no response
could not connect to ... connection refused
could not connect to ... network is unreachable
could not fetch index from ... not found
Tudo isso por causa de configuração apenas! É bom deixar o IP do servidor fixo para que possa dar permissão de porta, firewall, etc. No caso deixei como 192.168.88.30 (que no caso era minha própria máquina). Uma dica: às vezes dê um reboot no aparelho!
O próximo passo é ativar a porta da API que o Mikrotik dispõe para integração com linguagens de programação. É através dela que iremos conectar e fazer a comunicação. Só que precisamos ativá-la. Vá em IP > Services e ative a API na porta 8728.
Também libere, no Firewall, as portas para conexão tanto do sistema quanto do Winbox (pelo IP), senão quando estiver acessando pela página de cadastro, irá surgir o erro: "nenhuma conexão pôde ser feita porque a máquina de destino as recusou ativamente ..:8728.".
Para permitir a navegação e envio de informações, adicione as permissões no Walled Garden.
Vejam que até o momento tudo é configuração e nada de programação. Continuemos...
Agora vamos em Files e selecione todos os arquivos da pasta hotspot, arraste para sua área de trabalho que será copiado. Para enviar faça o processo inverso... Se estiver acessando pelo IP vai dar certo, senão cairá a conexão (lembra que disse acima?).
Abra o HTML da página login.html e acione um link para a página de cadastro que ficará hospedada no servidor. Adicionei o link <a href="http://192.168.88.30/mikrotik/cadastro.aspx">cadastre-se</a> . Customize as demais páginas como desejar e as envie de volta. Praticamente terminamos de trabalhar no Mikrotik.
Agora vem o mais simples: criar a página ASP.NET. Você pode utilizar qualquer linguagem de programação que possa usar TCP na comunicação e que a API suporte: PHP, Delphi, C, C++, C#, Flash, Ruby on Rails, Java, Python, VB.NET, etc.
Faça o download da classe MK, em C# (eles já dispõe de classes prontas para outras linguagens também), nesse link aqui e adicione no seu projeto. Agora crie um Web Form adicionando os campos que queira trabalhar. No meu exemplo, só quis login (username) e senha. Adicione um Button e um método para executar o cadastro do usuário conforme exemplo abaixo:
// Autenticação
MK mikrotik = new MK("192.168.88.2");
if (!mikrotik.Login("admin", ""))
{
ScriptManager.RegisterStartupScript(Page, typeof(Page), "alert", "alert('Houve um problema de comunicação com o Hotspot! Por favor, tente mais tarde.');", true);
mikrotik.Close();
return;
}
// Requisição
mikrotik.Send("/ip/hotspot/user/add");
mikrotik.Send("=name=" + nome.Text);
mikrotik.Send("=password=" + senha.Text, true);
//Retorno
string retorno = string.Empty;
foreach (string h in mikrotik.Read())
{
if (retorno != string.Empty)
retorno += ", ";
retorno += h;
}
// Fecha objeto
mikrotik.Close();
// Validação
if (retorno.ToLower().Contains("!done=ret="))
ScriptManager.RegisterStartupScript(Page, typeof(Page), "alert", "alert('Cadastro realizado com sucesso!'); location.href='http://192.168.88.1/login.html';", true);
else if (retorno.ToLower().Contains("message=failure: already have user with this name for this server"))
ScriptManager.RegisterStartupScript(Page, typeof(Page), "alert", "alert('Já existe um usuário com esse nome!');", true);
else
ScriptManager.RegisterStartupScript(Page, typeof(Page), "alert", "alert('Falha no cadastro: " + retorno + "!');", true);
Você poderia não só fazer o cadastro de usuário no hotspot como também executar qualquer comando (SSH) no Mikrotik. Lembrando que eu atropelei muita coisa aí no que diz respeito a configuração do dispositivo na qual disse logo no início que não era minha finalidade. Vocês observaram que a parte de programação é bem simples do que configuração... e com certeza é! Agora nunca irá sair de minha cabeça a palavra Mikrotik Mikrotik Mikrotik Mikrotik Mikrotik ... Por favor, qualquer erro ou informação adicional me avise!
[]'s
UPDATE: disponibilizei uma implementação no post http://thiagomarcal.blogspot.com.br/2016/09/implementacao-do-aspnet-c-com-o.html
Qual é o objetivo desse artigo então? A princípio é apenas obter as páginas originais de hotspot do Mikrotik, colocar um redirecionador para uma página externa, criar uma página externa de cadastro de usuário (para que possa acessar a rede) e fazer funcionar. Não ensinarei como configurar ou criar o hotspot. Pela net há vários tutoriais muito bons sobre o assunto e também não é de minha área. Recomendo fortemente o fórum da Under-Linux que lá o pessoal manja muito no assunto.
Nesse artigo usei o Mikrotik MKBR100 que é bem fácil de usar: basta plugar o cabo de rede da internet, do servidor e da energia. Pronto!
Para acessar seu SO, deve-se utilizar o Winbox como se fosse um daqueles players de máquina virtual ou OpenSSH. Vamos lá colocar a mão na massa!
Conecte o cabo de rede de seu PC (ou servidor) na porta (interface) ether2 do Mikrotik. Agora conecte outro cabo na ether1 para os outros computadores da rede (ou roteador simples). Porquê na ether1? Estou considerando que o hotspot está configurado para monitorar essa interface enquanto a ether2 será utilizado para que o servidor de comunique com o aparelho. Seria algo do tipo:
Vá em IP > Address no Mikrotik para que sejam configuradas as interfaces e sejam endereçados conforme os exemplos abaixo:
- ether1: 192.168.88.1
- ether2: 192.168.88.2
Somente através de IP que será possível enviar os arquivos do hotspot. Se ficar conectando, via MAC, pelo Winbox, você terá a mensagem de erro: "router has been disconnected" (logo, conecte-se usando a ether2 - 192.168.88.2). E outra coisa é: se não seguir o esquema acima, outros erros você terá, como:
could not connect to ... no response
could not connect to ... connection refused
could not connect to ... network is unreachable
could not fetch index from ... not found
Tudo isso por causa de configuração apenas! É bom deixar o IP do servidor fixo para que possa dar permissão de porta, firewall, etc. No caso deixei como 192.168.88.30 (que no caso era minha própria máquina). Uma dica: às vezes dê um reboot no aparelho!
O próximo passo é ativar a porta da API que o Mikrotik dispõe para integração com linguagens de programação. É através dela que iremos conectar e fazer a comunicação. Só que precisamos ativá-la. Vá em IP > Services e ative a API na porta 8728.
Também libere, no Firewall, as portas para conexão tanto do sistema quanto do Winbox (pelo IP), senão quando estiver acessando pela página de cadastro, irá surgir o erro: "nenhuma conexão pôde ser feita porque a máquina de destino as recusou ativamente ..:8728.".
Para permitir a navegação e envio de informações, adicione as permissões no Walled Garden.
Vejam que até o momento tudo é configuração e nada de programação. Continuemos...
Agora vamos em Files e selecione todos os arquivos da pasta hotspot, arraste para sua área de trabalho que será copiado. Para enviar faça o processo inverso... Se estiver acessando pelo IP vai dar certo, senão cairá a conexão (lembra que disse acima?).
Abra o HTML da página login.html e acione um link para a página de cadastro que ficará hospedada no servidor. Adicionei o link <a href="http://192.168.88.30/mikrotik/cadastro.aspx">cadastre-se</a> . Customize as demais páginas como desejar e as envie de volta. Praticamente terminamos de trabalhar no Mikrotik.
Agora vem o mais simples: criar a página ASP.NET. Você pode utilizar qualquer linguagem de programação que possa usar TCP na comunicação e que a API suporte: PHP, Delphi, C, C++, C#, Flash, Ruby on Rails, Java, Python, VB.NET, etc.
Faça o download da classe MK, em C# (eles já dispõe de classes prontas para outras linguagens também), nesse link aqui e adicione no seu projeto. Agora crie um Web Form adicionando os campos que queira trabalhar. No meu exemplo, só quis login (username) e senha. Adicione um Button e um método para executar o cadastro do usuário conforme exemplo abaixo:
// Autenticação
MK mikrotik = new MK("192.168.88.2");
if (!mikrotik.Login("admin", ""))
{
ScriptManager.RegisterStartupScript(Page, typeof(Page), "alert", "alert('Houve um problema de comunicação com o Hotspot! Por favor, tente mais tarde.');", true);
mikrotik.Close();
return;
}
// Requisição
mikrotik.Send("/ip/hotspot/user/add");
mikrotik.Send("=name=" + nome.Text);
mikrotik.Send("=password=" + senha.Text, true);
//Retorno
string retorno = string.Empty;
foreach (string h in mikrotik.Read())
{
if (retorno != string.Empty)
retorno += ", ";
retorno += h;
}
// Fecha objeto
mikrotik.Close();
// Validação
if (retorno.ToLower().Contains("!done=ret="))
ScriptManager.RegisterStartupScript(Page, typeof(Page), "alert", "alert('Cadastro realizado com sucesso!'); location.href='http://192.168.88.1/login.html';", true);
else if (retorno.ToLower().Contains("message=failure: already have user with this name for this server"))
ScriptManager.RegisterStartupScript(Page, typeof(Page), "alert", "alert('Já existe um usuário com esse nome!');", true);
else
ScriptManager.RegisterStartupScript(Page, typeof(Page), "alert", "alert('Falha no cadastro: " + retorno + "!');", true);
Você poderia não só fazer o cadastro de usuário no hotspot como também executar qualquer comando (SSH) no Mikrotik. Lembrando que eu atropelei muita coisa aí no que diz respeito a configuração do dispositivo na qual disse logo no início que não era minha finalidade. Vocês observaram que a parte de programação é bem simples do que configuração... e com certeza é! Agora nunca irá sair de minha cabeça a palavra Mikrotik Mikrotik Mikrotik Mikrotik Mikrotik ... Por favor, qualquer erro ou informação adicional me avise!
[]'s
UPDATE: disponibilizei uma implementação no post http://thiagomarcal.blogspot.com.br/2016/09/implementacao-do-aspnet-c-com-o.html
Recuperando a senha da conta identidade do Pool de Aplicativos do Plesk no IIS
Mais um título longo... um tanto confuso, mas em resposta a uma dúvida de um amigo:
Então façamos as seguintes etapas:
"Exclui um Application Pool no IIS e nela estava configurada uma conta interna do Plesk: IWAM_plesk. Não sei a senha utilizada. Tem como recuperar a senha para recriar um novo application?"Sim! O Plesk sempre nos pregando aquela peça... Os dois pools que o Plesk utiliza estão vinculados à conta IWAM_plesk (conta interna) para que possam manipular corretamente os arquivos e seus aplicativos (bem como as permissões necessárias) no sistema operacional:
- plesk(default)(2.0)(pool)
- plesk(default)(4.0)(pool)
Então façamos as seguintes etapas:
- Abra o Prompt de Comando em Modo Administrador;
- Navegue para a pasta C:\Windows\system32\inetsrv;
- Execute o comando appcmd.exe list apppool “plesk(default)(2.0)(pool)” /text:*
Aparecerá a descrição completa desse pool. Procure a entrada referente ao usuário e senha do Plesk conforme a figura abaixo:
Agora você tem a senha do usuário! No site de Dhiraj tem mais detalhes acerca desse tipo de recuperação.
Mega Post de Erros
Postado por
Thiago Marçal
on sábado, 9 de abril de 2011
/
Marcadores:
banco de dados,
cloud server,
crystal reports,
dll,
erros,
iis,
locaweb,
plesk,
sql server,
windows
/
Comments: (0)
Lidar com erros é algo realmente muito chato... Chato demais! Esses dias fui convocado para fazer um certo trabalho de migração entre servidores. Um desses servidores era um Cloud Server Pro da Locaweb. Em muitos posts que aqui escrevi tem um pouco retratando sobre a Locaweb. Trabalho e já trabalhei muito com ela e sei de todos os seus passos e "artimanhas" de atendimento... O antigo Cloud Server foi até tranquilo de trabalhar, mas esse novo... Vamos aos problemas!
Uma dica que dou sempre quando alguém quer contratar um servidor: leiam muito sobre os prós e contras. Os prós vejam no próprio site do prestador, os contras vejam nos relatos de usuários. No post a seguir não estou jogando a Locaweb contra a parede, apenas estou expondo erros que podem ser sanados de forma fácil mas que burocraticamente é jogado para o cliente se virar (nos 30!).
Nesse Cloud Server vem embutido o Plesk. Em poucas palavras serve para gerenciar a hospedagem através de uma interface web. É uma boa ferramenta de gerência, tem tudo para gerenciar sua hospedagem. Só que esse demais gera ocupação demais (redundância) de espaço em disco. Dos 50 Gb que você contrata, 40Gb é para o sistema operacional e 10Gb para seus arquivos. Sendo que dos 10Gb é para todos os seus arquivos, e-mails, banco de dados, etc. Ou seja, apenas usufrui dos 10Gb um pouco menos que 9Gb e olhe lá.
Bem, dizem que vem tudo preparado e instalado para usar... Verdade até certa parte! Quem está usando e é iniciante vai ver que é mil maravilhas. Dá para fazer o básico de tudo. O problema vem a seguir...
Um cliente contratou o Cloud Server gerenciado pelo cliente (ou seja, sobrou para o usuário final) e me passou para configurar e deixar no ponto de uso fazendo toda a migração e instalação. Em um passe de mágica surgem os problemas...
Os bancos de dados que vem são o MS SQL Server 2008 e o MySQL. Não há interface para dump e recovery das bases forçando a usar o Plesk para isso, mas não queria. Onde está o Management Studio 2008? Onde está o MySQL Workbench? Como vou fazer para migrar as bases? Gerar script de bancos gigantes? Nem pensar! Preciso instalar!
Mas como instalar esses aplicativos? Se fazer download, gera tráfego. Se pedir para a Locaweb tem que pagar e se pedir, de graça, não instala! Lembrando que esses aplicativos, no mínimo, são gratuitos e deveriam estar em uma zona em que os usuários pudessem obtê-los de forma fácil e sem cobrança. Pois bem, feito o download, hora de instalar. Abrindo o executável (lembrando que tem que ser a da versão 64bits) dá aviso de incompatibilidade. É preciso instalar o Service Pack 1 do SQL Server 2008 (mais tráfego). Baixado o SP1 é preciso instalá-lo. Tranquilo e instalado sem problemas. Hora de instalar o Management Studio...
Ao tentar abrir, outro problema?!?! É preciso do Framework 3.5! Incrivel... No Cloud Server vem instalado a versão 2.0 e 4.0 do Framework ASP.NET mas não tem a 3.5 ativado. Menos mal, porque no Windows Server 2008 é nativo, basta ativar. Realize os seguintes passos (retirado do Wiki):
Agora sim, tudo pronto! Vamos instalar o Management Studio. Clica no instalador e... Erro! Caramba... de novo!
TITLE: SQL Server Setup failure.
-------------------------------
SQL Server Setup has encountered the following error:
Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
A dica é: feche o Windows Explorer! Por algum motivo, a instalação do Management Studio não inicia quando o Windows Explorer estiver em aberto. Copie para a Área de Trabalho e abra o instalador... Agora sim! Depois de tanta malemolência pelo menos iniciemos a instalação. Para quem tem dúvidas e um passo-a-passo bem explicativo de como instalar o Management Studio, acesse aqui o post de Marcos dell Antonio. Há uma dica bem interessante que pode confundir o usuário na hora da instalação. Terminado a instalação, menos um item da lista de afazeres.
Consegui conectar ao SQL Server local, criei as bases, usuários, fiz restores, configurei o backup, providenciei tudo o que tinha que fazer onde o Plesk jamais pensaria em um dia ser. Agora o principal, testar um website. Publiquei o site no IIS e abri o navegador para visualizar. Erro!
Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Sabe o porquê disso? Eu instalei o ASP.NET 3.5 depois que eu já tinha a versão 4.0 instalada por causa do Management Studio então gerou conflito nas DLL's. Para resolver, faça o seguinte:
Agora vamos testar! Abri o navegador e digitei o endereço e... Mais erro!
There is a duplicate 'system.web.extensions/scripting/scriptResourceHandler' section defined
Mais conflitos! Se você tiver outra versão do System.Web.Extensions instalado, devido ao ASP.NET AJAX por exemplo, a versão que está no GAC do sistema difere da que você quer chamar ocorrendo ambiguidade. O correto seria alterar os assemblys mas como isso é muito trabalhoso e pode acontecer algum imprevisto para aqueles que não sabem manuseá-las, então aconselho o seguinte: remova toda a sectionGroup do seu web.config ou comente-as:
<!--
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere" />
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
-->
No caso comentei o sectionGroup do System.Web.Extension que pode estar na versão 1.0, 2.0 ou 3.5 que for.
Agora vamos lá! De pés juntos e mãos dadas: Abre o navegador e... e... e... Funcionou! Depois de um árduo trabalho aparentemente tudo estava normal. Vamos testar outros sites e... e... e... Mais erros!
Quem ainda não está acostumado a trabalhar com Windows Server 2008 e IIS 7 terá que aprender muito sobre permissões e tratamento de erros. Incontestavelmente a tela do erro 500 irá aparecer e muito se sua aplicação não estiver configurada adequadamente para o IIS 7. Nem sempre a mesma aplicação que está no IIS 6 irá funcionar no IIS 7. Então eis que surge a tela do Erro 500 Erro Interno do Servidor ou Error 500 Internal Server Error:
Ou então:
Dá para descobrir o que é? Vou dar a dica: revise seu web.config. "Ah, mas está tudo certo, não sei porque não funciona...". Engano, está errado. Já disse que o IIS 7 é chato, muito chato. O parser dele é muito minucioso e se não estiver nos padrões vai dar problema.
Se você não sabe utilizar bem o IIS e tem medo de alterar uma coisinha ali e outra acolá vou dar a maior dica: saia abrindo cada opção do painel da aplicação até que uma delas acuse um erro de configuração.
Por exemplo, abra o item Documento Padrão. Se ele estiver configurado corretamente então abrirá a próxima tela normalmente. Se tiver algum erro, aparecerá um alerta. Então no web.config você deve corrigir a sessão correspondente. Ficou claro? Saia clicando um a um até que um deles se denuncie podendo então fazer a correção.
O que ocorreu comigo foi que um site que estava no IIS 6 podia colocar a mesma página (index.aspx) como padrão, duas vezes, e não tinha problema. Quando foi para o IIS 7, na qual estava herdando a configuração pai, e foi adicionar a página index.aspx como padrão novamente, ele dava erro e não sabia porquê. Então removi a entrada do web.config e funcionou. Desabilitar a mensagem de erro amigável no navegador vai funcionar (encontrar o erro)? Não. Desabilitar as páginas de erros personalizáveis do IIS vai funcionar (encontrar o erro)? Talvez ou não. Depende muito do ambiente que está configurado e quem está manipulando.
Pronto! Mais um problema solucionado... Vamos testar outro site e... e... e... Erro! Agora aconteceu um erro 404. Mas como? Erro 404 de página não encontrada mas se o caminho está lá? Incrivelmente no IIS do Cloud Server possuem dois Applications Pools do Plesk (e mais outros nativos): Plesk(default)(2.0) e Plesk(default)(4.0). O pool do 2.0 quase nem sempre funciona. E um comportamento anormal é que se você tem um site pai em 2.0 e um filho em 2.0 às vezes pára de funcionar. O "correto" é ter um pai 2.0 ou 4.0 com filho sempre 4.0. Estranho? Pode crer! E onde está o pool do 3.5? Tem que criar na mão mesmo.
Nota: Se você reiniciar o IIS o Plesk pára de vez e não volta:
Você terá que iniciá-lo manualmente. Mas antes terá que iniciar seu pool também (que é muito suspeito):
Ajeitado uma coisinha ali, outra aqui, vamos testar mais algumas coisas e... e... e... Quase tudo certo. Em questão de funcionalidade (que deveria ser) está quase tudo certo a não ser o funcionamento do bom e velho Crystal Reports. Quem já leu o post de erros do Crystal aqui e aqui nos deparamos com o erro:
O inicializador de tipo de 'CrystalDecisions.CrystalReports.Engine.ReportDocument' acionou uma exceção
ou
The type initializer for 'CrystalDecisions.CrystalReports.Engine.ReportDocument' threw an exception
Cuidado! Esse não é o descritivo do erro. Só com isso não dá para saber o motivo. Faça o debug, log, exibição da pilha ou na própria tela exiba o erro (sem ter AJAX) que teremos o erro completo. No link dos dois posts anteriores que fiz explica o problema do Crystal na plataforma 64bits e como pode resolver. Só que o problema no meu caso era permissão.
Server Error in '/virtual_directory_name' Application.
Error in File UNKNOWN.RPT:
The request could not be submitted for background processing.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.COMException: Error in File UNKNOWN.RPT: The request could not be submitted for background processing.
Os usuários listados abaixo, não tinham permissão na execução de scripts DCOM e gravação em algumas pastas (principalmente as que estão na unidade C):
Esses são os usuários que devem ter privilégio (descritos abaixo) nas pastas listadas abaixo:
Obs: Para alguns servidores é preciso aplicar o Replace permission entries on all child objects nessas pastas.
Lembrando de reiniciar o IIS e/ou o servidor para recarregar as configurações.
Se estiver trabalhando com Windows Service ou Windows Form e ocorra o erro:
System.IO.FileNotFoundException: Retrieving the COM class factory for component with CLSID {5FF57840-5172-4482-9CA3-541C7878AE0F} failed due to the following error: 8007007e
Basta compilar sua aplicação em x86.
E agora, tudo certo? Até o momento sim. Porque não dizer que está tudo OK? Depois de ter ocorrido todos esses problemas, fica-se receoso com o futuro. Pode ser que ocorra outro problema posteriormente? Sim e irá.
Conforme disse anteriormente, o post não é para dizer mal sobre a Locaweb e/ou Plesk. Acho que eles prestam um serviço adequado para o nível nacional (até uso) contudo são coisas que acontecem que simplesmente poderiam ser sanadas antes de jogar o pepino para o cliente. Se você tiver algum problema desses e sua gerência for pelo cliente, nem adianta pedir que eles vão lhe informar: "o gerenciamento é por conta do cliente e não nos responsabilizamos" ou "a ferramenta (Plesk) é terceirizada e não prestamos suporte.". Enfim, espero que o post ajude a você, cliente e usuário, a corrigir seus problemas/pepinos que ocorrerem. Isso me lembra quando lançou o plug-and-play... a velha piadinha do plug-and-pray (ligar e rezar) não some da cabeça quando ocorre esse tipo de problema. Porque será?
Uma dica que dou sempre quando alguém quer contratar um servidor: leiam muito sobre os prós e contras. Os prós vejam no próprio site do prestador, os contras vejam nos relatos de usuários. No post a seguir não estou jogando a Locaweb contra a parede, apenas estou expondo erros que podem ser sanados de forma fácil mas que burocraticamente é jogado para o cliente se virar (nos 30!).
Nesse Cloud Server vem embutido o Plesk. Em poucas palavras serve para gerenciar a hospedagem através de uma interface web. É uma boa ferramenta de gerência, tem tudo para gerenciar sua hospedagem. Só que esse demais gera ocupação demais (redundância) de espaço em disco. Dos 50 Gb que você contrata, 40Gb é para o sistema operacional e 10Gb para seus arquivos. Sendo que dos 10Gb é para todos os seus arquivos, e-mails, banco de dados, etc. Ou seja, apenas usufrui dos 10Gb um pouco menos que 9Gb e olhe lá.
Bem, dizem que vem tudo preparado e instalado para usar... Verdade até certa parte! Quem está usando e é iniciante vai ver que é mil maravilhas. Dá para fazer o básico de tudo. O problema vem a seguir...
Um cliente contratou o Cloud Server gerenciado pelo cliente (ou seja, sobrou para o usuário final) e me passou para configurar e deixar no ponto de uso fazendo toda a migração e instalação. Em um passe de mágica surgem os problemas...
Os bancos de dados que vem são o MS SQL Server 2008 e o MySQL. Não há interface para dump e recovery das bases forçando a usar o Plesk para isso, mas não queria. Onde está o Management Studio 2008? Onde está o MySQL Workbench? Como vou fazer para migrar as bases? Gerar script de bancos gigantes? Nem pensar! Preciso instalar!
Mas como instalar esses aplicativos? Se fazer download, gera tráfego. Se pedir para a Locaweb tem que pagar e se pedir, de graça, não instala! Lembrando que esses aplicativos, no mínimo, são gratuitos e deveriam estar em uma zona em que os usuários pudessem obtê-los de forma fácil e sem cobrança. Pois bem, feito o download, hora de instalar. Abrindo o executável (lembrando que tem que ser a da versão 64bits) dá aviso de incompatibilidade. É preciso instalar o Service Pack 1 do SQL Server 2008 (mais tráfego). Baixado o SP1 é preciso instalá-lo. Tranquilo e instalado sem problemas. Hora de instalar o Management Studio...
Ao tentar abrir, outro problema?!?! É preciso do Framework 3.5! Incrivel... No Cloud Server vem instalado a versão 2.0 e 4.0 do Framework ASP.NET mas não tem a 3.5 ativado. Menos mal, porque no Windows Server 2008 é nativo, basta ativar. Realize os seguintes passos (retirado do Wiki):
- Clique em Start, Administrative Tools e selecione Server Manager;
- Na interface, clique em Features e clique em Add Features;
- Selecione a primeira opção .NET Framework 3.5.1 Features e adicione todos seus dependentes;
- Conclua a instalação do Framework.
Agora sim, tudo pronto! Vamos instalar o Management Studio. Clica no instalador e... Erro! Caramba... de novo!
TITLE: SQL Server Setup failure.
-------------------------------
SQL Server Setup has encountered the following error:
Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
A dica é: feche o Windows Explorer! Por algum motivo, a instalação do Management Studio não inicia quando o Windows Explorer estiver em aberto. Copie para a Área de Trabalho e abra o instalador... Agora sim! Depois de tanta malemolência pelo menos iniciemos a instalação. Para quem tem dúvidas e um passo-a-passo bem explicativo de como instalar o Management Studio, acesse aqui o post de Marcos dell Antonio. Há uma dica bem interessante que pode confundir o usuário na hora da instalação. Terminado a instalação, menos um item da lista de afazeres.
Consegui conectar ao SQL Server local, criei as bases, usuários, fiz restores, configurei o backup, providenciei tudo o que tinha que fazer onde o Plesk jamais pensaria em um dia ser. Agora o principal, testar um website. Publiquei o site no IIS e abri o navegador para visualizar. Erro!
Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Sabe o porquê disso? Eu instalei o ASP.NET 3.5 depois que eu já tinha a versão 4.0 instalada por causa do Management Studio então gerou conflito nas DLL's. Para resolver, faça o seguinte:
- Vá para a pasta C:\Windows\Microsoft.NET\Framework64\v4.0.30319;
- Execute o comando aspnet_regiis.exe -iru
Agora vamos testar! Abri o navegador e digitei o endereço e... Mais erro!
There is a duplicate 'system.web.extensions/scripting/scriptResourceHandler' section defined
Mais conflitos! Se você tiver outra versão do System.Web.Extensions instalado, devido ao ASP.NET AJAX por exemplo, a versão que está no GAC do sistema difere da que você quer chamar ocorrendo ambiguidade. O correto seria alterar os assemblys mas como isso é muito trabalhoso e pode acontecer algum imprevisto para aqueles que não sabem manuseá-las, então aconselho o seguinte: remova toda a sectionGroup do seu web.config ou comente-as:
<!--
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere" />
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
-->
No caso comentei o sectionGroup do System.Web.Extension que pode estar na versão 1.0, 2.0 ou 3.5 que for.
Agora vamos lá! De pés juntos e mãos dadas: Abre o navegador e... e... e... Funcionou! Depois de um árduo trabalho aparentemente tudo estava normal. Vamos testar outros sites e... e... e... Mais erros!
Quem ainda não está acostumado a trabalhar com Windows Server 2008 e IIS 7 terá que aprender muito sobre permissões e tratamento de erros. Incontestavelmente a tela do erro 500 irá aparecer e muito se sua aplicação não estiver configurada adequadamente para o IIS 7. Nem sempre a mesma aplicação que está no IIS 6 irá funcionar no IIS 7. Então eis que surge a tela do Erro 500 Erro Interno do Servidor ou Error 500 Internal Server Error:
Ou então:
Dá para descobrir o que é? Vou dar a dica: revise seu web.config. "Ah, mas está tudo certo, não sei porque não funciona...". Engano, está errado. Já disse que o IIS 7 é chato, muito chato. O parser dele é muito minucioso e se não estiver nos padrões vai dar problema.
Se você não sabe utilizar bem o IIS e tem medo de alterar uma coisinha ali e outra acolá vou dar a maior dica: saia abrindo cada opção do painel da aplicação até que uma delas acuse um erro de configuração.
Por exemplo, abra o item Documento Padrão. Se ele estiver configurado corretamente então abrirá a próxima tela normalmente. Se tiver algum erro, aparecerá um alerta. Então no web.config você deve corrigir a sessão correspondente. Ficou claro? Saia clicando um a um até que um deles se denuncie podendo então fazer a correção.
O que ocorreu comigo foi que um site que estava no IIS 6 podia colocar a mesma página (index.aspx) como padrão, duas vezes, e não tinha problema. Quando foi para o IIS 7, na qual estava herdando a configuração pai, e foi adicionar a página index.aspx como padrão novamente, ele dava erro e não sabia porquê. Então removi a entrada do web.config e funcionou. Desabilitar a mensagem de erro amigável no navegador vai funcionar (encontrar o erro)? Não. Desabilitar as páginas de erros personalizáveis do IIS vai funcionar (encontrar o erro)? Talvez ou não. Depende muito do ambiente que está configurado e quem está manipulando.
Pronto! Mais um problema solucionado... Vamos testar outro site e... e... e... Erro! Agora aconteceu um erro 404. Mas como? Erro 404 de página não encontrada mas se o caminho está lá? Incrivelmente no IIS do Cloud Server possuem dois Applications Pools do Plesk (e mais outros nativos): Plesk(default)(2.0) e Plesk(default)(4.0). O pool do 2.0 quase nem sempre funciona. E um comportamento anormal é que se você tem um site pai em 2.0 e um filho em 2.0 às vezes pára de funcionar. O "correto" é ter um pai 2.0 ou 4.0 com filho sempre 4.0. Estranho? Pode crer! E onde está o pool do 3.5? Tem que criar na mão mesmo.
Nota: Se você reiniciar o IIS o Plesk pára de vez e não volta:
Você terá que iniciá-lo manualmente. Mas antes terá que iniciar seu pool também (que é muito suspeito):
Ajeitado uma coisinha ali, outra aqui, vamos testar mais algumas coisas e... e... e... Quase tudo certo. Em questão de funcionalidade (que deveria ser) está quase tudo certo a não ser o funcionamento do bom e velho Crystal Reports. Quem já leu o post de erros do Crystal aqui e aqui nos deparamos com o erro:
O inicializador de tipo de 'CrystalDecisions.CrystalReports.Engine.ReportDocument' acionou uma exceção
ou
The type initializer for 'CrystalDecisions.CrystalReports.Engine.ReportDocument' threw an exception
Cuidado! Esse não é o descritivo do erro. Só com isso não dá para saber o motivo. Faça o debug, log, exibição da pilha ou na própria tela exiba o erro (sem ter AJAX) que teremos o erro completo. No link dos dois posts anteriores que fiz explica o problema do Crystal na plataforma 64bits e como pode resolver. Só que o problema no meu caso era permissão.
Server Error in '/virtual_directory_name' Application.
Error in File UNKNOWN.RPT:
The request could not be submitted for background processing.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.COMException: Error in File UNKNOWN.RPT: The request could not be submitted for background processing.
Os usuários listados abaixo, não tinham permissão na execução de scripts DCOM e gravação em algumas pastas (principalmente as que estão na unidade C):
- IWAN_plesk(default)
- IUSR
- IIS_IUSR
- NETWORK SERVICE
- INTERACTIVE
Esses são os usuários que devem ter privilégio (descritos abaixo) nas pastas listadas abaixo:
- C:\Windows\Temp\ : leitura \ escrita
- C:\Program Files (x86)\Business Objects\Common\2.8\bin\ : leitura
- C:\ : leitura
Obs: Para alguns servidores é preciso aplicar o Replace permission entries on all child objects nessas pastas.
Lembrando de reiniciar o IIS e/ou o servidor para recarregar as configurações.
Se estiver trabalhando com Windows Service ou Windows Form e ocorra o erro:
System.IO.FileNotFoundException: Retrieving the COM class factory for component with CLSID {5FF57840-5172-4482-9CA3-541C7878AE0F} failed due to the following error: 8007007e
Basta compilar sua aplicação em x86.
E agora, tudo certo? Até o momento sim. Porque não dizer que está tudo OK? Depois de ter ocorrido todos esses problemas, fica-se receoso com o futuro. Pode ser que ocorra outro problema posteriormente? Sim e irá.
Conforme disse anteriormente, o post não é para dizer mal sobre a Locaweb e/ou Plesk. Acho que eles prestam um serviço adequado para o nível nacional (até uso) contudo são coisas que acontecem que simplesmente poderiam ser sanadas antes de jogar o pepino para o cliente. Se você tiver algum problema desses e sua gerência for pelo cliente, nem adianta pedir que eles vão lhe informar: "o gerenciamento é por conta do cliente e não nos responsabilizamos" ou "a ferramenta (Plesk) é terceirizada e não prestamos suporte.". Enfim, espero que o post ajude a você, cliente e usuário, a corrigir seus problemas/pepinos que ocorrerem. Isso me lembra quando lançou o plug-and-play... a velha piadinha do plug-and-pray (ligar e rezar) não some da cabeça quando ocorre esse tipo de problema. Porque será?
Tocando/Emitindo som com C#
Dica rápida para emitir um som com C# usando a API do Windows: basta importar a função PlaySound. Crie a lista enumerada e importe a DLL utilizando os seguintes códigos:
// FLAGS DE SOM
[System.Flags]
public enum PlaySoundFlags : int
{
SND_SYNC = 0x0000,
SND_ASYNC = 0x0001,
SND_NODEFAULT = 0x0002,
SND_LOOP = 0x0008,
SND_NOSTOP = 0x0010,
SND_NOWAIT = 0x00002000,
SND_FILENAME = 0x00020000,
SND_RESOURCE = 0x00040004
}
// IMPORTAÇÃO DO COMPONENTE DE SOM
[DllImport("winmm.dll", EntryPoint = "PlaySound", SetLastError = true, CharSet = CharSet.Unicode, ThrowOnUnmappableChar = true)]
private static extern bool PlaySound(string szSound, System.IntPtr hMod, PlaySoundFlags flags);
Não precisa copiar a DLL para a aplicação uma vez que ele busca na biblioteca do próprio Windows.
Para tocar, execute o método (exemplo):
PlaySound("sound.wav", new System.IntPtr(), PlaySoundFlags.SND_ASYNC);
Sempre use a flag PlaySoundFlags.SND_ASYNC (forma assíncrona). É aconselhável usar ela do que PlaySoundFlags.SND_SYNC (forma síncrona) se estiver trabalhando com outro processamento em paralelo. Ou seja, após o som, se for realizar algum outro método ou trecho de código. De forma assíncrona ele irá tocar e continuar com o processamento do código que tiver logo abaixo (paralelo). De forma síncrona pode haver lentidão no processo pois à vezes o som pode demorar a tocar ou ter que esperar terminar para prosseguir (contínuo). Faça os testes antes para ver o diferencial.
Agora sim! Volte ao post do Microterminal e adicione sua função para tocar um som quando apertar * (asterisco).
// FLAGS DE SOM
[System.Flags]
public enum PlaySoundFlags : int
{
SND_SYNC = 0x0000,
SND_ASYNC = 0x0001,
SND_NODEFAULT = 0x0002,
SND_LOOP = 0x0008,
SND_NOSTOP = 0x0010,
SND_NOWAIT = 0x00002000,
SND_FILENAME = 0x00020000,
SND_RESOURCE = 0x00040004
}
// IMPORTAÇÃO DO COMPONENTE DE SOM
[DllImport("winmm.dll", EntryPoint = "PlaySound", SetLastError = true, CharSet = CharSet.Unicode, ThrowOnUnmappableChar = true)]
private static extern bool PlaySound(string szSound, System.IntPtr hMod, PlaySoundFlags flags);
Não precisa copiar a DLL para a aplicação uma vez que ele busca na biblioteca do próprio Windows.
Para tocar, execute o método (exemplo):
PlaySound("sound.wav", new System.IntPtr(), PlaySoundFlags.SND_ASYNC);
Sempre use a flag PlaySoundFlags.SND_ASYNC (forma assíncrona). É aconselhável usar ela do que PlaySoundFlags.SND_SYNC (forma síncrona) se estiver trabalhando com outro processamento em paralelo. Ou seja, após o som, se for realizar algum outro método ou trecho de código. De forma assíncrona ele irá tocar e continuar com o processamento do código que tiver logo abaixo (paralelo). De forma síncrona pode haver lentidão no processo pois à vezes o som pode demorar a tocar ou ter que esperar terminar para prosseguir (contínuo). Faça os testes antes para ver o diferencial.
Agora sim! Volte ao post do Microterminal e adicione sua função para tocar um som quando apertar * (asterisco).
Comunicando com microterminal em ASP.NET
Quem já foi em supermercado e nunca viu aquelas maquininhas que o operador fica digitando? Pois é... estamos falando dela mesma. Parece ser fácil seu uso, mas quem começa a trabalhar com elas é de perder os cabelos.
Nesse artigo veremos como comunicar com um microterminal via TCP/IP e trocar informações (ida e volta). Para isso vamos utilizar o modelo da Gertec MT 720. Uma breve descrição do aparelho e seu uso (retirado daqui):
Daí pensamos: "sem problemas! é só converter pra VB.NET a partir do VB"... Também pensei nisso e não consegui! Dando uma olhada de perto no código-fonte dá para saber que as proezas encontradas são só possíveis por artifícios que a linguagem oferece: por exemplo, ponteiros. Quem já programou em VB via a grande flexibilidade da linguagem de fazer tudo o que quer e do jeito que era mais conveniente. Maravilha! Pena que tenhamos que seguir certos padrões. Fica a dica: se não quiser perder tempo, pegue logo o código prontinho lá na página do fabricante (vem também no CD quando compra o aparelho) e utilize. De preferência use o Delphi e em seguida em VB. Se quiser aventurar vamos com C#...
Se escolheu C# siga lendo pois, em diante, veremos como fazer... Teremos os seguintes objetivos na implementação:
Instalação
Leia o manual do usuário aqui. Em resumo: ligue o microterminal na rede elétrica e conecte na porta traseira um cabo RJ-45 no dispositivo e a rede. Em seguida configure, no microterminal, o IP do Servidor (no meu caso, considerei minha máquina local com o IP 192.168.1.100, por exemplo). Demais configurações a seu gosto...
Implementação
Criemos um Windows Form. Coloquei alguns controles para embelezar a aplicação...
O mais importante é adicionar um objeto Timer. Os demais coloquei para gerar a aplicação final (que ficará no tray - perto do relógio - e outras coisas fru-frus). Configure seu Timer com Interval de 50. Pegue a DLL pmtg.dll e copie para sua aplicação. Eu disse copie! Você não conseguirá aplicar Reference sobre ela. Clique com o botão direito sobre a DLL e escolha Properties. Em Copy to Output Directory coloque Copy Always.
Agora vamos ao código! Clique sobre o WinForm e escolha View Code. Cole os códigos abaixo para que possamos usá-las no form:
// VARIÁVEIS
IntPtr v_Hwnd;
int statusCard;
int statusSerial;
int MsgReceiveData = 1;
string[] dados = new string[255];
// INICIALIZAÇÃO DE FUNÇÕES EXTERNAS
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_startserver(IntPtr mywhnd, int conecmsg, int commumsg);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern void mt_finishserver();
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_getkey(int id, StringBuilder str);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_backspace(int id);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_dispstr(int id, string str);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_dispch(int id, char ch);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_dispclrln(int id, int lin);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]]
public static extern int mt_gotoxy(int id, int lin, int col);
Em seguida adicionamos as duas funções primordiais: início (quando carregar o formulário) e término (quando fechar o formulário):
private void MicroTerminal_Load(object sender, EventArgs e)
{
v_Hwnd = this.Handle;
statusCard = 0;
statusSerial = 0;
if (mt_startserver(v_Hwnd, 0, MsgReceiveData) == 1)
{
temporizadorLista.Enabled = true;
}
else
MessageBox.Show("Não foi possível carregar os módulos de conexão à leitora!");
}
private void MicroTerminal_FormClosed(object sender, FormClosedEventArgs e)
{
temporizadorLista.Enabled = false;
mt_finishserver();
}
Lembrando que esses eventos devem estar configurados (não é apenas copiar e colar o código, lembra? deve-se indicar lá em Events do Form). Com isso, ao fazer o primeiro teste, sua aplicação já estará recebendo dados do microterminal. Em seguida devemos adicionar um evento Tick ao Timer. Ou seja, a cada 50 milisegundos (lembra que colocamos com esse valor) irá ser executado um determinado método.
Antes disso vamos criar um método que irá limpar a tela do microterminal e reiniciar os dados de entrada:
private void ReiniciaEntrada(int i)
{
// Limpa as duas linhas e o que foi armazenado
dados[i] = "";
mt_dispclrln(i, 1);
mt_dispclrln(i, 2);
// Coloca o cursor na primeira linha e prepara o display
mt_gotoxy(i, 1, 0);
mt_dispstr(i, "Numero: ");
mt_gotoxy(i, 2, 0);
}
Enfim adicionamos o código que irá ler temporariamente cada leitora conectada à rede e coletar/processar os dados de acordo com o que desejar. No meu caso deixei o seguinte:
private void temporizadorLista_Tick(object sender, EventArgs e)
{
StringBuilder rntStr = new StringBuilder();
int i = 0;
// Loop em toda faixa de Ips úteis: cada leitora conectada na rede
while (i < 255)
{
// Captura algo do teclado
if (mt_getkey(i, rntStr) == 1)
{
string chrAsHex = ((int)rntStr[0]).ToString("x");
// Entrada do display caso seja um número
if ((chrAsHex == "3030") || (chrAsHex == "30") || (chrAsHex == "31") || (chrAsHex == "32") || (chrAsHex == "33") || (chrAsHex == "34") || (chrAsHex == "35") || (chrAsHex == "36") || (chrAsHex == "37") || (chrAsHex == "38") || (chrAsHex == "39"))
{
if (dados[i].Length >= 20)
dados[i] = dados[i].Substring(0, 19) + rntStr[0];
else
dados[i] += rntStr[0];
mt_dispch(i, rntStr[0]);
}
// Se for um ENTER, dá a entrada na tela para mostrar
else if (chrAsHex == "d")
{
// Captura e trata a entrada
if (dados[i] != "")
{
// Faz o processamento do que desejar em dados[i]
}
// Limpa tela
ReiniciaEntrada(i);
}
// Se for um ESC, apaga tudo
else if (chrAsHex == "1b")
{
// Limpa tela
ReiniciaEntrada(i);
}
// Se for backspace apaga último caractere do display
else if (chrAsHex == "8")
{
if (dados[i].Length > 0)
dados[i] = dados[i].Substring(0, dados[i].Length - 1);
mt_backspace(i);
}
// Se apertar * toca o som
else if (chrAsHex == "2a")
{
// Toca um sonzinho... depois publico o código de tocar som!
}
}
i++;
}
}
Feito! Rode sua aplicação e digite algo no teclado do microterminal e verá que o que está sendo digitado está indo tanto para a aplicação quanto para o display (no microterminal). A saída seria algo do tipo:
Se precisar de saída na tela crie um outro WinForm que ocupe toda tela (sua) e captura o que está no display do microterminal. Assim é mais fácil! Ou faça do jeito que sua imaginação mandar! O mais difícil já passou...
Para quem quiser capturar os IPs de cada microterminal, utilize os métodos:
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern TTABSOCK mt_connectlist();
ou
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern StringBuilder mt_ipfromid(int id);
Nessas funções tem algumas particularidades muito chatinhas de se trabalhar (veja no manual das funções) por isso deixei de lado. Principalmente a classe:
[StructLayout(LayoutKind.Sequential)]
public struct TTABSOCK
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
public UInt32[] TSOCK;
}
Quem quiser se aventurar nela, fica aí a dica. Esse artigo merecia até uma vídeo-aula, mas a preguiça às vezes é muito forte! É até legalzinho ter esses desafios, mas às vezes se torna muito chato quando não consegue. Enfim, quanto menos se estressar, melhor! Então tente usar as implementações que já a Gertec já disponibilizou, caso não queira aventurar, a menos que precise de algo mais específico.
Falar que nem Marcoratti: "eu sei, é apenas ASP.NET, mas eu gosto!"
Nesse artigo veremos como comunicar com um microterminal via TCP/IP e trocar informações (ida e volta). Para isso vamos utilizar o modelo da Gertec MT 720. Uma breve descrição do aparelho e seu uso (retirado daqui):
"O MT 720 é um excelente microterminal que opera em rede Ethernet com protocolos TCP-IP. Seu teclado com 20 teclas programáveis pode ser utilizado com funções específicas de atalhos para agilizar a operação.
As teclas re-legendáveis permitem a identificação da função de cada tecla. O display com back light (iluminado), com 20 caracteres por 2 linhas, permite facilmente a visualização da informação, principalmente em ambientes que possuem pouca iluminação, como bares noturnos, por exemplo.
Através de uma porta de teclado (AT/PS2) e mais 3 portas Seriais (RS-232) é possível a conexão de periféricos como: Leitor de Código de Barras, Display de Cliente, Balança, Impressora, etc.
O MT 720 é ideal para aplicações de Cartão de Consumo, soluções para Bares, Lanchonetes, Restaurantes Self-Service, Livrarias, Papelarias, apontamento de produção em Indústrias."Na própria página do dispositivo (citada acima) tem alguns downloads de arquivos, dentre eles alguns códigos-fontes com exemplos de como fazer a comunicação bem como realizar as operações pelas quais foi criado. Um porém: só tem disponíveis nas linguagens C++, Delphi e VB (não é VB.NET).
Daí pensamos: "sem problemas! é só converter pra VB.NET a partir do VB"... Também pensei nisso e não consegui! Dando uma olhada de perto no código-fonte dá para saber que as proezas encontradas são só possíveis por artifícios que a linguagem oferece: por exemplo, ponteiros. Quem já programou em VB via a grande flexibilidade da linguagem de fazer tudo o que quer e do jeito que era mais conveniente. Maravilha! Pena que tenhamos que seguir certos padrões. Fica a dica: se não quiser perder tempo, pegue logo o código prontinho lá na página do fabricante (vem também no CD quando compra o aparelho) e utilize. De preferência use o Delphi e em seguida em VB. Se quiser aventurar vamos com C#...
Se escolheu C# siga lendo pois, em diante, veremos como fazer... Teremos os seguintes objetivos na implementação:
- Criar uma única aplicação que irá receber e enviar os dados;
- Exibir o que foi digitado tanto no microterminal quanto no monitor.
Instalação
Leia o manual do usuário aqui. Em resumo: ligue o microterminal na rede elétrica e conecte na porta traseira um cabo RJ-45 no dispositivo e a rede. Em seguida configure, no microterminal, o IP do Servidor (no meu caso, considerei minha máquina local com o IP 192.168.1.100, por exemplo). Demais configurações a seu gosto...
Implementação
Criemos um Windows Form. Coloquei alguns controles para embelezar a aplicação...
O mais importante é adicionar um objeto Timer. Os demais coloquei para gerar a aplicação final (que ficará no tray - perto do relógio - e outras coisas fru-frus). Configure seu Timer com Interval de 50. Pegue a DLL pmtg.dll e copie para sua aplicação. Eu disse copie! Você não conseguirá aplicar Reference sobre ela. Clique com o botão direito sobre a DLL e escolha Properties. Em Copy to Output Directory coloque Copy Always.
Agora vamos ao código! Clique sobre o WinForm e escolha View Code. Cole os códigos abaixo para que possamos usá-las no form:
// VARIÁVEIS
IntPtr v_Hwnd;
int statusCard;
int statusSerial;
int MsgReceiveData = 1;
string[] dados = new string[255];
// INICIALIZAÇÃO DE FUNÇÕES EXTERNAS
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_startserver(IntPtr mywhnd, int conecmsg, int commumsg);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern void mt_finishserver();
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_getkey(int id, StringBuilder str);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_backspace(int id);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_dispstr(int id, string str);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_dispch(int id, char ch);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int mt_dispclrln(int id, int lin);
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]]
public static extern int mt_gotoxy(int id, int lin, int col);
Em seguida adicionamos as duas funções primordiais: início (quando carregar o formulário) e término (quando fechar o formulário):
private void MicroTerminal_Load(object sender, EventArgs e)
{
v_Hwnd = this.Handle;
statusCard = 0;
statusSerial = 0;
if (mt_startserver(v_Hwnd, 0, MsgReceiveData) == 1)
{
temporizadorLista.Enabled = true;
}
else
MessageBox.Show("Não foi possível carregar os módulos de conexão à leitora!");
}
private void MicroTerminal_FormClosed(object sender, FormClosedEventArgs e)
{
temporizadorLista.Enabled = false;
mt_finishserver();
}
Lembrando que esses eventos devem estar configurados (não é apenas copiar e colar o código, lembra? deve-se indicar lá em Events do Form). Com isso, ao fazer o primeiro teste, sua aplicação já estará recebendo dados do microterminal. Em seguida devemos adicionar um evento Tick ao Timer. Ou seja, a cada 50 milisegundos (lembra que colocamos com esse valor) irá ser executado um determinado método.
Antes disso vamos criar um método que irá limpar a tela do microterminal e reiniciar os dados de entrada:
private void ReiniciaEntrada(int i)
{
// Limpa as duas linhas e o que foi armazenado
dados[i] = "";
mt_dispclrln(i, 1);
mt_dispclrln(i, 2);
// Coloca o cursor na primeira linha e prepara o display
mt_gotoxy(i, 1, 0);
mt_dispstr(i, "Numero: ");
mt_gotoxy(i, 2, 0);
}
Enfim adicionamos o código que irá ler temporariamente cada leitora conectada à rede e coletar/processar os dados de acordo com o que desejar. No meu caso deixei o seguinte:
private void temporizadorLista_Tick(object sender, EventArgs e)
{
StringBuilder rntStr = new StringBuilder();
int i = 0;
// Loop em toda faixa de Ips úteis: cada leitora conectada na rede
while (i < 255)
{
// Captura algo do teclado
if (mt_getkey(i, rntStr) == 1)
{
string chrAsHex = ((int)rntStr[0]).ToString("x");
// Entrada do display caso seja um número
if ((chrAsHex == "3030") || (chrAsHex == "30") || (chrAsHex == "31") || (chrAsHex == "32") || (chrAsHex == "33") || (chrAsHex == "34") || (chrAsHex == "35") || (chrAsHex == "36") || (chrAsHex == "37") || (chrAsHex == "38") || (chrAsHex == "39"))
{
if (dados[i].Length >= 20)
dados[i] = dados[i].Substring(0, 19) + rntStr[0];
else
dados[i] += rntStr[0];
mt_dispch(i, rntStr[0]);
}
// Se for um ENTER, dá a entrada na tela para mostrar
else if (chrAsHex == "d")
{
// Captura e trata a entrada
if (dados[i] != "")
{
// Faz o processamento do que desejar em dados[i]
}
// Limpa tela
ReiniciaEntrada(i);
}
// Se for um ESC, apaga tudo
else if (chrAsHex == "1b")
{
// Limpa tela
ReiniciaEntrada(i);
}
// Se for backspace apaga último caractere do display
else if (chrAsHex == "8")
{
if (dados[i].Length > 0)
dados[i] = dados[i].Substring(0, dados[i].Length - 1);
mt_backspace(i);
}
// Se apertar * toca o som
else if (chrAsHex == "2a")
{
// Toca um sonzinho... depois publico o código de tocar som!
}
}
i++;
}
}
Feito! Rode sua aplicação e digite algo no teclado do microterminal e verá que o que está sendo digitado está indo tanto para a aplicação quanto para o display (no microterminal). A saída seria algo do tipo:
Se precisar de saída na tela crie um outro WinForm que ocupe toda tela (sua) e captura o que está no display do microterminal. Assim é mais fácil! Ou faça do jeito que sua imaginação mandar! O mais difícil já passou...
Para quem quiser capturar os IPs de cada microterminal, utilize os métodos:
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern TTABSOCK mt_connectlist();
ou
[DllImport("pmtg.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern StringBuilder mt_ipfromid(int id);
Nessas funções tem algumas particularidades muito chatinhas de se trabalhar (veja no manual das funções) por isso deixei de lado. Principalmente a classe:
[StructLayout(LayoutKind.Sequential)]
public struct TTABSOCK
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
public UInt32[] TSOCK;
}
Quem quiser se aventurar nela, fica aí a dica. Esse artigo merecia até uma vídeo-aula, mas a preguiça às vezes é muito forte! É até legalzinho ter esses desafios, mas às vezes se torna muito chato quando não consegue. Enfim, quanto menos se estressar, melhor! Então tente usar as implementações que já a Gertec já disponibilizou, caso não queira aventurar, a menos que precise de algo mais específico.
Falar que nem Marcoratti: "eu sei, é apenas ASP.NET, mas eu gosto!"


















