Search code examples
wpftexthyperlinkdownload

retrieve links from external file


I'm working on a GUI that has as its main use downloading tools from the web.

The app is projected for .Net Framework 3.5 (for compatibility) and works great so far, but in my mind sparkled the following issue: every time one of those apps changes the link I have to alter it in my project too so it could reflect the latest version/link.

Would it be possible to read the links from a local text file or even better a pastbin/googledoc so I can modify the links externally?

Wish it was as simple as putting string ccleaner = "www.ccleaner.link etc. in the txt file and read it with File.ReadAllText... App.xaml.cs:

namespace myapp
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public void Application_Startup(object sender, StartupEventArgs e)
        {
            var wc = new WebClient();
            var csv = wc.DownloadString("https://docs.google.com/spreadsheets/d/1IjQfWMIQyw8NuncRd91iWJD_GdWTCqrrX11pTBv1bEA/edit?usp=sharing");
            var links = csv
                .Split('\n') // Extract lines
                .Skip(1) // Skip headers line
                .Select(line => line.Split(',')) // Separate application name from download URL
                .ToDictionary(tokens => tokens[0], tokens => tokens[1]);
            var CCleanerLink = links["CCleaner"];
        }
    }
}

tools.xaml.cs(which is a page in mainwindow)

namespace myapp
{
    /// <summary>
    /// Interaction logic for tools.xaml
    /// </summary>
    public partial class tools : Page
    {
        public tools()
        {
            InitializeComponent();

        }
        
        
        public void downloadFile(String address, String filename)
        {
            WebClient down = new WebClient();
            down.Headers.Add(HttpRequestHeader.UserAgent,"Mozilla/5.0 (compatible; http://example.org/)");
            ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
            down.DownloadFileAsync(new Uri(address), filename);
        }
        
        private void Autor_Checked(object sender, RoutedEventArgs e)
        {
            downloadFile("https://live.sysinternals.com/autoruns.exe", "autoruns.exe");

        }

        private void Ccleaner_Checked(object sender, RoutedEventArgs e)
        {
            downloadFile(CCleanerLink, "ccleaner.exe");
        }

    }

}

Solution

  • You could store your up-to-date links in a CSV file stored on your server, whose format would be similar to:

    Application,URL
    CCleaner,https://www.ccleaner.com/fr-fr/ccleaner/download
    ...,...
    ...,...
    ...,...
    

    And in your application retrieve it:

    var wc = new WebClient();

    var csv = wc.DownloadString("https://docs.google.com/spreadsheets/d/1IjQfWMIQyw8NuncRd91iWJD_GdWTCqrrX11pTBv1bEA/gviz/tq?tqx=out:csv&sheet=Sheet1");
    var links = csv
        .Split('\n') // Extract lines
        .Skip(1) // Skip headers line
        .Where(line => line != "") // Remove empty lines
        .Select(line => line.Split(',')) // Separate application name from download URL
        .ToDictionary(tokens => tokens[0].Trim('"'), tokens => tokens[1].Trim('"'));
    var CCleanerLink = links["CCleaner"];
    

    To cleanly manage the URIs in your application you can use the repository pattern:

    public static class ApplicationsRepository
    {
        private static IDictionary<string, string> URIs = null;
    
        public static IDictionary<string, string> GetAllURIs()
        {
            if (URIs == null)
            {
                var wc = new WebClient();
                var csv = wc.DownloadString("http://myhosting.com/application/tools-downloader/config/links.csv");
                URIs = csv
                    .Split('\n')
                    .Skip(1)
                    .Select(line => line.Split(','))
                    .ToDictionary(tokens => tokens[0], tokens => tokens[1]);
            }
    
            return URIs;
        }
    
        public static string GetURI(string applicationName)
        {
            var allURIs = GetAllURIs();
    
            string applicationURI = null;
            allURIs.TryGetValue(applicationName, out applicationURI);
    
            return applicationURI;
        }
    }
    

    Then in your event handler:

    private void Ccleaner_Checked(object sender, RoutedEventArgs e)
    {
        downloadFile(ApplicationsRepository.GetURI("CCleaner"), "ccleaner.exe");
    }