windows-7 c#-4.0 uac httplistener

windows 7 - Acceso de HttpListener denegado



windows-7 c#-4.0 (10)

Estoy escribiendo un servidor HTTP en C #.

Cuando trato de ejecutar la función HttpListener.Start() obtengo una HttpListenerException dice

"Acceso denegado".

Cuando ejecuto la aplicación en modo de administrador en Windows 7, funciona bien.

¿Puedo hacer que funcione sin el modo de administrador? Si es así, ¿cómo? Si no, ¿cómo puedo hacer que la aplicación cambie al modo de administración después de comenzar a correr?

using System; using System.Net; namespace ConsoleApplication1 { class Program { private HttpListener httpListener = null; static void Main(string[] args) { Program p = new Program(); p.Server(); } public void Server() { this.httpListener = new HttpListener(); if (httpListener.IsListening) throw new InvalidOperationException("Server is currently running."); httpListener.Prefixes.Clear(); httpListener.Prefixes.Add("http://*:4444/"); try { httpListener.Start(); //Throws Exception } catch (HttpListenerException ex) { if (ex.Message.Contains("Access is denied")) { return; } else { throw; } } } } }


¿Puedo hacer que funcione sin el modo de administrador? Si es así, ¿cómo? Si no, ¿cómo puedo hacer que la aplicación cambie al modo de administración después de comenzar a correr?

No puede, tiene que comenzar con privilegios elevados. Puede reiniciarlo con el verbo runas , que pedirá al usuario que cambie al modo de administración

static void RestartAsAdmin() { var startInfo = new ProcessStartInfo("yourApp.exe") { Verb = "runas" }; Process.Start(startInfo); Environment.Exit(0); }

EDITAR: en realidad, eso no es verdad; HttpListener puede ejecutarse sin privilegios elevados, pero debe otorgar permiso para la URL en la que desea escuchar. Vea la respuesta de Darrel Miller para más detalles.


Como alternativa que no requiere elevación o netsh, también puede usar TcpListener, por ejemplo.

El siguiente es un extracto modificado de este ejemplo: https://github.com/googlesamples/oauth-apps-for-windows/tree/master/OAuthDesktopApp

// Generates state and PKCE values. string state = randomDataBase64url(32); string code_verifier = randomDataBase64url(32); string code_challenge = base64urlencodeNoPadding(sha256(code_verifier)); const string code_challenge_method = "S256"; // Creates a redirect URI using an available port on the loopback address. var listener = new TcpListener(IPAddress.Loopback, 0); listener.Start(); string redirectURI = string.Format("http://{0}:{1}/", IPAddress.Loopback, ((IPEndPoint)listener.LocalEndpoint).Port); output("redirect URI: " + redirectURI); // Creates the OAuth 2.0 authorization request. string authorizationRequest = string.Format("{0}?response_type=code&scope=openid%20profile&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}", authorizationEndpoint, System.Uri.EscapeDataString(redirectURI), clientID, state, code_challenge, code_challenge_method); // Opens request in the browser. System.Diagnostics.Process.Start(authorizationRequest); // Waits for the OAuth authorization response. var client = await listener.AcceptTcpClientAsync(); // Read response. var response = ReadString(client); // Brings this app back to the foreground. this.Activate(); // Sends an HTTP response to the browser. WriteStringAsync(client, "<html><head><meta http-equiv=''refresh'' content=''10;url=https://google.com''></head><body>Please close this window and return to the app.</body></html>").ContinueWith(t => { client.Dispose(); listener.Stop(); Console.WriteLine("HTTP server stopped."); }); // TODO: Check the response here to get the authorization code and verify the code challenge

Los métodos de lectura y escritura son:

private string ReadString(TcpClient client) { var readBuffer = new byte[client.ReceiveBufferSize]; string fullServerReply = null; using (var inStream = new MemoryStream()) { var stream = client.GetStream(); while (stream.DataAvailable) { var numberOfBytesRead = stream.Read(readBuffer, 0, readBuffer.Length); if (numberOfBytesRead <= 0) break; inStream.Write(readBuffer, 0, numberOfBytesRead); } fullServerReply = Encoding.UTF8.GetString(inStream.ToArray()); } return fullServerReply; } private Task WriteStringAsync(TcpClient client, string str) { return Task.Run(() => { using (var writer = new StreamWriter(client.GetStream(), new UTF8Encoding(false))) { writer.Write("HTTP/1.0 200 OK"); writer.Write(Environment.NewLine); writer.Write("Content-Type: text/html; charset=UTF-8"); writer.Write(Environment.NewLine); writer.Write("Content-Length: " + str.Length); writer.Write(Environment.NewLine); writer.Write(Environment.NewLine); writer.Write(str); } }); }


De forma predeterminada, Windows define el siguiente prefijo que está disponible para todos: http://+:80/Temporary_Listen_Addresses/

Para que pueda registrar su HttpListener través de:

Prefixes.Add("http://+:80/Temporary_Listen_Addresses/" + Guid.NewGuid().ToString("D") + "/";

Esto a veces causa problemas con software como Skype, que intentará utilizar el puerto 80 de forma predeterminada.


En caso de que quiera usar el indicador "usuario = todos", debe ajustarlo al idioma de su sistema. En inglés es como se menciona:

netsh http add urlacl url=http://+:80/ user=Everyone

En alemán sería:

netsh http add urlacl url=http://+:80/ user=Jeder


La sintaxis fue incorrecta para mí, debes incluir las comillas:

netsh http add urlacl url="http://+:4200/" user=everyone

de lo contrario, recibí "El parámetro es incorrecto"


Puede iniciar su aplicación como administrador si agrega Manifiesto de aplicación a su proyecto.

Simplemente agregue un nuevo ítem a su proyecto y seleccione "Archivo de Manifiesto de Aplicación". Cambie el elemento <requestedExecutionLevel> a:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />


Sí, puedes ejecutar HttpListener en modo no administrador. Todo lo que necesita hacer es otorgar permisos a la URL en particular. p.ej

netsh http add urlacl url=http://+:80/MyUri user=DOMAIN/user

La documentación está here .


Si usa http://localhost:80/ como prefijo, puede escuchar las solicitudes http sin necesidad de privilegios administrativos.


También me enfrenté a un problema similar. Si ya ha reservado la URL, primero debe eliminar la url para ejecutarla en modo no administrador, de lo contrario fallará con el error Acceso denegado.

netsh http delete urlacl url=http://+:80