Passing Command Line arguments to .exe generated after build #407

Closed
opened 2026-01-29 16:38:47 +00:00 by claunia · 9 comments
Owner

Originally created by @VH97 on GitHub (Nov 5, 2019).

Originally assigned to: @GregorBiswanger on GitHub.

I have a desktop App.exe built using Electron.Net, if I pass parameters along with "electronize start", these arguments get ignored. In command prompt, when I run App.exe with command line arguments it does not accept the parameters being passed to it.

Example: App.exe hello 123
electronize start hello 123

I tried to make little changes in code to try to achieve the same. I have attached my findings below in Changes file.
It would be great if this feature could be supported in the coming days. Thank you.

Changes.docx

Originally created by @VH97 on GitHub (Nov 5, 2019). Originally assigned to: @GregorBiswanger on GitHub. I have a desktop App.exe built using Electron.Net, if I pass parameters along with "electronize start", these arguments get ignored. In command prompt, when I run App.exe with command line arguments it does not accept the parameters being passed to it. Example: App.exe hello 123 electronize start hello 123 I tried to make little changes in code to try to achieve the same. I have attached my findings below in Changes file. It would be great if this feature could be supported in the coming days. Thank you. [Changes.docx](https://github.com/ElectronNET/Electron.NET/files/3810517/Changes.docx)
claunia added the FeatureIn progress labels 2026-01-29 16:38:47 +00:00
Author
Owner

@MrCircuit commented on GitHub (Nov 22, 2019):

The implementation sketch given by @VH97 works except for one case:

For the "electronize start [args]" sequence one has to pay attention to the first parameter. If it denotes a valid path, this parameter will be used by the ExecuteAsync method of StartElectronCommand for the "aspCoreProjectPath". A safer solution would be to extend this part like this:

            string aspCoreProjectPath = "";
            if (_args.Length > 0)
            {
                if (Directory.Exists(_args[0]))
                {
                    aspCoreProjectPath = _args[0];
                    _args = _args.Skip(1).ToArray();
                }
            }
            else
            {
                aspCoreProjectPath = Directory.GetCurrentDirectory();
            }

Otherwise, the parameters of "electronize start" must be escaped e.g. using commands like "--path [coreProjectPath]" and "--args [argument list as string]".

@MrCircuit commented on GitHub (Nov 22, 2019): The implementation sketch given by @VH97 works except for one case: For the "electronize start [args]" sequence one has to pay attention to the first parameter. If it denotes a valid path, this parameter will be used by the ExecuteAsync method of StartElectronCommand for the "aspCoreProjectPath". A safer solution would be to extend this part like this: string aspCoreProjectPath = ""; if (_args.Length > 0) { if (Directory.Exists(_args[0])) { aspCoreProjectPath = _args[0]; _args = _args.Skip(1).ToArray(); } } else { aspCoreProjectPath = Directory.GetCurrentDirectory(); } Otherwise, the parameters of "electronize start" must be escaped e.g. using commands like "--path [coreProjectPath]" and "--args [argument list as string]".
Author
Owner

@MrCircuit commented on GitHub (Nov 22, 2019):

I've implemented the latter because it seemed more reliable to me. I kept the case of exactly one parameter that is interpreted as the aspCoreProjectPath for the sake of backward compatibility.

Shall I create a PR?

@MrCircuit commented on GitHub (Nov 22, 2019): I've implemented the latter because it seemed more reliable to me. I kept the case of exactly one parameter that is interpreted as the aspCoreProjectPath for the sake of backward compatibility. Shall I create a PR?
Author
Owner

@GregorBiswanger commented on GitHub (Nov 30, 2019):

Implemented! Available in Electron.NET version 7.30.2.

You can start the app with:

electronize start /args --dog=woof --test=true

or

myapp.exe /args --dog=woof --test=true

With the Electron.NET API you can get the value:

if (await Electron.App.CommandLine.HasSwitchAsync("dog"))
{
   string value = await Electron.App.CommandLine.GetSwitchValueAsync("dog");
   await Electron.Dialog.ShowMessageBoxAsync(value);
}      
@GregorBiswanger commented on GitHub (Nov 30, 2019): Implemented! Available in Electron.NET version 7.30.2. **You can start the app with:** `electronize start /args --dog=woof --test=true` or `myapp.exe /args --dog=woof --test=true` **With the Electron.NET API you can get the value:** ``` if (await Electron.App.CommandLine.HasSwitchAsync("dog")) { string value = await Electron.App.CommandLine.GetSwitchValueAsync("dog"); await Electron.Dialog.ShowMessageBoxAsync(value); } ```
Author
Owner

@VH97 commented on GitHub (Nov 30, 2019):

Thank you!

@VH97 commented on GitHub (Nov 30, 2019): Thank you!
Author
Owner

@MrCircuit commented on GitHub (May 18, 2021):

Just one remark on the feature: The command line arguments are passed in lowercase to the Electron.NET API.

Took me quite some time to find out :-P

@MrCircuit commented on GitHub (May 18, 2021): Just one remark on the feature: The command line arguments are passed in **lowercase** to the Electron.NET API. Took me quite some time to find out :-P
Author
Owner

@locoruiz commented on GitHub (Feb 11, 2022):

Hello, this works very well, however, I need to access a Filepath when a file is dropped on the app.exe to open it.
Or to open it with the protocol from the browser (like Zoom), is this possible?

@locoruiz commented on GitHub (Feb 11, 2022): Hello, this works very well, however, I need to access a Filepath when a file is dropped on the app.exe to open it. Or to open it with the protocol from the browser (like Zoom), is this possible?
Author
Owner

@danatcofo commented on GitHub (Feb 11, 2022):

@locoruiz

for url support you need to register a scheme with the os and associate it with the app. This is different for each os in how you do this.

in the code to handle the scheme

In Mac

info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>CFBundleURLTypes</key>
  <array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>None</string>
        <key>CFBundleUrlIconFile</key>
        <string>Contents/Resouces/MyApp.icns</string>
        <key>CFBundleUrlName</key>
        <string>com.myapp.app</string>
        <key>CFBundleUrlSchemes</key>
        <array>
            <string>myappscheme</string>
        </array>
    </dict>
  </array>
  <key>NSPrincipalClass</key>
  <string>AtomApplication</string>
</dict>
</plist>

electron.manifest.json

{
  "build": {
      "protocols": [
      {
        "name": "myapp",
        "role": "Viewer",
        "schemes": [ "myappscheme"]
      }
    ]
  },
  "mac": {
    "appBundleId": "com.myapp.app",
    "appCategoryType": "app-category-type=public.app-category.developer-tools",
    "extendedInfo": "info.plist"
  }
}

please note that you might have to do some pathing alterations to get the electron.manifest.json embedded paths to resolve correctly

csharp code

app.On("open-url", o => {
  // myappscheme://the/rest/of/the/url
  var url = o.ToString();
  // Do logic here to parse the url for intended results
});

In Windows/Linux

app.On("second-instance", o => {
  var args = ((JToken)o).ToObject(typeof(List<string>)) as List<string>;
  var url = args.FirstOrDefault(i => i.StartsWith("myappscheme://");
  if (string.IsNullOrWhitespace(url) == false) {
    // Do logic here to parse the url for intended results
  }
});

Likewise handling files is similar, you must first register the app as a handler for the file type and that is os dependent.

In Windows with NSIS

Nsis install script adddition

; Register the extension with your app, look up RegisterExtension in NSIS documentation
${RegisterExtension} "$INSTDIR\MyApplication.exe" ".ext" "NAME_FOR_EXTENSION"

Don't ask me how to integrate that off the shelf with electron-builder, I have a very customized nsis build script that using the unpacked outputs.
In Windows/Linux

csharp code

app.On("second-instance", o => {
   var args = ((JToken)o).ToObject(typeof(List<string>)) as List<string>;
   var path = args
      .SkipWhile(a => !a.Equals("--allow-file-access-from-files"))
      .Skip(1).FirstOrDefault();
   if (string.IsNullOrWhiteSpace(path) == false) {
      // do something with the path
   }
});

Notice this is the same event listener in windows/linux as the scheme (url) handler

In Mac

csharp

  app.On("open-file", async o =>
  {
      var path = o.ToString();
      // Do something with the path
  });

Note that the file handlers described here also work as the handlers for any Recent Documents that are attached to the program in the OS

Now I'm sure I've definitely missed something here in this long winded explanation as there are too many intricacies that I figured out, got set up and working and promptly forgot about but this should get you started.

@danatcofo commented on GitHub (Feb 11, 2022): @locoruiz for url support you need to register a scheme with the os and associate it with the app. This is different for each os in how you do this. in the code to handle the scheme **In Mac** ***info.plist*** ```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>None</string> <key>CFBundleUrlIconFile</key> <string>Contents/Resouces/MyApp.icns</string> <key>CFBundleUrlName</key> <string>com.myapp.app</string> <key>CFBundleUrlSchemes</key> <array> <string>myappscheme</string> </array> </dict> </array> <key>NSPrincipalClass</key> <string>AtomApplication</string> </dict> </plist> ``` ***electron.manifest.json*** ```json { "build": { "protocols": [ { "name": "myapp", "role": "Viewer", "schemes": [ "myappscheme"] } ] }, "mac": { "appBundleId": "com.myapp.app", "appCategoryType": "app-category-type=public.app-category.developer-tools", "extendedInfo": "info.plist" } } ``` > please note that you might have to do some pathing alterations to get the electron.manifest.json embedded paths to resolve correctly ***csharp code*** ```csharp app.On("open-url", o => { // myappscheme://the/rest/of/the/url var url = o.ToString(); // Do logic here to parse the url for intended results }); ``` **In Windows/Linux** ```csharp app.On("second-instance", o => { var args = ((JToken)o).ToObject(typeof(List<string>)) as List<string>; var url = args.FirstOrDefault(i => i.StartsWith("myappscheme://"); if (string.IsNullOrWhitespace(url) == false) { // Do logic here to parse the url for intended results } }); ``` Likewise handling files is similar, you must first register the app as a handler for the file type and that is os dependent. **In Windows with NSIS** ***Nsis install script adddition*** ```NSIS ; Register the extension with your app, look up RegisterExtension in NSIS documentation ${RegisterExtension} "$INSTDIR\MyApplication.exe" ".ext" "NAME_FOR_EXTENSION" ``` > Don't ask me how to integrate that off the shelf with electron-builder, I have a very customized nsis build script that using the unpacked outputs. **In Windows/Linux** ***csharp code*** ```csharp app.On("second-instance", o => { var args = ((JToken)o).ToObject(typeof(List<string>)) as List<string>; var path = args .SkipWhile(a => !a.Equals("--allow-file-access-from-files")) .Skip(1).FirstOrDefault(); if (string.IsNullOrWhiteSpace(path) == false) { // do something with the path } }); ``` > Notice this is the same event listener in windows/linux as the scheme (url) handler **In Mac** ***csharp*** ```csharp app.On("open-file", async o => { var path = o.ToString(); // Do something with the path }); ``` > Note that the file handlers described here also work as the handlers for any Recent Documents that are attached to the program in the OS Now I'm sure I've definitely missed something here in this long winded explanation as there are too many intricacies that I figured out, got set up and working and promptly forgot about but this should get you started.
Author
Owner

@locoruiz commented on GitHub (Feb 11, 2022):

@locoruiz

for url support you need to register a scheme with the os and associate it with the app. This is different for each os in how you do this.

in the code to handle the scheme

In Mac

info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>CFBundleURLTypes</key>
  <array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>None</string>
        <key>CFBundleUrlIconFile</key>
        <string>Contents/Resouces/MyApp.icns</string>
        <key>CFBundleUrlName</key>
        <string>com.myapp.app</string>
        <key>CFBundleUrlSchemes</key>
        <array>
            <string>myappscheme</string>
        </array>
    </dict>
  </array>
  <key>NSPrincipalClass</key>
  <string>AtomApplication</string>
</dict>
</plist>

electron.manifest.json

{
  "build": {
      "protocols": [
      {
        "name": "myapp",
        "role": "Viewer",
        "schemes": [ "myappscheme"]
      }
    ]
  },
  "mac": {
    "appBundleId": "com.myapp.app",
    "appCategoryType": "app-category-type=public.app-category.developer-tools",
    "extendedInfo": "info.plist"
  }
}

please note that you might have to do some pathing alterations to get the electron.manifest.json embedded paths to resolve correctly

csharp code

app.On("open-url", o => {
  // myappscheme://the/rest/of/the/url
  var url = o.ToString();
  // Do logic here to parse the url for intended results
});

In Windows/Linux

app.On("second-instance", o => {
  var args = ((JToken)o).ToObject(typeof(List<string>)) as List<string>;
  var url = args.FirstOrDefault(i => i.StartsWith("myappscheme://");
  if (string.IsNullOrWhitespace(url) == false) {
    // Do logic here to parse the url for intended results
  }
});

Likewise handling files is similar, you must first register the app as a handler for the file type and that is os dependent.

In Windows with NSIS

Nsis install script adddition

; Register the extension with your app, look up RegisterExtension in NSIS documentation
${RegisterExtension} "$INSTDIR\MyApplication.exe" ".ext" "NAME_FOR_EXTENSION"

Don't ask me how to integrate that off the shelf with electron-builder, I have a very customized nsis build script that using the unpacked outputs.
In Windows/Linux

csharp code

app.On("second-instance", o => {
   var args = ((JToken)o).ToObject(typeof(List<string>)) as List<string>;
   var path = args
      .SkipWhile(a => !a.Equals("--allow-file-access-from-files"))
      .Skip(1).FirstOrDefault();
   if (string.IsNullOrWhiteSpace(path) == false) {
      // do something with the path
   }
});

Notice this is the same event listener in windows/linux as the scheme (url) handler

In Mac

csharp

  app.On("open-file", async o =>
  {
      var path = o.ToString();
      // Do something with the path
  });

Note that the file handlers described here also work as the handlers for any Recent Documents that are attached to the program in the OS

Now I'm sure I've definitely missed something here in this long winded explanation as there are too many intricacies that I figured out, got set up and working and promptly forgot about but this should get you started.

Thank you very much!

@locoruiz commented on GitHub (Feb 11, 2022): > @locoruiz > > for url support you need to register a scheme with the os and associate it with the app. This is different for each os in how you do this. > > in the code to handle the scheme > > **In Mac** > > _**info.plist**_ > > ``` > <?xml version="1.0" encoding="UTF-8"?> > <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> > <plist version="1.0"> > <dict> > <key>CFBundleURLTypes</key> > <array> > <dict> > <key>CFBundleTypeRole</key> > <string>None</string> > <key>CFBundleUrlIconFile</key> > <string>Contents/Resouces/MyApp.icns</string> > <key>CFBundleUrlName</key> > <string>com.myapp.app</string> > <key>CFBundleUrlSchemes</key> > <array> > <string>myappscheme</string> > </array> > </dict> > </array> > <key>NSPrincipalClass</key> > <string>AtomApplication</string> > </dict> > </plist> > ``` > > _**electron.manifest.json**_ > > ```json > { > "build": { > "protocols": [ > { > "name": "myapp", > "role": "Viewer", > "schemes": [ "myappscheme"] > } > ] > }, > "mac": { > "appBundleId": "com.myapp.app", > "appCategoryType": "app-category-type=public.app-category.developer-tools", > "extendedInfo": "info.plist" > } > } > ``` > > > please note that you might have to do some pathing alterations to get the electron.manifest.json embedded paths to resolve correctly > > _**csharp code**_ > > ```cs > app.On("open-url", o => { > // myappscheme://the/rest/of/the/url > var url = o.ToString(); > // Do logic here to parse the url for intended results > }); > ``` > > **In Windows/Linux** > > ```cs > app.On("second-instance", o => { > var args = ((JToken)o).ToObject(typeof(List<string>)) as List<string>; > var url = args.FirstOrDefault(i => i.StartsWith("myappscheme://"); > if (string.IsNullOrWhitespace(url) == false) { > // Do logic here to parse the url for intended results > } > }); > ``` > > Likewise handling files is similar, you must first register the app as a handler for the file type and that is os dependent. > > **In Windows with NSIS** > > _**Nsis install script adddition**_ > > ```nsis > ; Register the extension with your app, look up RegisterExtension in NSIS documentation > ${RegisterExtension} "$INSTDIR\MyApplication.exe" ".ext" "NAME_FOR_EXTENSION" > ``` > > > Don't ask me how to integrate that off the shelf with electron-builder, I have a very customized nsis build script that using the unpacked outputs. > > **In Windows/Linux** > > _**csharp code**_ > > ```cs > app.On("second-instance", o => { > var args = ((JToken)o).ToObject(typeof(List<string>)) as List<string>; > var path = args > .SkipWhile(a => !a.Equals("--allow-file-access-from-files")) > .Skip(1).FirstOrDefault(); > if (string.IsNullOrWhiteSpace(path) == false) { > // do something with the path > } > }); > ``` > > > Notice this is the same event listener in windows/linux as the scheme (url) handler > > **In Mac** > > _**csharp**_ > > ```cs > app.On("open-file", async o => > { > var path = o.ToString(); > // Do something with the path > }); > ``` > > > Note that the file handlers described here also work as the handlers for any Recent Documents that are attached to the program in the OS > > Now I'm sure I've definitely missed something here in this long winded explanation as there are too many intricacies that I figured out, got set up and working and promptly forgot about but this should get you started. Thank you very much!
Author
Owner

@Atmosferrum commented on GitHub (Nov 1, 2022):

Implemented! Available in Electron.NET version 7.30.2.

You can start the app with:

electronize start /args --dog=woof --test=true

or

myapp.exe /args --dog=woof --test=true

With the Electron.NET API you can get the value:

if (await Electron.App.CommandLine.HasSwitchAsync("dog"))
{
   string value = await Electron.App.CommandLine.GetSwitchValueAsync("dog");
   await Electron.Dialog.ShowMessageBoxAsync(value);
}      

The " myapp.exe /args --dog=woof --test=true" desn't work for me. I'm getting:
A positional parameter cannot be found that accepts argument '--dog=woof'.
It doesn't matter even if I use my own arguments.

@Atmosferrum commented on GitHub (Nov 1, 2022): > Implemented! Available in Electron.NET version 7.30.2. > > **You can start the app with:** > > `electronize start /args --dog=woof --test=true` > > or > > `myapp.exe /args --dog=woof --test=true` > > **With the Electron.NET API you can get the value:** > > ``` > if (await Electron.App.CommandLine.HasSwitchAsync("dog")) > { > string value = await Electron.App.CommandLine.GetSwitchValueAsync("dog"); > await Electron.Dialog.ShowMessageBoxAsync(value); > } > ``` The " myapp.exe /args --dog=woof --test=true" desn't work for me. I'm getting: **_A positional parameter cannot be found that accepts argument '--dog=woof'._** It doesn't matter even if I use my own arguments.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/Electron.NET#407