ホーム » 検索結果: Shell
検索結果: Shell
Shell Extension のデバッグ
ここ 1ヶ月位,共通のコードを分割したり,古いままの部分を改良したりしていた.
ある程度区切りがついたので,ツール関係のプロジェクトからビルドして exe はできる様になった.
それぞれの動作チェックはこれから.
昨日新しいコードでビルドしたものに,「シェルエクステンション」のものがある.
新しいものに置き換えて PC を操作していると,エクスプローラがうまく動作しない.ダウンする.
他の exe で実行しても同様で,イベントビューアを見ると次の様になっている.
障害が発生しているアプリケーション名: DImg.exe、バージョン: 1.0.0.1、タイム スタンプ: 0x4b5822a3
障害が発生しているモジュール名: iShelExt.dll、バージョン: 1.55.2024.8、タイム スタンプ: 0x6751c1dc
例外コード: 0xc000041d
障害オフセット: 0x0004aadc
障害が発生しているプロセス ID: 0x5054
障害が発生しているアプリケーションの開始時刻: 0x01db477a20d02f17
障害が発生しているアプリケーション パス: L:\Document\Develop\Debug\ShellExt\DImg\Release\DImg.exe
障害が発生しているモジュール パス: C:\Users\Public\Documents\Tools\i_Tools\Test\iShelExt.dll
レポート ID: c898b214-2c4e-4701-8c17-27d414c106fb
障害が発生しているパッケージの完全な名前:
障害が発生しているパッケージに関連するアプリケーション ID:
シェルエクステンションでの表示データを求める部分を直接呼出している単体テスト用 exe では問題ない.
これは予想通り.
「開く」ダイアログでシェルエクステンションのテストができるのでコンソール AP を作成.
https://itl.mish.work/i_Tools/Doc/blog/vc/c_sxt.zip
VC 2022 の「デバッグ」-「コマンドライン」で …\c_sxt.exe を指定.
__targv がうまくなかった.DLL の場合は NULL になる?
次の様に修正.
#ifdef _MSC_VER
{
if (G_arg.size() == 0) {
// ::reg_argv(__argc,__targv) ;
if (__targv != NULL) {
for (int index=0 ; index<__argc ; index++) {
tstring av = __targv[index] ;
G_arg.push_back(av) ;
}
}
}
}
#endif
::ShellExecute
「インデックスのオプション」を開くために ::ShellExecute などから開けないかと…
検索するとコマンドプロンプトなどで「control.exe /name Microsoft.IndexingOptions」とすれば良いことがわかった.
この動作の cpp のコード.
CString Error_FormatMessage(const DWORD error)
{
CString message ;
LPVOID lpMessageBuffer = NULL ;
if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,error,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
(LPTSTR)&lpMessageBuffer,0,NULL)) {
message = LPTSTR(lpMessageBuffer) ;
::LocalFree(lpMessageBuffer) ;
}
return message ;
}
void CShellEDlg::OnExecute()
{
UpdateData(TRUE) ;
HINSTANCE hInst = ::ShellExecute(this->GetSafeHwnd(),m_StrOper,m_StrFile,m_StrPara,NULL,SW_SHOW) ;
if (UINT64(hInst) > 32) { return ; }
DWORD error = ::GetLastError() ;
CString str ;
{
str.Format(_T("%d\r\n%d"),DWORD(hInst),error) ;
str += _T(" ") + ::Error_FormatMessage(error) ;
str += _T("\r\n") + m_StrOper ;
str += _T("\r\n") + m_StrFile ;
str += _T("\r\n") + m_StrPara ;
}
AfxMessageBox(str) ;
}
IShellLink::SetShowCmd
ツールなどのスタートアップへの登録.
スタートアップのパスの取得は次の様な感じ.
LPITEMIDLIST pidl = 0 ;
::SHGetSpecialFolderLocation(NULL,CSIDL_STARTUP,&pidl) ;
tstring start_path = ::SH_GetPathFromIDList(pidl) ;
lnk の作成は,以前にツールを作成してその時のものを利用.
http://mish.work/joomla/index.php/i-tools/create-l.html
https://mish.myds.me/wordpress/dev/2020/01/11/msdn-createlink/
lnk のスタートアップへの登録は次の様にできる.
tstring start_lnk = ::Path_AddLastSP(start_path) + ::Path_GetTitle(file_path) + _T(".lnk") ;
tstring descript = _T("コメント") ;
::Create_lnk(file_path.c_str(),start_lnk.c_str(),descript.c_str()) ;
今回は,robocopy のコマンドを BAT ファイルとして生成し,それをスタートアップへ登録したかった.
http://mish.work/joomla/index.php/i-tools/cl-copy.html
動作としてはうまく機能するが,BAT ファイルを使用しているためコマンドプロンプトが表示されてしまう.
最小化された状態で起動する方が動作はスマート?
lnk 作成時に指定できるだろうと思い 検索 するとあった.
シェルリンク
IShellLink::SetShowCmd を使えば良さそう.
SW_SHOWMINIMIZED を指定してもうまく動作しない.SW_SHOWMAXIMIZED はうまく動作する.
SW_SHOWMINIMIZED ではなく SW_SHOWMINNOACTIVE を使うみたい.
::Create_lnk(file_path.c_str(),start_lnk.c_str(),descript.c_str(),work_dir.c_str(),SW_SHOWMINNOACTIVE) ;
::CreateLink している所を変更してうまくいった.
S_lnk.hxx
PHP escapeshellarg
以前から気にはなっていた PHP の escapeshellarg を調べてみた.
次の様なコードがうまくない.
<?php $param = ($_REQUEST['input']) ; $cmd_to = "cal " . $param ; system ( $cmd_to ) ; ?>
次の様な入力を意図しているが,
…/cal/?input=2020
後ろに次のコマンドを付加されるとうまくない.
…/cal/?input=2020;ls -l
cal 2020 が表示された後 ls -l が動作している.
「コマンドインジェクション」と呼ぶらしく,検索するといろいろと出てくる.
コマンドの引数にあたる部分に escapeshellarg を使用するか,$param をチェックするする必要がある.
$cmd_to = "cal " . escapeshellarg ( $param ) ;
shell:sendto
ドキュメントの「右クリック」-「送る」に「メモ帳」を追加しようと思い検索.
SendTo フォルダに NotePad.exe のショートカットを作成すれば良い.
これはいつも行っていることなので知っていたが,新しいしことを見つけた.
【Windows】右クリックメニュー[送る]の活用方法、追加・設定方法(SendToディレクトリの場所一覧)
Windows10 「送る」によく使うフォルダーを追加する方法(SendTo)
送る(sendto)、スタートアップ(startup)のフォルダに簡単にアクセスする方法 | Windows10
「ファイル名を指定して実行」やエクスプローラのアドレス欄に shell:sendto と入力すると対応するフォルダを開くことができる.
Shell コマンドで開く特殊フォルダー一覧
::SHGetFolderPath にあたる機能みたい.
今は ::SHGetKnownFolderPath .
CSIDL が FOLDERID .
Shell Extension のデバッグ
Shell Extension で,縮小版の背景に GDI+ を使用して,どうも動作が安定しなくなった.
現象としては,環境によるが explorer.exe が「応答なし」に.
GDI+ の GdiplusShutdown の呼び方が悪かったみたいで,DllCanUnloadNow で終わらせる様にした.
また,今回デバッグ用にダンプする様にしていて,そのファイルをエクスプローラで選択しようとするとフリーズ.
これは,デフォルトでは出力しないことで回避.
今回これらをやっていて,以前から面倒と思っていた ShellExt.dll のデバッグ.
デバッグ版.dll が呼ばれる様に設定して,普通の exe で「開く」ダイアログで dll 内をデバッグできる.
Shell を利用した zip
以下のページを参考にさせてもらって,zip を扱うクラスを作成した.
http://eternalwindows.jp/installer/zip/zip01.html
http://www.softist.com/programming/shell32-zip/shell32-zip.htm
但し,zip , CopyHere で検索すると以下が見つかり,本当はうまくないものと思われる.
CopyHere メソッドから Zip ファイルを処理することはできません
ついに解禁!.NET で ZIP 制御
ZipFold.2012.11.19.zip
i_ZipFold 1.0.2013.1
i_Tools Vector
この exe では,パスワードに対応してません.エラーになります.
2022/01/06
i_Zip.hxx
Shell Extension InfoTip の追加
Shell Extension の作成 InfoTip
1.プロジェクトの作成
MFC App Wizard(dll)
「スタティックライブラリを使用した DLL」を選択
「オートメーション」のサポート
2.クラスファクトリの作成
Class Wizard で,クラスの新規作成
基本クラスは CCmdTarget
「タイプ ID で作成」
3.ヘッダ部に INTERFACE_PART の追加
BEGIN_INTERFACE_PART(QueryInfoT,IQueryInfo)
STDMETHOD (GetInfoFlags) (DWORD* pdwFlags) ;
STDMETHOD (GetInfoTip ) (DWORD dwFlags,LPWSTR* ppwszTip) ;
END_INTERFACE_PART (QueryInfoT)
…
BEGIN_INTERFACE_PART(PersistFile,IPersistFile)
…
4.必要な変数を追加
InfoTip の場合,FileName など
5.ソースに INTERFACE_MAP の追加
BEGIN_INTERFACE_MAP(CI_ShellExt,CCmdTarget)
INTERFACE_PART (CI_ShellExt,IID_IQueryInfo,QueryInfoT)
INTERFACE_PART (CI_ShellExt,IID_IPersistFile,PersistFile)
END_INTERFACE_MAP ()
6.CI_ShellExt::XQueryInfoT::~ の実装
幾つかはある程度決まったコードになる.
CI_ShellExt::XQueryInfoT::GetInfoTipは,ppwszTipに表示する文字列を返す.
METHOD_PROLOGUE pThisでCCmdTargetの派生クラスにアクセス可能になる.
レジストリへの登録
[HKEY_CURRENT_USER\Software\Classes\CLSID\{56D044C5-9F47-4CD3-B130-9E52BE7460F3}]
@=”I.ShellExt”
[HKEY_CURRENT_USER\Software\Classes\CLSID\{56D044C5-9F47-4CD3-B130-9E52BE7460F3}\InProcServer32]
@=”C:\\Documents and Settings\\All Users\\Documents\\VC_TEST\\IShlExt\\Release\\I_Shl_E.dll”
“ThreadingModel”=”Apartment”
[HKEY_CURRENT_USER\Software\Classes\CLSID\{56D044C5-9F47-4CD3-B130-9E52BE7460F3}\ProgID]
@=”I.ShellExt”
拡張子の登録例
[HKEY_CURRENT_USER\Software\Classes\.Test_ShellExt\ShellEx\{00021500-0000-0000-C000-000000000046}]
@=”{56D044C5-9F47-4CD3-B130-9E52BE7460F3}”
{56D044C5-9F47-4CD3-B130-9E52BE7460F3} の部分は,ソースの IMPLEMENT_OLECREATE の前の行のコメントより
今回使用したコードは,IShlExt.zip
参考にしたのは,
Debugging with the Shell
MSDN Magazine 2000/04 新しいinfotip,アイコンオーバーレイ,シェルエクステンション
Windows 2000 UI Innovations: Enhance Your User’s Experience with New Infotip and Icon Overlay Shell Extensions
MSDN Magazine 2000/07 ハイパーテキストテンプレートファイルのカスタマイズによるエクスプローラの表示の拡張
Windows 95 ユーザーインターフェイス プログラミング
ExtractImage を実装してエラーになった場合
I_ShlExt.obj:error LNK2001:外部シンボル “_IID_IExtractImage” は未解決です
#include <initguid.h> を I_ShlExt.cpp の StdAfx.h の次に追加.
Shell.Tile…
以前,デスクトップ上のウィンドウを操作したいことがあった.
ToggleDT.scf
[Shell]
Command=2
IconFile=explorer.exe,3
[Taskbar]
Command=ToggleDesktop
TileVert.vbs
Set objShell = CreateObject(“Shell.Application”)
objShell.TileVertically
TileHorz.vbs
Set objShell = CreateObject(“Shell.Application”)
objShell.TileHorizontally
CascadeW.vbs
Set objShell = CreateObject(“Shell.Application”)
objShell.CascadeWindows
//**************************************************************************************************
// ファイル名 :CtrlDskT.cxx
// 機能名 :デスクトップの制御
// 作成者 :
// 作成年月日 :’07/08/08
// 変更履歴 :
//**************************************************************************************************
//
#include <Afx.h>
#include "DelFileE.hxx"
#include "CharMFC.hxx"
#include "ShellExc.hxx"
#include "HelpAPI.hxx"
#include "CtrlDskT.hxx"
////
//*******************************************************************************
// 関数名 :デスクトップの表示
// 作成日 :’07/08/08
//*******************************************************************************
// http://support.microsoft.com/kb/190355/ja
// クイック起動バーに [デスクトップの表示] アイコンを再登録する方法
BOOL ControlDesktop::ToggleDesktop (void)
{
CString td_scf = ::GetTempPath()+_T("Command.tmp\\") + _T("ToggleDT.scf") ;
if (::FileIsNothing(td_scf)) {
// "デスクトップの表示.scf" の生成
::CreateEmptyFile(td_scf) ;
CString tdCmd ;
tdCmd += _T("[Shell]\r\n") ;
tdCmd += _T("Command=2\r\n") ;
tdCmd += _T("IconFile=explorer.exe,3\r\n") ;
tdCmd += _T("[Taskbar]\r\n") ;
tdCmd += _T("Command=ToggleDesktop\r\n") ;
::SaveText(td_scf,tdCmd) ;
}
ShellExec se ;
se.SetFile(td_scf) ;
se.Execute() ;
{ // 終了時に削除するように登録
static DelFileE dfe ;
dfe.Add(td_scf) ;
}
return TRUE ;
}
////
//*******************************************************************************
// 関数名 :重ねて表示,上下に並べて表示,左右に並べて表示
// 作成日 :’07/08/08
//*******************************************************************************
// http://www.microsoft.com/japan/technet/scriptcenter/resources/qanda/jul05/hey0726.mspx
// Hey, Scripting Guy! デスクトップ上にウィンドウを並べて表示する方法はありますか
#define CD_AW_CascadeW 0
#define CD_AW_TileHorz 1
#define CD_AW_TileVert 2
BOOL ControlDesktop::CascadeWindows (void) { return
ArrangeWindows(CD_AW_CascadeW) ; }
BOOL ControlDesktop::TileHorizontally(void) { return
ArrangeWindows(CD_AW_TileHorz) ; }
BOOL ControlDesktop::TileVertically (void) { return
ArrangeWindows(CD_AW_TileVert) ; }
BOOL ControlDesktop::ArrangeWindows (const long type)
{
CString cw_vbs = ::GetTempPath()+_T("Command.tmp\\") + _T("CascadeW.vbs") ;
CString th_vbs = ::GetTempPath()+_T("Command.tmp\\") + _T("TileHorz.vbs") ;
CString tv_vbs = ::GetTempPath()+_T("Command.tmp\\") + _T("TileVert.vbs") ;
CString cmdvbs ;
CString cmdExc ;
switch (type) {
case CD_AW_CascadeW : cmdvbs = cw_vbs ; cmdExc = _T("objShell.CascadeWindows \r\n") ; break ;
case CD_AW_TileHorz : cmdvbs = th_vbs ; cmdExc = _T("objShell.TileHorizontally \r\n") ; break ;
case CD_AW_TileVert : cmdvbs = tv_vbs ; cmdExc = _T("objShell.TileVertically \r\n") ; break ;
default : cmdvbs = cw_vbs ; cmdExc = _T("objShell.CascadeWindows \r\n") ; break ;
}
if (::FileIsNothing(cmdvbs)) {
::CreateEmptyFile(cmdvbs) ;
CString awCmd ;
awCmd += _T("Set objShell = CreateObject(\"Shell.Application\")\r\n") ;
awCmd += cmdExc ;
// objShell.TileHorizontally
// objShell.TileVertically
// objShell.CascadeWindows
::SaveText(cmdvbs,awCmd) ;
}
ShellExec se ;
se.SetFile(cmdvbs) ;
se.SetShowCmd(SW_HIDE) ;
se.Execute() ;
{ // 終了時に削除するように登録
static DelFileE dfe ;
dfe.Add(cmdvbs) ;
}
return TRUE ;
}
デスクトップ上にウィンドウを並べて表示する方法はありますか。
Shell.TileHorizontally method
Shell_NotifyIcon
http://support.microsoft.com/kb/418138/ja
マウスの位置の取得
BOOL ::GetCursorPos(LPPOINT lpPoint) ;
http://cid-535f5973454c1292.office.live.com/self.aspx/.Public/MFC/NotifyI.hxx.txt
サムネイル表示が止まる?
以前作成したエクスプローラのサムネイル表示.
前からの現象だが,不定期に表示が止まってしまうことがあった.
ほとんどが個人的に作成したシェルエクステンションの影響だが,今回は違ったように思う.
全ての explorer.exe を終了させても改善されない.
再起動すれば良いのはわかっているが,順に exe を終了させることに…
dllhost.exe を終了させると,止まっていた表示が動き出した.
ハッキリしたことがわかってないので,とりあえずメモ.
TryHackMe を使って…
先日「7日間でハッキングをはじめる本」を購入して,その内容をやった.
7日間とはいかず,2週間程度かかってしまった.
20年位前に作成した Web のシステムでは,これらの知識がなかったため幾つか問題があった.
何年か前に修正済みで,そのほとんどが「クロスサイトスクリプティング」だったと思う.
「OSコマンドインジェクション」などは知っていたが,ポートスキャンやパスワードの具体的な部分がわかった.
デフォルトポートの危険性や,パスワードで「数桁の数字」などは意味がないことがよくわかる.
外には公開していないので問題なかったとは思うが
LAN 内の幾つかの機器をポートスキャンしてみると,意図していないものが開いたままのものがあった.
10年位前に追加したもので,設定を間違えたのか,デフォルトで開いていたのか…
2024/10/02
この様な記事を書いたからというわけではないと思うが,昨日から次の様なアクセスが来ている.
//mish.work/?a='>"></script><svg/onload=confirm(1)>&b='>"></script><svg/onload=confirm(2)>&c=...
特に問題ないと思うが,ログが汚くなってしまう.
¥¥(コンピュータ名) を開く
\\(ComputerName) を開きたいと思い,次の様なコードを書いた.
{
tstring self_name = _T("\\\\") + ::GetComputerName() + _T("\\") ;
S_Exec se ;
se.SetFile(self_name.c_str()) ;
se.Execute() ;
}
これはこれでうまく動作するが,それを perplexity に問い合わせると
#include <windows.h>
#include <shellapi.h>
int main()
{
TCHAR computerName[MAX_COMPUTERNAME_LENGTH + 1];
DWORD size = sizeof(computerName) / sizeof(computerName[0]);
// コンピューター名を取得
if (GetComputerName(computerName, &size))
{
// ネットワークパスを構築
TCHAR networkPath[MAX_PATH];
wsprintf(networkPath, TEXT("\\\\%s"), computerName);
// ShellExecuteを使用してエクスプローラーを起動
ShellExecute(NULL, TEXT("open"), TEXT("explorer.exe"), networkPath, NULL, SW_SHOWNORMAL);
}
return 0;
}
そのままで動作するコードが表示されている.
CXxxxDlg::OnCreate が 2 回
「ある操作を行ったとき exe が 2 つ起動する」と報告があった.
言い訳になるが,通常この動作は年に 2 回程度しか通らないもの.また,他の操作により通らないこともある.
その条件になる様に環境を設定して試すと,確かに…
その部分のコードは,何年も変更はしていない.
いろいろと動作を確認していると,VC 10 以前では問題ないが,11 以降で 2 つ起動することがわかった.
その動作の部分のみを抜き出して動作を試した.
int CT_DlG_1Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: ここに特定な作成コードを追加してください。
{
HWND HWnd = NULL ;
{
CWnd* mainWnd = AfxGetMainWnd() ;
if (mainWnd != NULL) {
HWnd = mainWnd->GetSafeHwnd() ;
}
}
HINSTANCE hInst = ::ShellExecute(HWnd,NULL,_T("NotePad.exe"),NULL,NULL,SW_SHOWNORMAL) ;
return -1 ;
}
return 0;
}
MFC の動作が変わったのか,CXxxxDlg::OnCreate が 2 回呼ばれるようになったみたい.
https://itl.mish.work/i_Tools/Doc/blog/vc/TDlg0614.zip
2 回目に呼ばれた時は,何もしないで return -1 とする様に変更予定.
「Windows 検索」設定
Windwos Search の「インデックスのオプション」を開きたいと問い合わせが入った.
以前の Windows であれば「コントロールパネル」から入ると「インデックスのオプション」があった.
Win10 以降?は「コントロールパネル」も簡単には開けない.
Windows の検索ボックスで “インデックスのオプション” と入力すれば良かったのだが…
それが思い出せず,”Windows サーチ” や “Windows 検索” と入力して,うまくたどり着けない.
“Windows Search” と入力しないとうまくないみたい.
「Windows 検索」の「クラッシック」の下の「…検索場所をカスタマイズ…」を選ぶと表示できる.
Windows の設定などは,キーワードを英語で入力する方が良いのかもしれない.
2024/06/19
「スタート」で表示される「検索ボックス」に何か入力すると「…」(オプション メニュー)が表示される.
それを選択すると「インデックス オプション」などがある.
2024/06/20
「インデックス オプション」は次の様なコマンドでも可能なので,::ShellExecute で呼び出す様にした.
control.exe /name Microsoft.IndexingOptions
3MF データが開けない?
3D データを 3MF 出力したものが開けなくなったと問い合わせが入った.
開発環境では現象がなかなか確認できなかったが,自前の iZIP.exe 版の影響とわかった.
Shell の ZIP 機能を使用していた 2022/12 いっぱいぐらいはうまく動作する.
.net を使用した iZIP.exe にしてからの 3MF がうまく開けない.
自前で作成している 3D ビューアなどではうまく開ける.
それぞれの 3MF を展開して,テキストエディタなどで比較しても特に違いはない.
また 3MF をバイナリで比較すると,少し異なる所があることはわかる.
まだはっきりしていないが,バイナリを見た限りではディレクトリ区切りの影響か?
2024/05/16
iZIP.exe が影響していることはわかったが,その違いがなかなかわからなかった.
iZIP.exe を起動して 3MF を展開したイメージのフォルダをドロップして確認.
iZIP.exe をビルドしている VC が 2022 でないとうまくないみたい.
関連しそうなのは次の情報か?
軽減策:ZipArchiveEntry.FullName パスの区切り文字
.NET Framework 4.6.x への移行に関する変更の再ターゲット
試しに ZipFile::CreateFromDirectory に渡すファイル名を ‘/’ にしてみたが,効果はなかった.
ダイアログベース コマンドライン
ファイルの関連付けを調べていて,3D データを表示するツールに関連付けるとうまく表示されない.
MFC ダイアログベースのスケルトンでは,コマンドラインの標準的な処理は入っていない.
それで OnInitDialog の最後の方で次の様にした.
{
CStringArray readFiles ;
for (int a_index=1 ; a_index<__argc ; a_index++) {
CString av = __targv[a_index] ;
readFiles.Add(av) ;
}
if (readFiles.GetSize() > 0) {
ReadFiles(readFiles) ;
}
}
更に,幾つかのツールでうまく開けないものがあった.
InitInstance での初期化手順がうまくなかった.
.INI に更新されない?
個人的なツールなどでレジストリを汚したくないために .ini を使用している.
今回個人的な ProtectT クラスを書き直してテストしているとうまく動作しない.
該当コードの単体テストではうまく通るが,ツールに組込んで動作させるとうまくいかないことがある.
コードの内容としては,共通の i_Tools.ini と AP.ini に同じ値を更新していて,それを読みだした時に値が異なっていた.
i_Tools.ini は他の AP からも読み書きしている.
タイミングによって,うまく更新できないことがある?
ProtectT の i_Tools.ini へアクセスするコードを見直して,極力書き込みを減らすようにした.
また,読み込み時,値が意図したものと異なる場合は AP.ini の方を利用する様にした.
これで今回の部分は対応できていると思うが,他の既存部分ではまだ問題がありそう.
次の様なコードで確認すると,やはり書けないことがある様子.
{
#define Sec_test _T("_test_")
#define Ent_test _T("_test_")
RI_app app ;
RI_env env ;
for (long index=0 ; index<500 ; index++) {
if (index%10 == 0) { std::tout << std::endl ; }
std::tout << index << _T("\t") ;
std::tout << app.set(Sec_test,Ent_test,index) ; std::tout << _T(" ") ;
std::tout << env.set(Sec_test,Ent_test,index) ; std::tout << _T("\t") ;
long val_a = app.get(Sec_test,Ent_test,-1) ;
long val_e = env.get(Sec_test,Ent_test,-2) ;
if (val_a != val_e) {
std::tout << std::endl ;
std::tout << val_a << _T("\t") << val_e << std::endl ;
::Sleep(1000) ;
break ;
}
::Sleep(10) ;
}
std::tout << std::endl ;
return true ;
}
env.set(…) は,内部的に ::WritePrivateProfileString を呼出していて 0 が返っている.
最初現象を簡単には再現できなかったが,エクスプローラのサムネイル表示を行っていると発生しやすい.
また,今回のテスト用 exe が止まってしまうこともあった.開いているエクスプローラをすべて閉じることで解消.
シェルエクステンションのコードの見直しが必要か?
ini への書き込み部分を次の様に変更.
// return ( ::WritePrivateProfileString(sec,ent,val,ini)==TRUE) ;
BOOL res = ::WritePrivateProfileString(sec,ent,val,ini) ;
if (!res) {
std::terr << _T("::WritePrivateProfileString ") << sec << _T(" ") << ent << _T(" ") << ::GetLastError() << std::endl ;
for (size_t index=0 ; index<10 ; index++) {
res = ::WritePrivateProfileString(sec,ent,val,ini) ;
if (res) { break ; }
::Sleep(10) ;
}
}
return (res==TRUE) ;
::GetLastError() では 32 ERROR_SHARING_VIOLATION が返ってくる.