使我的应用程序成为打开所有.txt文件的默认应用程序
本文关键字:应用程序 txt 文件 默认 我的 | 更新日期: 2023-09-27 18:22:09
发布我的应用程序后,我可以将我的app.exe文件指定为打开.txt文件的默认文件。在这里,我如何获得调用应用程序的文件的filePath?
public MainWindow()
{
InitializeComponent();
string filePath = "";
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
txt.Text = sr.ReadToEnd();
sr.Close();
fs.Close();
}
在这里,当用户双击资源管理器中的某个txt文件时,我如何获得filePath。。?
在.NET中有两种方法可以获取命令行参数。您可以在Main
方法上放置参数列表,也可以使用Environment.GetCommandLineArgs
方法。
var allArgs = Environment.GetCommandLineArgs();
// The first element is the path to the EXE. Skip over it to get the actual arguments.
var userSpecifiedArguments = allArgs.Skip(1);
由于您使用的是WPF(因此不控制Main
方法),因此最好使用GetCommandLineArgs
。
文件参数通过命令行参数传递。因此,您需要签入Program.cs
文件(可能)来查看string[] args
参数。
void Main(string[] args)
{
string filename;
if(args != null && args.Length > 0)
filename = args[0];
else
filename = null;
// use filename as appropriate, perhaps via passing it to your entry Form.
}
本质上,当Notepad是默认的文本编辑器时,双击test.txt
时,explorer.exe
(Windows资源管理器、桌面、开始菜单,等等)所做的调用看起来像这样:
notepad.exe C:'users'name'desktop'test.txt
它的语法与您在命令行中调用robocopy
的语法相同(尽管您可能需要更多的参数):
robocopy source.txt destination.txt
由于此工作流,您还可以覆盖默认的文件关联行为,以便启动您选择的读取文件的程序,类似于编程Open With...
。以下内容将始终打开记事本,而不管其他任何应用程序可能与.jpg
扩展程序(可能不是记事本)关联。
notepad.exe C:'users'name'desktop'test.jpg
有几种方法可以使您的应用程序成为特定文件类型的默认应用程序。
- 您可以手动更改注册表值,并为.txt扩展名提供应用程序路径HKEY_CURRENT_USER''Software''Classes
- 在设置项目中分配属性:项目属性->发布->选项->文件关联->[添加扩展名]
- 您可以编写一些代码来更改注册表,并将默认应用程序与特定扩展关联起来
[DllImport("Kernel32.dll")]
private static extern uint GetShortPathName(string lpszLongPath,
[Out] StringBuilder lpszShortPath, uint cchBuffer);
// Return short path format of a file name
private static string ToShortPathName(string longName)
{
StringBuilder s = new StringBuilder(1000);
uint iSize = (uint)s.Capacity;
uint iRet = GetShortPathName(longName, s, iSize);
return s.ToString();
}
// Associate file extension with progID, description, icon and application
public static void Associate(string extension,
string progID, string description, string icon, string application)
{
Registry.ClassesRoot.CreateSubKey(extension).SetValue("", progID);
if (progID != null && progID.Length > 0)
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(progID))
{
if (description != null)
key.SetValue("", description);
if (icon != null)
key.CreateSubKey("DefaultIcon").SetValue("", ToShortPathName(icon));
if (application != null)
key.CreateSubKey(@"Shell'Open'Command").SetValue("",
ToShortPathName(application) + " '"%1'"");
}
}
// Return true if extension already associated in registry
public static bool IsAssociated(string extension)
{
return (Registry.ClassesRoot.OpenSubKey(extension, false) != null);
}
///How to Associate
///.ext: give the extension here ie. .txt
///ClassID.ProgID: Give the unique id for your application. ie. MyFirstApplication1001
///ext File:Description of your application
///YourIcon.ico:Icon file
///YourApplication.exe:Your application name
Associate(".ext", "ClassID.ProgID", "ext File", "YourIcon.ico", "YourApplication.exe");
您也可以阅读本文并从这里下载相同的示例
在Matthew Haugen的帮助下,我完成了这项工作,并为Forms Application 工作
程序.cs
static class Program
{
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1(args != null && args.Length > 0 ? args[0] : ""));
}
}
和形式
public partial class Form1 : Form
{
public Form1(string fileName)
{
InitializeComponent();
if (fileName != "")
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
using (var sr = new StreamReader(fs)) textBox1.Text = sr.ReadToEnd();
}
}
我假设这可能对Forms Application有所帮助。但我仍在为在WPF中做同样的事情寻找答案。。
以下是WPF的解决方案
Matthew向我展示了如何在windows窗体应用程序中做到这一点,我进行了一些研究,找到了wpf的解决方案。
这是我一步一步做的。。
首先,我在App.Xaml.cs中添加了一个void Main函数
public partial class App : Application
{
[STAThread]
public static void Main()
{
}
}
在编译时,它显示了一个错误"为应用程序指定多个入口点"。双击时,它导航到存在实际入口点的App.g.cs文件。。
public partial class App : System.Windows.Application {
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public void InitializeComponent() {
#line 4 "..'..'App.xaml"
this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);
#line default
#line hidden
}
/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public static void Main() {
FileOpen.App app = new FileOpen.App();
app.InitializeComponent();
app.Run();
}
}
现在我删除了这里的所有行,并将入口点复制到App.xaml.cs还从App.xaml 中删除了startupURI
<Application x:Class="FileOpen.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Application.Resources>
</Application.Resources>
现在是App.g.cs
public partial class App : System.Windows.Application {
/// <summary>
/// Application Entry Point.
}
和App.xaml.cs
public partial class App : Application
{
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public static void Main(string[] args)
{
MainWindow window = new MainWindow(args != null && args.Length > 0 ? args[0] : "");
window.ShowDialog();
}
}
和主窗口
public partial class MainWindow : Window
{
public MainWindow(string filePath)
{
InitializeComponent();
if (filePath != "")
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (var sr = new StreamReader(fs)) txt.Text = sr.ReadToEnd();
}
}