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

时间:2016-08-24 22:00:57

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

我一直想知道是否有可能创建一个在Windows中充当文件提供程序的库。

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

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

要理解:我需要这个在全系统工作。现在已连接到互联网浏览器。

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

1 个答案:

答案 0 :(得分:0)

执行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方案的。

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

如果您只是希望通过转到像它一样的steam://rungameid/382110之类的网址来打开您的应用,则只需按照this MSDN page中的说明进行操作。

如果您希望自己的文件可以打开"通过像http:ftp:这样的shell对打开的文件对话框,您需要编写一个COM对象作为"源过滤器",我不知道任何地方找到相关的文件。

更新:阅读更多内容看起来像您提到的Asynchronous Pluggable Protocol是如何制作这些源过滤器的。我从来没有试过制作一个,所以除了那个我无法帮助你。