관리 속성 핸들러 셸 확장을 구현하는 올바른 방법은 무엇입니까?
-
12-09-2020 - |
문제
이제 .NET CLR 4.0이 SXS (Side yout) 작동을 지원하므로 이제 셸을 작성할 수 있습니다. 관리 코드의 확장. 나는 이것을 시도했고, 속성 처리기를 성공적으로 코딩했다. 이는 IPropertyStore, IInitializeWithStream 및 iPropertyStoreCapabilities를 구현합니다.
핸들러 잘 작동하며 탐색기를 통해 파일을 탐색 할 때 예상대로 호출됩니다. 또한 그를 표시 할 때 잘 작동합니다 미리보기 패널 및 파일 속성 "Detail"패널의 사용자 지정 속성.
그러나, 내가 시도 할 때 미리보기 패널에서 속성을 편집 한 다음 "저장"을 클릭하십시오. "사용중인 파일"오류가 발생합니다. 파일이 Windows 탐색기에서 열려 있습니다.
몇 가지 tidbits :
- 탐색기가 iInitializeWithStream.Initialize를 호출 할 때 STGM 속성은 stgm_share_deny_write로 설정됩니다.
- 및 No Point Ded explorer가 iPropertyStore.setValue 또는 iPropertyStore.commit을 호출합니다.
- 동일한 파일 속성에 대해 다른 스레드에서 핸들러에 대한 호출이 반복됩니다.
그래서 나는 재산 저장을 위해 재산을 변경하기 위해 변경 (또는 레지스터에 설정)을 변경해야합니까?
업데이트 :
벤 덕분에 나는 그것을 일하고 있습니다. "어려운 부분"(적어도 나를 위해)은 COM interop이 내 PropertyHandler에서 폐기 또는 완료하지 않을 것이라는 것을 이해하는 것이 었습니다. 이것은 GC가 실행될 때까지 내가 처리 한 파일을 열었습니다.
다행히도 "속성 핸들러 프로토콜"은 iInitializeWithsReam.Initialize ()가 ReadValue ()에 대해 호출되면 StreamMode가 읽기 쉽고 SetValue ()에 대해 호출 될 때 streammode가 readwrite 및 커밋 ()에 대해 호출 될 때입니다. 끝에서 호출됩니다.
int IInitializeWithStream.Initialize( IStream stream, uint grfMode )
{
_stream = stream;
_streamMode = (Stgm)grfMode;
Load();
// We release here cause if this is a read operation we won't get called back,
// and our finializer isn't called.
if ( ( _streamMode & Stgm.ReadWrite ) != Stgm.ReadWrite )
{
Marshal.ReleaseComObject( _stream );
_stream = null;
}
return HResult.S_OK;
}
int IPropertyStore.Commit()
{
bool result = false;
if ( _stream != null )
{
result = WriteStream( _stream );
Marshal.ReleaseComObject( _stream );
_stream = null;
}
return result ? HResult.S_OK : HResult.E_FAIL;
}
.해결책
예, 열기를 유지하고 참조를 올바르게 유지하려면 스트림을 addref ()해야합니다.
인덱서는 속성 핸들러를 사용하여 파일을 엽니 다.따라서 스트림 개체가 누출되면 파일이 열려 있습니다.SysInternals Procexp를 사용하여 파일이 열려있는 프로세스를 알리거나 사용 된 호출 및 매개 변수를 알리기 위해 Procmon을 알 수 있습니다.
다른 팁
탐색기는 파일이 열려있을 수있는 다른 응용 프로그램을 방해하지 않도록합니다.다른 응용 프로그램에서 파일을 정당하게 사용할 수 있습니까?미리보기 처리기가 열려 있습니까?
때로는 스트림을 필요한 것보다 긴 오랜 시간 이상 열어 두는 속성 핸들러가 있거나 제한적 권한으로 파일을 열 수있는 파일 기반 핸들러를 봅니다.스트림을 적시에 릴리스하는지 확인할 수 있습니까?
마지막으로, 이것은 당신의 즉각적인 문제와 관련이 있지만 .NET 쉘 확장을 사용하는 것은 지원되지 않습니다.이것은 모든 제품에 통합되지 않는 것이 좋습니다.
-ben