-1

Intro:

I've hit a design wall and encountered a issue that is beyond me. I could use guidance.

I am creating a application and I'd like to use url protocols for accessibility/security and user convivence. Until I'm ready to build a API. I have codded the features I want thus far into my app including a download method and a standard url protocool procedure.

Problem:

All the download addresses I'm using are encoded and require WebUtility.UrlDecode() after parsing to extract a useable download address. The question is: How can I store the address generated upon left-clicking it and pass it to my file downloader method? I'm confused on how to accomplish this task. To reiterate: I want to capture a portion of my url protocol hosted online via left-click and store it in a variable to use.

How program should run:

NOTE: ✔️ = working. ❌ = not working.

  1. A unknown user is on "a page" and presented with a choice to Download & Install via through App ✔️
  2. User left-clicks the hyperlink. ✔️
  3. Download address information is passed to the application. ❌
  4. Application opens. ✔️
  5. Download initiates of "x-item" and installs (only works when I manually insert a link). ✔️

Practical address example:

<a href="myApp://https%4A%7F%0B.amazon.8943fj9f8j3%2Ftest.json" target="_blank">Download & Install via myApp</a>

I'd want to store...

https%4A%7F%0B.amazon.8943fj9f8j3%2Ftest.json //store this. 

//and it would be decoded and made into a usable address to download from...
Example code...
//output desired from the original url. 
string arg = "https%4A%7F%0B.amazon.8943fj9f8j3%2Ftest.json ";
string encoded_url = arg.Trim().Split('/').Last();
string url = Uri.UnescapeDataString(enc_url);
//output example --> https://www.example.com/yadayada/sample.json

TLDR: For simplicity and clarity...in my mind the application would work similarly to how a user would join a discord server. A user would click a discord server invite-hyperlink and then the discord app would open with a prompting message asking...if the user would like to join the server.

Rudimentary Code.

        static void Main()

            //TESTING...START

            string[] args = Environment.GetCommandLineArgs();

            //args[0] is always the path to the application
            RegisterMyAppProtocol(args[0]);
            //the above method posted before, that edits registry      

            try
            {
                Console.WriteLine("Argument: " + args[1].Replace("myapp:", string.Empty));
            }
            catch
            {
                Console.WriteLine("No argument(s)");  //if there's an exception, there's no argument
            }

            Console.ReadLine();

            //TESTING...END


        }

        static void RegisterMyAppProtocol(string AppPath)  //myAppPath = full path to application
        {
            //open myApp protocol's subkey
            RegistryKey key = Registry.ClassesRoot.OpenSubKey("myApp");


            //if the protocol is not registered yet...register it
            if (key == null)  
            {
                key = Registry.ClassesRoot.CreateSubKey("myApp");
                key.SetValue(string.Empty, "URL: myApp Protocol");
                key.SetValue("URL Protocol", string.Empty);

                key = key.CreateSubKey(@"shell\open\command");
                key.SetValue(string.Empty, AppPath.Replace("dll", "exe") + " " + "%1");
                //%1 represents the argument - this tells windows to open this program with an argument / parameter
            }

            key.Close();
        }
Cherarium
  • 1
  • 6
  • `static async Task Main(...)` then you don't need to worry about calling an async method from a sync method. You should probably quote your app path and %1 in the `shell\open\command` registry value. Don't trust `argv[0]` for the full path, instead you could use `Process.GetCurrentProcess().MainModule.FileName`. How are you passing `args[1]` to your `FileDownloader`? – Jeremy Lakeman Feb 23 '22 at 02:57
  • Thanks for the tips. At the moment I'm not passing any arguments to the ``FileDownloader`` that what I'm trying to figure out how to do. The main argument I'd like to pass is the ``download address`` from the hyperlink to ``FileDownloader.cs`` – Cherarium Feb 23 '22 at 03:08
  • https://stackoverflow.com/questions/1405048/how-do-i-decode-a-url-parameter-using-c with `argv[1][6..]`? – Jeremy Lakeman Feb 23 '22 at 03:14
  • I already have a function to ``decode url parameters`` and it returns the correct address for my download(s). But this is only when I manually input that address into the decoder. My question is: how would the program get that said address when it's hosted online? Clicking it is not enough. – Cherarium Feb 23 '22 at 03:22
  • Url Protocols must be installed before they can be used. Your registry code looked ok, but have you debugged what is actually in the registry? – Jeremy Lakeman Feb 23 '22 at 03:37
  • I have found a solution to my problem. – Cherarium Feb 24 '22 at 01:02

1 Answers1

0

I chained multiple arguments and was able to get the solution to my problem. The result is that the rawUrl/decodedUrl variables return as the needed string from pressing protocol url hyperlink.

            var rawUrl = string.Empty;
            var decodedUrl = string.Empty;

            try
            {
                //if there's an argument passed, write it
                rawUrl = args[0];
                if (rawUrl[rawUrl.Length - 1] == '/')
                    rawUrl = rawUrl.Remove(rawUrl.Length - 1);
                Console.WriteLine($"Argument: {rawUrl}");
                decodedUrl = returnURL(rawUrl);
            }
            catch
            {
                Console.WriteLine("No argument(s)");  //if there's an exception, there's no argument
            }


            if (!string.IsNullOrEmpty(decodedUrl))
            {
                  //input method details so it does stuff. 
            }
Cherarium
  • 1
  • 6