"打开..."在资源管理器中无法启动我的应用程序

时间:2016-02-26 18:15:26

标签: c# .net winforms visual-studio

我正在编写一个Windows窗体应用程序,用于读取和写入我自己的文件类型。该程序使用Visual Studio 2015,.NET 4.6。

当我将程序与文件类型关联时,我遇到了一个问题,右键单击文件,单击打开方式,最后我选中了选项以始终使用此程序打开文件扩展名。问题是,当我尝试通过双击文件来启动程序时,没有任何反应。该程序没有显示在屏幕上。

我打开了任务管理器,看它是否启动,我发现它实际上确实启动了一会儿,但在后台运行,然后关闭。

起初我认为这是我的项目的一个问题,所以我创建了一个新的Windows窗体项目,不改变单个项目设置,并将文件类型与之关联,但我仍然遇到同样的问题。我也尝试在不同的计算机上使用相同的应用程序,我遇到了同样的问题。

请注意,我实际上可以正常打开程序,即双击Windows资源管理器中的.exe,然后通过Visual Studio运行它。

这就是我在我创建的测试项目中的Program.cs和Form1.cs中所拥有的内容,它也无法通过关联启动:

Program.cs的

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(args.Length == 0 ? new Form1(string.Empty) : new Form1(args[0]));
    }
}

Form1.cs的

public partial class Form1 : Form
{
    public Form1(string path)
    {
        InitializeComponent();

        // Nothing here gets called.            

        if (path != string.Empty)
        {
            MessageBox.Show("File path found!");
        }
        else
        {
            MessageBox.Show("No file path found.");
        }
    }
}

这对我来说是新的,因为我之前已经将文件类型与我的程序相关联,并且没有任何问题。然而,它是早期版本的Visual Studio,所以我不确定它是否与它有关。

现在让我困惑了几天,所以我来这里寻求帮助,希望能帮助那些有同样问题的人。

我在Windows 7 x64和Windows 10 x86上都尝试过它。

我对此有任何想法。

1 个答案:

答案 0 :(得分:0)

应用程序与文件扩展名的关联(与Windows 10兼容):

String App_Exe = "MyApp.exe";
String App_Path = "%localappdata%";
SetAssociation_User("myExt", App_Path + App_Exe, App_Exe);

public static void SetAssociation_User(string Extension, string OpenWith, string ExecutableName){
    try {
        using (RegistryKey User_Classes = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Classes\\", true))
        using (RegistryKey User_Ext = User_Classes.CreateSubKey("." + Extension))
        using (RegistryKey User_AutoFile = User_Classes.CreateSubKey(Extension + "_auto_file"))
        using (RegistryKey User_AutoFile_Command = User_AutoFile.CreateSubKey("shell").CreateSubKey("open").CreateSubKey("command"))
        using (RegistryKey ApplicationAssociationToasts = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\ApplicationAssociationToasts\\", true))
        using (RegistryKey User_Classes_Applications = User_Classes.CreateSubKey("Applications"))
        using (RegistryKey User_Classes_Applications_Exe = User_Classes_Applications.CreateSubKey(ExecutableName))
        using (RegistryKey User_Application_Command = User_Classes_Applications_Exe.CreateSubKey("shell").CreateSubKey("open").CreateSubKey("command"))
        using (RegistryKey User_Explorer = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\." + Extension))
        using (RegistryKey User_Choice = User_Explorer.OpenSubKey("UserChoice")){
              User_Ext.SetValue("", Extension + "_auto_file", RegistryValueKind.String);
              User_Classes.SetValue("", Extension + "_auto_file", RegistryValueKind.String);
              User_Classes.CreateSubKey(Extension + "_auto_file");
              User_AutoFile_Command.SetValue("", "\"" + OpenWith + "\"" + " \"%1\"");
              ApplicationAssociationToasts.SetValue(Extension + "_auto_file_." + Extension, 0);
              ApplicationAssociationToasts.SetValue(@"Applications\" + ExecutableName + "_." + Extension, 0);
              User_Application_Command.SetValue("", "\"" + OpenWith + "\"" + " \"%1\"");
              User_Explorer.CreateSubKey("OpenWithList").SetValue("a", ExecutableName);
              User_Explorer.CreateSubKey("OpenWithProgids").SetValue(Extension + "_auto_file", "0");

              if (User_Choice != null) User_Explorer.DeleteSubKey("UserChoice");
                  User_Explorer.CreateSubKey("UserChoice").SetValue("ProgId", @"Applications\" + ExecutableName);
              }

              SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);
        }
        catch (Exception e)
        {
            //Your code here
        }
  }

  [DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);

您的代码呢,通常它必须按原样工作,但是通过以下方式更新代码会更好:

static class Program
{
    [STAThread]
    static void Main(string[] args)
    {

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        // The first element in the array contains the file name of the executing program. 
        // If the file name is not available, the first element is equal to String.Empty. 
        // The remaining elements contain any additional tokens entered on the command line. 
        var args = Environment.GetCommandLineArgs()[0];
        var path = (args.Count == 1) ? args[0] : args[1];

        if (path == string.Empty)
        {
            MessageBox.Show("No file path found.");
        }
        else
        {
            MessageBox.Show("File path found!");
        }
    }
}

因为我现在无法访问VS,所以没有尝试代码。因此可能会有一些代码错误。