代码之家  ›  专栏  ›  技术社区  ›  Randall Flagg

HttpListener访问被拒绝

  •  146
  • Randall Flagg  · 技术社区  · 14 年前

    当我试图执行这个函数时 HttpListener.Start() HttpListenerException

    “拒绝访问”。

    当我在Windows7中以管理模式运行应用程序时,它运行得很好。

    我能让它在没有管理模式的情况下运行吗?如果是怎么做的? 如果没有,我如何使应用程序在开始运行后更改为管理模式?

    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 回复  |  直到 11 年前
        1
  •  297
  •   Håkon K. Olafsen    5 年前

    是的,您可以在非管理模式下运行HttpListener。您只需授予特定URL的权限。例如

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

    文件是 here .

        2
  •  27
  •   Community Michael Schmitz    7 年前

    你不能,必须从提升权限开始。你可以用 runas 动词,它将提示用户切换到管理模式

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

    Darrel Miller's answer 详细情况。

        3
  •  22
  •   Ehsan Mirsaeedi    11 年前

    如果你使用 http://localhost:80/

        4
  •  20
  •   Michele d'Amico    9 年前

    语法对我来说是错误的,你必须包括引号:

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

    否则我收到“参数不正确”

        5
  •  13
  •   Christoph Brückmann    8 年前

    如果要使用“user=Everyone”标志,则需要将其调整为系统语言。在英语中,如前所述:

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

    德语是:

    netsh http add urlacl url=http://+:80/ user=Jeder
    
        6
  •  10
  •   Sebastian    7 年前

    作为不需要提升或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);
            }
        });
    }
    
        7
  •  7
  •   R.Titov    8 年前

    如果将应用程序清单添加到项目中,则可以以管理员身份启动应用程序。

    <requestedExecutionLevel> 元素到:

    <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
    
        8
  •  5
  •   Sebastian    7 年前

    默认情况下,Windows定义了对所有人都可用的以下前缀: http://+:80/Temporary_Listen_Addresses/

    HttpListener 通过:

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

        9
  •  4
  •   Yirkha    7 年前
    httpListener.Prefixes.Add("http://*:4444/");
    

    您使用“*”以便以管理员身份执行以下命令

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

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

        10
  •  1
  •   Vivek Nuna Chetan sabhaya    8 年前

    我也遇到了类似的问题。如果您已经保留了url,那么您必须先删除url才能在非管理模式下运行,否则它将失败,并出现Access is Denied错误。

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