WebClient 下载问题“拒绝访问”

问题描述

我启动应用程序时的错误

System.Net.WebException: Exception during request WebClient. ---> System.UnauthorizedAccessException: Access denied: "C:\Users\pwlam\Desktop\launcher\Loader-master\Loader\LoadeRel\bin\Debug".
       в System.IO.__Error.WinIOError(Int32 errorCode,String maybeFullPath)
       в System.IO.FileStream.Init(String path,FileMode mode,FileAccess access,Int32 rights,Boolean useRights,FileShare share,Int32 bufferSize,FileOptions options,Security_ATTRIBUTES secAttrs,String msgPath,Boolean bFromProxy,Boolean useLongPath,Boolean checkHost)
       в System.IO.FileStream..ctor(String path,FileAccess access)
       в System.Net.WebClient.DownloadFile(Uri address,String fileName)
       --- End of trace of the internal exception stack ---
       в System.Net.WebClient.DownloadFile(Uri address,String fileName)
       в System.Net.WebClient.DownloadFile(String address,String fileName)
       в Launcher.update.timer1_Tick(Object sender,EventArgs e) в C:\Users\pwlam\Desktop\launcher\Loader-master\Loader\LoadeRel\update.line:77
       в System.Windows.Forms.Timer.OnTick(EventArgs e)
       в System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
       в System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)

update.cs:

// uses the the System namespace
using System;
// uses the System.Windows.Forms namespace
using System.Windows.Forms;
// uses the System.Net namespace
using System.Net;
// uses the System.Threading namespace
using System.Threading;
//(The using comments were given by Peatreat)


namespace Launcher
//Open brackets
{
    public partial class update : MetroFramework.Forms.MetroForm
    //Open brackets
    {
        public update()
        //Open brackets
        {
            InitializeComponent(); //Kys
        //Close brackets
        }

        string versioncheck = new WebClient().DownloadString(settings.Check); //Gets the value of your version.txt and saves it as a string named versioncheck

        string location = System.IO.Path.GetDirectoryName(Application.ExecutablePath); //Gets the current dir/location of the loader and saves it as a string named location

        private void update_Load(object sender,EventArgs e) //The code that is executed as soon as u open this form up
    //Open brackets
    {
        
        metroLabel1.Text = "Loading."; //Changes the label to say "Loading."
        //Thread.Sleep means it will take a quick nap
        
        //Note: every 1000 = 1 second
        Thread.Sleep(100);
        metroLabel1.Text = "Loading.."; //Changes the label to say "Loading.."
        Thread.Sleep(100); //Thread.Sleep means it will take a quick nap
        metroLabel1.Text = "Loading..."; //Changes the label to say "Loading..."
        Thread.Sleep(100); //Thread.Sleep means it will take a quick nap
        metroLabel1.Text = "Loading."; //Changes the label to say "Loading."
        Thread.Sleep(100); //Thread.Sleep means it will take a quick nap
        metroLabel1.Text = "Loading.."; //Changes the label to say "Loading.."
        Thread.Sleep(100); //Thread.Sleep means it will take a quick nap
        metroLabel1.Text = "Loading..."; //Changes the label to say "Loading..."
        Thread.Sleep(100); //Thread.Sleep means it will take a quick nap
        metroLabel1.Text = "Checking for update"; //Changes the label to say "Checking for update"
        //End of animation
        

        if (versioncheck != settings.version.ToString()) //Checks if url string is not equal to string in memory. -Peatreat
        //Open brackets
        {
            timer1.Start(); //Starts timer1 so look at the code down below
        //Close brackets
        }
        else //If its not equal:
        //Open brackets
        {
            timer2.Start(); //Starts timer2 so look at the code down below
        //Close brackets
        }
    //Close brackets
    }

    private void timer1_Tick(object sender,EventArgs e) //This is timer1 and if it was activated,well... code is below,this is self explanitory so kys
    //Open brackets
    {
        metroLabel1.Text = "Update found!"; //Changes the label to say "Update found!"
        Thread.Sleep(100);//Thread.Sleep means it will take a quick nap
        metroLabel1.Text = "Downloading"; //Changes the label to say "Downloading"
        WebClient webClient = new WebClient(); //The thing used to connect to the worst place in the world...! The INTERNET!!! *DUN DUN DUNNNNNNN*
        webClient.DownloadFile(settings.Update,location); //Code to download "your" loader
        metroLabel1.Text = "Done!"; //Changes the label to say "Done!"
        Application.Exit(); //Close the loader after it downloaded the new loader
        timer1.Stop(); //Stops the timer so this code ends and does not repeat. If you dont undertstand this,comment out this entire line and find out.
    //Close brackets
    }

    private void timer2_Tick(object sender,EventArgs e)
    //Open brackets
    {
        metroLabel1.Text = "No update found :)"; //Changes the label to say "No update found :)"
        Thread.Sleep(1000); //Thread.Sleep means it will take a quick nap for 1 sec (Litterly)
        //---------------------------------------------------------------------------------------
        //All this does is just closes this form and opens form2. so lemme break it down:
        //Makes a variable called form2 which equals to open form2
        var form1 = new Main();
        //Overall its just a tricky way to not have to declare an entire function (event handler) 
        //outside of the current one that handles Form2.Closed event. – KDecker 
        //Also note: I didnt really kNow how to explain this but this guy did a good job!
        form1.Closed += (s,args) => this.Close();
        //This shows form2
        form1.Show();
        //This closes/hides this form
        this.Hide();
        //---------------------------------------------------------------------------------------
        timer2.Stop();//Stops the timer so this code ends and does not repeat. If you dont undertstand this,comment out this entire line and find out.
    //Close brackets
    }
//Close brackets
}
//Close brackets
}

在 settings.cs 中,我有文件的路径。

和这个用户代理

public static string UserAgentString = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/46.0.2490.33 Safari/537.36";

有人可以向我展示一些例子或指出正确的方向吗?

感谢您的帮助。

解决方法

您将 location 变量设置为目录名称

string location = System.IO.Path.GetDirectoryName(Application.ExecutablePath);

然后您尝试将 HTTP 请求中的流写入该目录

webClient.DownloadFile(settings.Update,location);

您需要将其写入该目录中的文件,例如

webClient.DownloadFile(settings.Update,Path.Combine(location,"myfile.txt"));

System.UnauthorizedAccessException: Access denied: 准确地告诉您发生了什么。正在将数据写入不允许的位置。错误信息中也提到了位置

C:\Users\pwlam\Desktop\launcher\Loader-master\Loader\LoadeRel\bin\Debug

由于该位置不是文件,因此您会收到错误消息。