- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我试着在 SO 上看这个,但所有试图回答的问题都没有提供完整的答案。
我实际上想在现有文件的详细信息选项卡中添加一个属性。文件的扩展名为 sldprt。属性/值必须在 Windows 资源管理器中可见。
不确定如何使用 Windows API 代码包外壳或 DSOFile 完成此操作?任何其他解决方案也可以。
我在 Windows 10 上使用 VS、C#。
如果有人能提供详细的解决方案,我将不胜感激。
完美的解决方案是:
这个question的答案不向详细信息选项卡或 Windows 资源管理器详细 View 添加属性。
我认为这是可能的,因为 SOLIDWORKS(3d 包)向所有 SOLIDWORKS 文件添加了一个名为 sw last saved with 的属性。详细信息窗口中还有大量其他属性。
如果您没有正确的解决方案,请不要回答。非常感谢。
我不确定这个问题是否与 Add new metadata properties to a file 重复.
预览:
编辑:
sldprt 扩展的注册表(供引用):
最佳答案
属性窗口中的详细信息选项卡填充有 metadata property handlers .元数据属性系统是 Microsoft 在 Windows Vista 中引入的,它是开放和可扩展的,使独立开发人员(如 Solidworks)能够实现和支持他们自己的文件属性。非常粗略地说,执行流程是这样的:
User clicks file properties
Look up property handler for the file format
If found property handler:
Query property handler for properties
Populate file details with queried properties
Else:
Populate file details with generic file info
属性处理程序是 COM 对象。 COM (Component Object Model)是 Microsoft 对独立于语言的面向对象框架的尝试,其起源可以追溯到 90 年代,但出于此解释的目的,只需说 COM 对象是实现 IUnknown
的 C++ 类即可。界面。属性处理程序必须实现 IPropertyStore
上面的界面:
struct IPropertyStore : public IUnknown
{
public:
virtual HRESULT GetCount(
DWORD *cProps) = 0;
virtual HRESULT GetAt(
DWORD iProp,
PROPERTYKEY *pkey) = 0;
virtual HRESULT GetValue(
REFPROPERTYKEY key,
PROPVARIANT *pv) = 0;
virtual HRESULT SetValue(
REFPROPERTYKEY key,
REFPROPVARIANT propvar) = 0;
virtual HRESULT Commit( void) = 0;
};
此接口(interface)的便捷实现是 CLSID_InMemoryPropertyStore
提供给开发人员以简化他们自己的 IPropertyStore
实现。这里有趣的方法是 GetValue
和 SetValue
。为属性分配了一个唯一的 GUID,传递到这些函数中的 PROPERTYKEY
结构包含该 GUID 以标识该属性。 GetValue
和 SetValue
的实现细节留给开发人员,因此由开发人员决定如何以及在何处存储每个属性的值——这些值可以是存储在另一个文件、备用文件流或注册表中,仅举几个选项——但出于可移植性原因,建议将值存储在文件本身中。这样,如果文件被压缩并通过电子邮件发送,例如,属性会随之而来。
属性处理程序 COM 对象被编译成 DLL 并使用 regsvr32
向系统注册。这允许 Windows 知道去哪里寻找特定文件格式的属性。注册后,可以通过多种方式获取属性处理程序,其中之一是便捷函数 SHGetPropertyStoreFromParsingName
:
HRESULT GetPropertyStore(PCWSTR pszFilename, GETPROPERTYSTOREFLAGS gpsFlags, IPropertyStore** ppps)
{
WCHAR szExpanded[MAX_PATH];
HRESULT hr = ExpandEnvironmentStrings(pszFilename, szExpanded, ARRAYSIZE(szExpanded)) ? S_OK : HRESULT_FROM_WIN32(GetLastError());
if (SUCCEEDED(hr))
{
WCHAR szAbsPath[MAX_PATH];
hr = _wfullpath(szAbsPath, szExpanded, ARRAYSIZE(szAbsPath)) ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
hr = SHGetPropertyStoreFromParsingName(szAbsPath, NULL, gpsFlags, IID_PPV_ARGS(ppps));
}
}
return hr;
}
获取后,可以在 IPropertyStore
对象上调用 GetValue
和 SetValue
来获取、更改或设置属性的新值。如果使用 SetValue
,请确保调用 Commit
Microsoft 提供了一个名为 PropertyEdit
的实用程序, 获取和设置文件的元数据属性作为其 Windows 经典示例的一部分。很遗憾他们没有在帮助页面的任何地方提及它。由于您已经安装了 Solidworks,您感兴趣的文件格式的属性处理程序应该已经在系统上注册,这应该是编译 PropertyEdit
并使用它来获取和设置处理程序支持的元数据属性。这是一个简单的命令行实用程序。
如果您需要或想要为您自己的文件格式支持自定义元数据,还有一个完整的示例属性处理程序:RecipePropertyHandler
.
作为引用,通过规范名称设置属性:
HRESULT GetPropertyStore(PCWSTR pszFilename, GETPROPERTYSTOREFLAGS gpsFlags, IPropertyStore** ppps)
{
WCHAR szExpanded[MAX_PATH];
HRESULT hr = ExpandEnvironmentStrings(pszFilename, szExpanded, ARRAYSIZE(szExpanded)) ? S_OK : HRESULT_FROM_WIN32(GetLastError());
if (SUCCEEDED(hr))
{
WCHAR szAbsPath[MAX_PATH];
hr = _wfullpath(szAbsPath, szExpanded, ARRAYSIZE(szAbsPath)) ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
hr = SHGetPropertyStoreFromParsingName(szAbsPath, NULL, gpsFlags, IID_PPV_ARGS(ppps));
}
}
return hr;
}
HRESULT SetPropertyValue(PCWSTR pszFilename, PCWSTR pszCanonicalName, PCWSTR pszValue)
{
// Convert the Canonical name of the property to PROPERTYKEY
PROPERTYKEY key;
HRESULT hr = PSGetPropertyKeyFromName(pszCanonicalName, &key);
if (SUCCEEDED(hr))
{
IPropertyStore* pps = NULL;
// Call the helper to get the property store for the
// initialized item
hr = GetPropertyStore(pszFilename, GPS_READWRITE, &pps);
if (SUCCEEDED(hr))
{
PROPVARIANT propvarValue = {0};
hr = InitPropVariantFromString(pszValue, &propvarValue);
if (SUCCEEDED(hr))
{
hr = PSCoerceToCanonicalValue(key, &propvarValue);
if (SUCCEEDED(hr))
{
// Set the value to the property store of the item.
hr = pps->SetValue(key, propvarValue);
if (SUCCEEDED(hr))
{
// Commit does the actual writing back to the file stream.
hr = pps->Commit();
if (SUCCEEDED(hr))
{
wprintf(L"Property %s value %s written successfully \n", pszCanonicalName, pszValue);
}
else
{
wprintf(L"Error %x: Commit to the propertystore failed.\n", hr);
}
}
else
{
wprintf(L"Error %x: Set value to the propertystore failed.\n", hr);
}
}
PropVariantClear(&propvarValue);
}
pps->Release();
}
else
{
wprintf(L"Error %x: getting the propertystore for the item.\n", hr);
}
}
else
{
wprintf(L"Invalid property specified: %s\n", pszCanonicalName);
}
return hr;
}
关于c# - 在现有文件的详细信息选项卡中添加/编辑新的扩展属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50686095/
我有一个如下图所示的情节。对于这个情节,我想在情节(右下角或左下角)的某处添加类似的线图。我正在使用的子图的命令是 plot( 1:121, sample(1:121),type='l' ) 它绘制在
我有一个单表数据库,我继承并迁移到 SQL Server,然后通过创建、链接和填充一大堆表示主表中项目的查找类型表来规范化它。我现在想用它们的外键替换原始表中的那些项目。我是不是一直在写一堆查询或 U
我有一个 Web 应用程序,它当前正在从服务器获取 PDF 的 base64 表示。我可以使用 Mozilla 的 pdf.js 在 上显示它并使用下拉菜单切换页面。 根据我所能找到的一切和Can
在 DB2 上运行的 Moodle 2 安装中,删除用户不成功,返回从数据库读取错误: Debug info: [IBM][CLI Driver][DB2/LINUXX8664] SQL0206N "
我在grails项目的RH包中添加了一个名为Authorization的新域类。 然后,我从grails菜单自动生成了 Controller 和 View 。 但是当我尝试输入 Controller
今天,我发现了一个有趣的plunker,经过谷歌大量搜索后一无所获,希望我能在这里找到答案。我只是想要那个笨蛋的副本。我不想使用复制和粘贴技术。有什么方法可以获取已建立的 plunk 的副本吗?我如何
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: Migrate normal sqlite3 database to core data? 是否可以将现有的 sql
我正在尝试在我的应用程序上添加启动画面。我干净地构建了程序,但我选择了错误的文件。现在我第二次编辑了 VM 选项并再次干净构建,现在我收到此错误: C:\Users\User\Documents\Ne
我已经查看了很多问题,我不相信这是重复使用单元格的结果,因为新的单元格图像是正确的,但是现有的单元格图像不正确并且曾经是正确的。我会先发布图片,以便更容易理解问题。 我有一个图像单元的 Collect
我在来自 Vaadin 的 ContainerHierarchicalWrapper 的这段代码中有一个非常奇怪的错误: for (Object object : children.keySet())
到目前为止,我正在使用 Globalize用于我的 JavaScript 应用程序的 i18n 和 l10n(使用 jQuery UI 构建)。这行得通,但它将我的代码与另一个特定的库联系在一起。现在
我正在创建一个 JHipster 应用程序,现在确定了 full text search 的必要性.我知道 JHipster 与 Elasticseach 集成,但我在创建项目时没有启用它。有没有一种
我一直在寻找堆栈中的建议,但我仍然不能 100% 确定改进它的最佳方法。我有一个存储大约 130K 条记录的 mysql INNODB“产品”表。杂项产品数据等大约有 80 个字段,然后我们一直在为每
我在一本书上看到,它说:当我们使用另一个初始化新创建的对象时 - 使用复制构造函数创建一个临时对象,然后使用赋值运算符将值复制到新对象! 后来在书中我读到:当使用另一个对象初始化新对象时,编译器创建一
我第一次安装现有的 Django 项目时遇到了启动服务器 python manage.py runserver 的问题 这是我做的 1.克隆仓库, 2.制作虚拟环境 3.pip安装要求.txt 4.生
我有一个网站,还有一个登录表单。我不想使用 PHP 来检查我的 MySQL 数据库,因此我正在寻找一种方法来检查用户凭据以查看是否已有 Linux 用户。我知道 PAM,但我还没有找到任何有关如何从网
我有一个现有的 Umbraco 项目在 IIS 服务器上运行。当我开始这个项目时,我基本上是将 Umbraco 直接安装到服务器上,并通过管理界面进行编码,直到网站启动并上线。 现在,客户想要一些更改
我是 Android 开发新手,目前正在学习一些教程。当我在 Eclipse 中设置一个新的 Android 项目,并选择 Windows -> Android SDK and AVD Manager
我有这个注册页面可以正常工作,但对于电子邮件字段,我需要确保电子邮件正确有效1:正确2 : 有效 为了正确添加电子邮件,我正在使用 Java 脚本验证来维护abc@def.com 很好用 但我的问题是
首先让我说我不熟悉 COM 引用,并且我在 Windows 7 64 位计算机上使用 VS2010。今天早上,我从 TFS 中删除了一个现有项目。然后我尝试构建项目并收到此错误: The type o
我是一名优秀的程序员,十分优秀!