c# - 是否可以定义在系统范围内使用的自定义 URI 方案?

标签 c# c++ windows com uri-scheme

很长一段时间以来,我一直在想是否有可能创建一个库来充当 Windows 中的文件提供程序。

例如,如果您尝试使用标准打开文件对话框打开 ftp://example.com/touch.txt 文件,它(不知何故神奇地)起作用了。有没有办法为我自己的 URI 方案实现我自己的提供程序?

Asynchronous Pluggable Protocol 可以作为解决方案吗?我无法找到有关如何使其工作的工作代码示例。

理解:我需要它在整个系统范围内工作。这没有连接到互联网浏览器。

如果我需要这个 File.Open("my://test.txt") 工作怎么办?

最佳答案

执行 File.ReadAllBytes("ftp://example.com/touch.txt"); 不起作用,如果你尝试它,你会得到一个异常

System.NotSupportedException was unhandled
  Message=The given path's format is not supported.
  Source=mscorlib
  StackTrace:
       at System.Security.Util.StringExpressionSet.CanonicalizePath(String path, Boolean needFullPath)
       at System.Security.Util.StringExpressionSet.CreateListFromExpressions(String[] str, Boolean needFullPath)
       at System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList)
       at System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, AccessControlActions control, String[] pathList, Boolean checkForDuplicates, Boolean needFullPath)
       at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
       at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
       at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
       at System.IO.File.ReadAllBytes(String path)
       at WindowsFormsApplication1.Form1.button1_Click(Object sender, EventArgs e) in D:\Code\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 25
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at WindowsFormsApplication1.Program.Main() in D:\Code\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:line 17
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

它在您执行 OpenFileDialog 时起作用的原因是 Windows 作弊并首先将文件下载到本地临时文件夹。它只对 ftp:http: 执行此操作,因为 OpenFileDialog 由 Windows shell 处理,而 shell 是使用 URI 方案的。

我相信 HKCR\ftp 下的 Source Filter 键指向一个已注册的 COM 对象,该对象处理执行该本地拷贝的逻辑。

如果您只是希望通过访问 URL 来打开您的应用程序,就像 steam 使用 steam://rungameid/382110 那样,您只需按照 this MSDN page 中的说明进行操作。 .

如果您希望您的文件可以通过像 http:ftp: 这样的 shell 来“打开”,那么您需要编写一个 COM 对象充当“源过滤器”,我不知道有什么地方可以找到相关文档。

更新:阅读更多它确实看起来像Asynchronous Pluggable Protocol就像你提到的那样,你是如何制作这些源过滤器的。我从未尝试过制作一个,所以除此之外我无能为力。

关于c# - 是否可以定义在系统范围内使用的自定义 URI 方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39133686/

相关文章:

c++ - 不能明确特化

windows - 来自 System.Net.WebClient 的 powershell 字符编码

windows - Powershell 脚本卡住,从批处理文件调用时不退出

c# - c#中的CRC-ITU计算

c# - 类型转换器因原始类型而损坏?

c# - 这对 sql 注入(inject)安全吗?

c++ - 为什么析构函数在 C++ 中运行两次?

c# - 选择静态选择列表的值

c++ - 尝试返回 std::string 时出现 std::logic_error

windows - 在 OS X 上运行时,如何提交具有 LF 行结尾的文件,但将某些文件类型保留在 CRLF 中?