Associate a file extension to an application within C# application
Seems that you haven't enough permissions for writing in the windows registry
Try to add to project app.manifest file with content:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</asmv1:assembly>
or if application have to work without requesting admin rights on each start add ability to self-elevate as shown in this example UAC self-elevation
Associate File Extension with Application
The answer was a lot simpler than I expected. Windows Explorer has its own override for the open with application, and I was trying to modify it in the last lines of code. If you just delete the Explorer override, then the file association will work.
I also told explorer that I had changed a file association by calling the unmanaged function SHChangeNotify()
using P/Invoke
public static void SetAssociation(string Extension, string KeyName, string OpenWith, string FileDescription)
{
// The stuff that was above here is basically the same
// Delete the key instead of trying to change it
var CurrentUser = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + Extension, true);
CurrentUser.DeleteSubKey("UserChoice", false);
CurrentUser.Close();
// Tell explorer the file association has been changed
SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);
}
[DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
Associate file types with my application C#
Found the answer:
For that I created a faulty file type and associated it to my program.
Then I searched the registry for changes and copied the pathes of those changes.
The code is here and I would like to here if anyone has a better answer.
`
public static void SetAssociation(string Extension, string KeyName, string OpenWith, string FileDescription)
{
RegistryKey OpenMethod;
RegistryKey FileExts;//HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.avi\UserChoice -->"Progid" "Applications\YEPlayer.exe"
OpenMethod = Registry.CurrentUser.OpenSubKey(@"Software\Classes\Applications\", true);
OpenMethod.CreateSubKey(KeyName + @".exe\shell\open\command").SetValue("",'"'+OpenWith+'"'+ " "+ '"'+"%1"+'"');
FileExts = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\", true);
foreach (string child in FileExts.OpenSubKey(Extension).GetSubKeyNames())
{
FileExts.OpenSubKey(Extension,true).DeleteSubKey(child);
}
FileExts.CreateSubKey(Extension + @"\UserChoice").SetValue("Progid", @"Applications\" + KeyName +".exe");
}
'
Thanks alot!
Associated extension doesn't send file name to application on double click
I actually solved my own problem with the following code:
RegistryKey command, defaultIcon, extension;
// Create Keys
command = Registry.CurrentUser.CreateSubKey(@"Software\Classes\APP NAME\shell\open\command");
defaultIcon = Registry.CurrentUser.CreateSubKey(@"Software\Classes\APP NAME\DefaultIcon");
extension = Registry.CurrentUser.CreateSubKey(@"Software\Classes\.EXTENSION");
// Create Values
command.SetValue("", "\"" + Application.ExecutablePath + "\" %1", RegistryValueKind.String);
defaultIcon.SetValue("", "ICON PATH", RegistryValueKind.String);
extension.SetValue("", "APP NAME", RegistryValueKind.String);
APP NAME is where I put the name of my application,
EXTENSION is where I put the extension I want to associate with my application, and ICON PATH is the path to the icon file which I want the associated files to have.
The %1 at the end of the ExecutablePath makes the path of the double-clicked associated file to be passed as an argument to Main method of my application.
Allow a custom file to double click and open my application while loading it's data
The answer to your question is no different for a WinForms app and a console app.
The path of the .mmi
file that triggered your app will be args[0]
in your app's Main
method (assuming the signature Main(string[] args)
).
So knowing what .mmi
file was double-clicked to trigger your app will essentially come for free - after you have told Windows to open .mmi
files with your app.
Here is an example - where I just used a text file Test.mmi
and a simple console app ConsoleApplication1
for a PoC:
/*
* Program.cs
*/
using System;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
if (args.Length > 0)
{
// Open and display the text in the double-clicked .mmi file.
Console.WriteLine(File.ReadAllText(args[0]));
}
// Pause for 5 seconds to see the double-clicked file's text.
Thread.Sleep(5000);
}
}
}
After telling Windows to open .mmi
files with ConsoleApplication1.exe
, ConsoleApplication1.exe
displays the text in Test.mmi
(Whatever....
) when I double-click it:
The only thing that will differ from the PoC I have offered is whatever you need do with the file path that comes in as args[0]
.
How to get recommended programs associated with file extension in C#
I wrote a small routine:
public IEnumerable<string> RecommendedPrograms(string ext)
{
List<string> progs = new List<string>();
string baseKey = @"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\." + ext;
using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(baseKey + @"\OpenWithList"))
{
if (rk != null)
{
string mruList = (string)rk.GetValue("MRUList");
if (mruList != null)
{
foreach (char c in mruList.ToString())
progs.Add(rk.GetValue(c.ToString()).ToString());
}
}
}
using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(baseKey + @"\OpenWithProgids"))
{
if (rk != null)
{
foreach (string item in rk.GetValueNames())
progs.Add(item);
}
//TO DO: Convert ProgID to ProgramName, etc.
}
return progs;
}
which gets called like so:
foreach (string prog in RecommendedPrograms("vb"))
{
MessageBox.Show(prog);
}
Open custom file with own application
When you open a file with an application, the path to that file is passed as the first command line argument.
In C#, this is args[0]
of your Main
method.
static void Main(string[] args)
{
if(args.Length == 1) //make sure an argument is passed
{
FileInfo file = new FileInfo(args[0]);
if(file.Exists) //make sure it's actually a file
{
//Do whatever
}
}
//...
}
WPF
In case your project is an WPF application, in your App.xaml
add a Startup
event handler:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
Startup="Application_Startup"> <!--this line added-->
<Application.Resources>
</Application.Resources>
</Application>
Your command line arguments will now be in e.Args
of the Application_Startup
event handler:
private void Application_Startup(object sender, StartupEventArgs e)
{
if(e.Args.Length == 1) //make sure an argument is passed
{
FileInfo file = new FileInfo(e.Args[0]);
if(file.Exists) //make sure it's actually a file
{
//Do whatever
}
}
}
c#: icon associated with file extension
you need to modify registry entries.
A code snippet how to do with c# can be found here:
http://mel-green.com/2009/04/c-set-file-type-association/
Related Topics
Easier Way to Debug a Windows Service
Get Output Parameter Value in Ado.Net
Why Can't the C# Constructor Infer Type
How to Enable C# 6.0 Feature in Visual Studio 2013
Difference Between Asynchronous Programming and Multithreading
What Is the Best Choice For .Net Inter-Process Communication
Data Binding to Selecteditem in a Wpf Treeview
Dpi Awareness - Unaware in One Release, System Aware in the Other
How to Convert a Structure to a Byte Array in C#
Convert Datatable to Json in C#
Execute Powershell Script from C# With Commandline Arguments
Get Enum from Description Attribute
How to Tell Whether a Point Is to the Right or Left Side of a Line
What Is App.Config in C#.Net - How to Use It
Why Does Adding a New Value to List≪≫ Overwrite Previous Values in the List≪≫