Question

Je suis en train d'écrire un serveur HTTP en C #.

Lorsque je tente d'exécuter la fonction HttpListener.Start() je reçois un HttpListenerException disant

  

"Accès refusé".

Quand je lance l'application en mode admin dans Windows 7, il fonctionne très bien.

Puis-je faire fonctionner sans le mode d'administration? si oui, comment? Sinon, comment puis-je faire le changement d'application en mode admin après le démarrage en marche?

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;
                }
            }
        }
    }
}
Était-ce utile?

La solution

Oui, vous pouvez exécuter HttpListener en mode non-admin. Tout ce que vous devez faire est accorder les autorisations à l'URL particulière. par exemple.

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

La documentation est .

Autres conseils

  

Puis-je faire fonctionner sans le mode d'administration? si oui, comment? Sinon, comment puis-je faire le changement d'application en mode admin après le démarrage en marche?

Vous ne pouvez pas, il doit commencer avec des privilèges élevés. Vous pouvez redémarrer avec le verbe runas, qui invite l'utilisateur à passer en mode admin

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

EDIT: En fait, ce n'est pas vrai; HttpListener peut fonctionner sans privilèges élevés, mais vous devez donner la permission de l'URL sur laquelle vous voulez écouter. Voir Darrel de réponse de Miller pour plus de détails.

Si vous utilisez http://localhost:80/ comme préfixe, vous pouvez écouter des requêtes HTTP sans avoir besoin de privilèges d'administration.

La syntaxe était mauvaise pour moi, vous devez inclure les guillemets:

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

sinon je reçu "Le paramètre est incorrect"

Si vous voulez utiliser le drapeau « utilisateur = Tout le monde », vous devez l'adapter à votre langue du système. En anglais, il est mentionné:

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

En allemand, il serait:

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

Comme une alternative qui ne nécessite pas d'élévation ou NETSH vous pouvez également utiliser TcpListener par exemple.

Ce qui suit est un extrait modifié de cet échantillon: https://github.com/googlesamples/oauth-apps-for -Windows / arbre / maître / 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

Les méthodes de lecture et d'écriture étant:

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

Vous pouvez démarrer votre application en tant qu'administrateur si vous ajoutez Manifest application à votre projet.

Il suffit d'ajouter un nouvel élément à votre projet et sélectionnez « Fichier manifeste de l'application ». Changer l'élément <requestedExecutionLevel> à:

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

Par défaut, Windows définit le préfixe suivant qui est accessible à tous: http: // +: 80 / Temporary_Listen_Addresses /

Vous pouvez enregistrer votre HttpListener via:

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

Cela provoque parfois des problèmes avec des logiciels tels que Skype, qui va essayer d'utiliser le port 80 par défaut.

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

vous utilisez "*" si vous exécutez cmd suivante en tant qu'administrateur

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

pas d'utilisation +, doit utiliser *, parce que vous spec *. ~ 4444

https://msdn.microsoft.com/en -nous / bibliothèque / system.net.httplistener.aspx

J'ai aussi fait face à problème.Si similaire, vous avez déjà réservé URL alors vous devez d'abord supprimer l'URL pour exécuter en mode non admin sinon il échouera avec l'accès est refusé erreur.

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

netsh nécessite des droits d'administrateur

Vous pouvez corriger cela pour localhost sans droits d'administrateur en définissant IgnoreWriteExceptions:

listener.IgnoreWriteExceptions = True
listener.Start()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top