Ame*_*ILI 4 c# attributes windows-api-code-pack dsofile
我尝试在SO上查看,但所有试图回答的问题都没有提供完整的答案.
我实际上想要在现有文件的详细信息选项卡中添加属性.文件是sldprt扩展名.必须在Windows资源管理器中显示属性/值.
不确定如何使用Windows API Code Pack Shell或DSOFile完成此操作?任何其他解决方案也很好.
我在Windows 10上使用VS,C#.
如果有人能提供详细的解决方案,我会非常感激.
完美的解决方案是:
如此这样的回答问题不属性的细节选项卡,也没有Windows资源管理器的详细视图中添加.
我认为这是可能的,因为SOLIDWORKS(3d包)将所有名为sw的属性添加到所有SOLIDWORKS文件中.详细信息窗口中有很多其他属性.
如果您没有正确的解决方案,请不要回答.非常感谢你.
我不确定这个问题与向文件添加新元数据属性有关.
预览:
编辑:
关于sldprt扩展的注册(供参考):
属性窗口中的详细信息选项卡填充了元数据属性处理程序.元数据属性系统是Microsoft在Windows Vista中引入的,它是开放和可扩展的,使独立开发人员(如Solidworks)能够实现和支持他们自己的文件属性.非常粗略地说,执行流程是这样的:
Run Code Online (Sandbox Code Playgroud)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(组件对象模型)是Microsoft尝试的一种独立于语言的面向对象框架,其起源一直追溯到九十年代,但出于这种解释的目的,可以说COM对象是一个C++类,它实现了IUnknown接口.属性处理程序必须在其上实现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;
};
Run Code Online (Sandbox Code Playgroud)
CLSID_InMemoryPropertyStore为开发人员提供了一个方便的实现,以简化他们自己的实现IPropertyStore.这里有趣的方法是GetValue和SetValue.为属性分配一个唯一的GUID,PROPERTYKEY传递给这些函数的结构包含用于标识属性.实现详细信息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;
}
Run Code Online (Sandbox Code Playgroud)
一旦获得,GetValue并SetValue可以在上调用IPropertyStore对象或者获取,对于属性改变或设置新值.如果使用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;
}
Run Code Online (Sandbox Code Playgroud)