Доступ Элементе Httplistener Отказано
Я пишу HTTP-сервер в C#.
когда я пытаюсь выполнить функцию HttpListener.Start()
Я HttpListenerException
слова
"Доступ Запрещен".
когда я запускаю приложение в режиме администратора в windows 7 он работает нормально.
могу ли я заставить его работать без режима администратора? если да, то как?
Если нет, то как я могу изменить приложение в режим администратора после запуска?
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;
}
}
}
}
}
10 ответов:
Да, вы можете запустить httplistener в режиме администратора. Все, что вам нужно сделать, это предоставить разрешения на конкретный URL. например,
netsh http add urlacl url=http://+:80/MyUri user=DOMAIN\user
документация здесь.
могу ли я заставить его работать без режима администратора? если да, то как? Если нет, то как я могу изменить приложение в режим администратора после запуска?
вы не можете, это должно начинаться с повышенных привилегий. Вы можете перезапустить его с помощью
runas
глагол, который предложит пользователю перейти в режим администратораstatic void RestartAsAdmin() { var startInfo = new ProcessStartInfo("yourApp.exe") { Verb = "runas" }; Process.Start(startInfo); Environment.Exit(0); }
EDIT: на самом деле, это не так; HttpListener может работать без повышенных привилегий, но вам нужно дать разрешение на URL, на котором вы хотите слушать. Смотрите ответ Даррела Миллера для сведения.
Если вы используете
http://localhost:80/
в качестве префикса вы можете прослушивать http-запросы без каких-либо административных привилегий.
синтаксис был неправильным для меня, вы должны включить кавычки:
netsh http add urlacl url="http://+:4200/" user=everyone
в противном случае я получил "неверный параметр"
Если вы хотите использовать флаг "пользователь=все", вам нужно настроить его на свой системный язык. На английском языке это, как уже упоминалось:
netsh http add urlacl url=http://+:80/ user=Everyone
по-немецки это будет:
netsh http add urlacl url=http://+:80/ user=Jeder
в качестве альтернативы, которая не требует высоты или netsh вы также можете использовать TcpListener например.
ниже приведен измененный фрагмент этого образца: 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
методы чтения и записи:
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); } }); }
вы можете запустить приложение в качестве администратора, если вы добавляете манифест приложения в свой проект.
просто добавьте новый элемент в свой проект и выберите "файл манифеста приложения". Измените
<requestedExecutionLevel>
элемент to:<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
по умолчанию Windows определяет следующий префикс, который доступен всем: http://+: 80 / Temporary_Listen_Addresses/
Так что вы можете зарегистрировать свой
HttpListener
через:
Prefixes.Add("http://+:80/Temporary_Listen_Addresses/" + Guid.NewGuid().ToString("D") + "/";
это иногда вызывает проблемы с программным обеспечением, таким как Skype, который будет пытаться использовать порт 80 по умолчанию.
httpListener.Prefixes.Add("http://*:4444/");
можно использовать "*" так вы выполните следующую команду cmd как администратор
netsh http add urlacl url=http://*:4444/ user=username
не использовать +, должны использовать *, потому что вы спецификации *:4444~.
https://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx
Я также столкнулся с подобной проблемой.Если вы уже зарезервировали url-адрес, то вам нужно сначала Удалить url-адрес для запуска в режиме без администратора, иначе он не будет работать с ошибкой Access is Denied.
netsh http delete urlacl url=http://+:80
Comments