标签: windows-shell

如何在Windows shell中为文件类型添加辅助动词?

Windows shell编程的基本思想是,您可以将给定的文件类型(扩展名)与MS当前调用的编译器(例如,Company.Type.Ver)相关联:

HKCR\.txt @ = Acme.Text.1

HKCR\Acme.Text.1 @ =这是Acme文本文件关联的progid

然后Acme Corp可以将尽可能多的shell动词作为HKCR\Acme.Text.1\shell的子键,例如HKCR\Acme.Text.1\shell\open.

但如果我是XyzCorp,如何在文本文件中添加辅助动词?

我不想篡夺主文件关联 - 我很高兴它与Acme.Text.1相关联,但我想添加"导入到Xyz编辑器".

我可以:
1.向Acme的progid添加一个动词(例如HKCR\Acme.Text.1\shell\my-verb)
2.代表我们创建一个新的progid并将Acme的数据复制到那个,并将XyzCorp的动词合并到
3.将动词直接添加到文件扩展名(至少有一个曾经能够这样做)
4.???

有谁知道这个"正确"的答案?

编辑:我真的不喜欢任何涉及修改别人的PROGID的解决方案.我真的更愿意在相关的PROGID之外添加一些东西 - 一个IContextMenu或其他任何东西,以便为给定的文件类型添加额外的动词/选项.

似乎这样一个疯狂的系统有ext-> progid,其中progid由个别开发公司拥有,并且可以随意删除或更改.这让我觉得很脆弱(卸载东西和poof,你的文件扩展名停止正常工作,或安装一些东西,同样你的辅助动词消失,因为ext现在映射到一个不同的专有PROGID,我没有添加我们的动词安装(当时,不知道任何关于这个其他尚未存在的程序)),而且只是愚蠢.在所有这些时间之后,所有这些版本的Windows和Microsoft从未找到过为给定文件类型提供多层处理程序的方法?真?!?

我发现那令人惊叹!初级编程101涉及学习命令模式或其他分层/级联系统.Windows WinProcs本身是以命令模式模式组织的 - 因此从内部窗口上下文到外部,许多可能的处理程序在给定的MSG中被给予破解.

当然有一种方法可以添加一个适用于多个扩展的动词,而不会覆盖扩展的主要progid关联,它本身完全独立于主扩展 - > progid映射(这样用户可以随着时间的推移安装多个程序,并且仍然有权访问该文件类型的辅助动词).

我想我可以看看HKCR.*...我理解可以在那里添加适用于所有文件类型的动词.但是,我需要找到一些方法来过滤,这样我们的动词才真正存在于我们应该应用的实际文件类型中......

windows registry windows-shell

9
推荐指数
2
解决办法
1892
查看次数

如何使嵌入式Explorer IShellView可浏览(即触发BrowseObject事件)

我在我的Win32应用程序中"嵌入Windows资源管理器".(从技术上讲,我在我的应用程序中托管了一个文件夹的ShellView,这是Windows资源管理器所做的).

问题是视图永远不会调用IShellBrowser.BrowseObject.shell视图不是要求导航到新位置(通过BrowseObject事件),而是启动Windows资源管理器的副本以查看该文件夹.

我希望默认的shell视图(通俗地称为DefView)是可浏览的.


示例代码教程

首先,我们需要获取IShellFolder我想要显示的文件夹.要获取的最简单的文件夹是Desktop文件夹,因为SHGetDesktopFolder API它有一个for:

folder: IShellFolder;

SHGetDesktopFolder({out} folder);
Run Code Online (Sandbox Code Playgroud)

接下来我们要求桌面文件夹将其IShellView 交给我们:

view: IShellView;

folder.CreateViewObject(Self.Handle, IID_IShellView, {out}view);
Run Code Online (Sandbox Code Playgroud)

现在我们有文件夹的IShellView(而不是IContextMenuIExtractIcon),我们现在想通过调用IShellView.CreateViewWindow来显示shell视图:

hostRect: TRect; //where the view is to display itself
folderSettings: TFolderSettings; //display settings for the view
hwndView: HWND; //the newly created view's window handle

folderSettings.ViewMode := FVM_DETAILS; //details mode please, rather than icon/list/etc
folderSettings.fFlags := 0;
hostRect := Rect(20, 20, 660, 500); //the view …
Run Code Online (Sandbox Code Playgroud)

windows winapi windows-explorer windows-shell

9
推荐指数
1
解决办法
3643
查看次数

如何在打开一个进程(记事本)后将焦点设置回形式?

我用我的程序打开了一个记事本,Process.Start()但新打开的记事本覆盖了屏幕.但我确实希望我的应用程序保持其重点.

我同样(使用相同的Process.Start)打开MS Excel和Word,但要将焦点重新放回我的表单,我需要编写的是:

this.Focus();
Run Code Online (Sandbox Code Playgroud)

但是用记事本怪起来:我打开记事本(以及所有其他这样的过程)

Process process = new Process();
process.StartInfo.UseShellExecute = true;
process.EnableRaisingEvents = true;
process.StartInfo.FileName = @"abc.log";
process.Start();
Run Code Online (Sandbox Code Playgroud)

现在记事本成为焦点.

我试过这些:

  1. this.Activate(),this.Focus()不用提

  2. [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]  
    public static extern IntPtr SetFocus(HandleRef hWnd);
    
    {
       IntPtr hWnd = myProcess.Handle;
       SetFocus(new HandleRef(null, hWnd));
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. [DllImport("User32")]
    private static extern int SetForegroundWindow(IntPtr hwnd);
    
    [DllImportAttribute("User32.DLL")]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    private const int SW_SHOW = 5;
    private const int SW_MINIMIZE = 6;
    private const int SW_RESTORE = 9; …
    Run Code Online (Sandbox Code Playgroud)

c# focus process windows-shell winforms

9
推荐指数
1
解决办法
3万
查看次数

如何从文件快捷方式获取路径名?获得例外

可能重复:
获取快捷方式文件夹的目标

例如,在C:\TEMP\我有一个名为test.dll快捷方式的快捷方式将导致文件名test.dll

我想从快捷方式只获取路径名到它自己的文件.所以,我在另一个递归函数中调用此函数,并在每次从我的硬盘中的另一个目录中放入此函数.

例如,第一个目录C:\TEMP就在C:\TEMP那里有快捷方式文件,我只想获取文件的路径.在C:\TEMP测试中,我现在有3个文件:

hpwins23.dat
hpwmdl23.dat
hpwmdl23.dat - Shortcut(C:\TEMP\hpwmdl23.dat)

所以,我想得到的是快捷方式的路径名,本例中是C:\ TEMP

我试着使用这个功能:

public string GetShortcutTargetFile(string shortcutFilename)
        {
            string pathOnly = System.IO.Path.GetDirectoryName(shortcutFilename);
            string filenameOnly = System.IO.Path.GetFileName(shortcutFilename);
            Shell shell = new Shell();
            Folder folder = shell.NameSpace(pathOnly);
            if (folder == null)
            {
            }
            else
            {
                FolderItem folderItem = folder.ParseName(filenameOnly);
                if (folderItem != null)
                {
                    Shell32.ShellLinkObject link = (Shell32.ShellLinkObject)folderItem.GetLink;
                    return link.Path;
                }
            }
            return string.Empty;
        }
Run Code Online (Sandbox Code Playgroud)

但是当我使用该函数并且它到达一个快捷方式时,我遇到异常错误:

Shell32.ShellLinkObject link …
Run Code Online (Sandbox Code Playgroud)

c# windows-shell

9
推荐指数
1
解决办法
2万
查看次数

如何从C#中获取Windows资源管理器的选定文件?

我需要获取在Windows资源管理器中选择的当前文件集合.我从这里找到了以下代码.

不过,我不在那里.首先,它GetForegroundWindow来自哪里?另一方面,编译器在线上抱怨

var shell = new Shell32.Shell();
Run Code Online (Sandbox Code Playgroud)

"无法找到类型或命名空间名称'Shell32'(您是否缺少using指令或程序集引用?)".我已经添加了SHDocVw作为参考,但我仍然无法通过编译器.有人可以帮我完成这个吗?

    IntPtr handle = GetForegroundWindow();

    ArrayList selected = new ArrayList();
    var shell = new Shell32.Shell();
    foreach(SHDocVw.InternetExplorer window in shell.Windows()) {
        if (window.HWND == (int)handle)
        {
            Shell32.FolderItems items = ((Shell32.IShellFolderViewDual2)window.Document).SelectedItems();
            foreach(Shell32.FolderItem item in items)
            {
                selected.Add(item.Path);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

c# windows-shell

9
推荐指数
1
解决办法
5746
查看次数

有没有办法检测显示器是否已插入?

我有一个用C++编写的自定义应用程序,它控制连接到嵌入式系统的监视器上的分辨率和其他设置.有时系统无头启动并通过VNC运行,但可以在以后插入监视器(启动后).如果发生这种情况,则在启用监视器之前,监视器不会输入视频.我发现调用"displayswitch/clone"会启动监视器,但我需要知道监视器何时连接.我有一个每5秒运行一次的计时器并查找显示器,但是我需要一些API调用来告诉我显示器是否已连接.

这里有一些psudocode来描述我所追求的(当计时器每5秒到期时执行什么).

if(If monitor connected) 
{
   ShellExecute("displayswitch.exe /clone);
}else
{
   //Do Nothing
}
Run Code Online (Sandbox Code Playgroud)

我试图GetSystemMetrics(SM_CMONITORS)返回监视器的数量,但如果监视器已连接,则返回1.还有其他想法吗?

谢谢!

c++ windows winapi shellexecute windows-shell

9
推荐指数
1
解决办法
1794
查看次数

在Windows资源管理器中打开文件夹,然后选择仅第二次运行的文件

使用SO帖子"打开文件夹并选择文件"的答案中描述的代码,我创建了这个函数:

public static void OpenExplorerAndSelectFile(string filePath)
{
    Process.Start(
        @"explorer.exe",
        string.Format(@"/select, ""{0}""", filePath));
}
Run Code Online (Sandbox Code Playgroud)

这个功能运行良好,有一个小问题:

首次为特定文件调用该函数时,Windows资源管理器会正确显示该文件的文件夹,但不会选择该文件.

再次为同一个文件调用相同的函数,它会切换回Windows资源管理器中已打开的文件夹,然后选择该文件.

例如,第一次调用OpenExplorerAndSelectFile("C:\MyFolder\MyFile.txt")在新的Windows资源管理器窗口中打开文件夹"C:\ MyFolder".第二次调用OpenExplorerAndSelectFile("C:\MyFolder\MyFile.txt")实际上再次激活该窗口并选择MyFile.txt.

在谷歌浏览器中做类似的事情(转到下载页面并显示以前下载的文件)实际上在第一次尝试时效果很好.

所以我的结论是谷歌Chrome似乎与我有点不同.

我的问题:

有没有办法调试/跟踪谷歌Chrome调用的Win32/Shell方法?

然后我会将它们与我所做的比较以查看差异.

.net c# explorer windows-explorer windows-shell

9
推荐指数
1
解决办法
2576
查看次数

如何"安全地"将文件夹删除到回收站中

我正在寻找一种方法将文件夹(包含子文件夹)放入具有以下条件的回收站:

  1. 它必须以静默方式完成 - 没有任何 Windows UI.

  2. 永远不能永久删除该文件夹.如果无法将其放入回收站,我希望API失败.

  3. CopyFileEx那样获取进程的回调例程.

到目前为止,我能够想出这个:

SHFILEOPSTRUCT sfo = {0};
sfo.wFunc = FO_DELETE;
sfo.pFrom = L"K:\\test del from USB\0";     //Folder on a USB stick
sfo.fFlags = FOF_ALLOWUNDO |
     FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR |
     FOF_WANTNUKEWARNING;

int res = SHFileOperation(&sfo);
BOOL bFullSuccess = res == 0 && !sfo.fAnyOperationsAborted;
Run Code Online (Sandbox Code Playgroud)

哪个位于USB闪存驱动器上的文件夹可怕失败,即尽管有标志,它仍被永久删除FOF_ALLOWUNDO.

所以我是不是做对了,或者SHFileOperation API是非常错误的!

知道如何做我上面概述的内容吗?

编辑:我实现了IRecycleBinManager::WillRecycle@Denis Anisimov建议的方法,但显然更多.这是我的C++版本.我需要的方法的第一个接口定义:

#if defined(__cplusplus) && !defined(CINTERFACE)

    MIDL_INTERFACE("5869092D-8AF9-4A6C-AE84-1F03BE2246CC")
    IRecycleBinManager : public IUnknown
    {
    public: …
Run Code Online (Sandbox Code Playgroud)

c++ windows winapi recycle-bin windows-shell

9
推荐指数
1
解决办法
2226
查看次数

在C#应用程序中使用第三方上下文菜单(对于Windows资源管理器)?

与其他希望将项目添加到Windows资源管理器的人不同,我想在我的应用程序中显示上下文菜单.现在你可能在想,你正在寻找的课程是ContextMenu.让我告诉你我有兴趣做什么.请原谅小图片......

这是我目前拥有的:

我当前的上下文菜单

这就是我希望它:

我希望它看起来像什么

让我们把假设排除在外.我已经检测到用户安装了TortoiseSVN并且他们选择的项目受源代码管理.

我到目前为止的研究:

检索上下文菜单 - 这非常有用.这是Windows资源管理器的ac#库(可以检索特定文件夹/文件的上下文菜单).但是,即使在测试示例时,它也不会检索TortoiseSVN选项.

另一个上下文菜单检索 - 几乎与前一个链接相同(再次使用C#代码).获取Windows资源管理器上下文菜单减去TortoiseSVN选项.

添加上下文菜单的过程 - 我刚刚开始阅读这些深入的帖子.答案可能在本文中,但我需要一些时间来完成它.如果我有这些运气,我会回复一个答案.

用户似乎能够完成此任务 - 这似乎是一个处理SVN开发的电子邮件组.为什么要在这里发布?也许是为了证明这可以做到.引用:"我正在使用TSVN shell上下文菜单.我正在使用IContextMenu.QueryContextMenu(C++代码)方法访问TSVN shell上下文菜单,然后我将通过返回的菜单进行浏览."

总而言之,这似乎应该是一个相当直接的事情,我只是错过了一步.欢迎任何和所有建议.谢谢!

编辑:尝试更好地利用标签和更集中的标题

c# c++ tortoisesvn contextmenu windows-shell

8
推荐指数
1
解决办法
537
查看次数

Microsoft如何为即将推出的OneDrive On-Demand功能实施外壳扩展?

在即将推出的(当前内部版本)OneDrive客户端 - 按需功能中,Microsoft引入了一些新的shell /命名空间扩展.

还有一列显示文件可用性状态,以及状态栏中的文本.

Microsoft是否为OneDrive同步文件夹或其他一些shell界面开发了特殊的IShellView实现?他们是如何联系到文件选择更改事件的呢?

我知道自从以前的一些Windows版本以来,对列处理程序扩展的支持已被删除.

请指出一些有关开发此类功能的有用资源:自定义列和状态栏扩展(最好使用C#..).

windows-shell shell-extensions shell-namespace-extension

8
推荐指数
0
解决办法
386
查看次数