Frage

Ich schreibe einen HTTP -Server in C#.

Wenn ich versuche, die Funktion auszuführen HttpListener.Start() Ich bekomme eine HttpListenerException Sprichwort

"Zugriff abgelehnt".

Wenn ich die App im Administratormodus in Windows 7 ausführe, funktioniert sie gut.

Kann ich es ohne Administratormodus laufen lassen? Wenn ja, wie? Wenn nicht, wie kann ich nach dem Ausführen die App in den Administratormodus ändern?

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;
                }
            }
        }
    }
}
War es hilfreich?

Lösung

Ja, Sie können httplistener im Nicht-Adminampfer-Modus ausführen. Alles, was Sie tun müssen, ist, der jeweiligen URL Berechtigungen zu gewähren. z.B

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

Dokumentation ist hier.

Andere Tipps

Kann ich es ohne Administratormodus laufen lassen? Wenn ja, wie? Wenn nicht, wie kann ich nach dem Ausführen die App in den Administratormodus ändern?

Sie können nicht, es muss mit erhöhten Privilegien beginnen. Sie können es mit dem neu starten runas Verb, das den Benutzer auffordert, in den Administratormodus zu wechseln

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

Bearbeiten: Eigentlich ist das nicht wahr; Httplistener kann ohne erhöhte Privilegien laufen, aber Sie müssen die Erlaubnis für die URL geben, auf die Sie zuhören möchten. Sehen Darrel Millers Antwort für Details.

Wenn du benutzt http://localhost:80/ Als Präfix können Sie HTTP -Anfragen ohne Verwaltungsrechte anhören.

Die Syntax war falsch für mich, Sie müssen die Zitate einschließen:

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

Andernfalls habe ich "Der Parameter ist falsch" erhalten. "

Falls Sie das Flag "user = jeder" verwenden möchten, müssen Sie es an Ihre Systemsprache anpassen. Auf Englisch ist es wie erwähnt:

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

Auf Deutsch wäre es:

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

Als Alternative, die keine Höhe oder Netsh erfordert, können Sie beispielsweise auch TCplistener verwenden.

Das Folgende ist ein modifizierter Auszug dieses Beispiels:https://github.com/googlessamples/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

Die Lese- und Schreibmethoden sind:

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);
        }
    });
}

Sie können Ihre Anwendung als Administrator starten, wenn Sie Ihrem Projekt Bewerbungsinformationen hinzufügen.

Fügen Sie einfach Ihrem Projekt ein neues Element hinzu und wählen Sie "Anwendungsmanifest -Datei". Ändere das <requestedExecutionLevel> Element zu:

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

Standardmäßig definiert Windows das folgende Präfix, das allen verfügbar ist:http: //+: 80/temporary_listen_addresses/

So können Sie Ihre registrieren HttpListener über:

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

Dies führt manchmal zu Problemen mit Software wie Skype, die standardmäßig versuchen, Port 80 zu verwenden.

httpListener.Prefixes.Add("http://*:4444/");

Sie verwenden "*"

netsh http add urlacl url=http://*:4444/ user=username

Keine Verwendung +, muss *verwenden *, weil Sie spec *: 4444 ~.

https://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx

Ich habe auch ein ähnliches Problem gestellt. Wenn Sie bereits URL reserviert haben, müssen Sie zuerst die URL löschen, um im Nicht -Administrator -Modus ausgeführt zu werden.

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

Netsh erfordert die Rechte von Verwaltungsrechten

Sie können dies für Localhost ohne Administratorrechte beheben, indem Sie IgnoreWriteExceptions festlegen:

listener.IgnoreWriteExceptions = True
listener.Start()
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top