ホーム » Windows

Windows」カテゴリーアーカイブ

2024年7月
 123456
78910111213
14151617181920
21222324252627
28293031  

カテゴリー

アーカイブ

ブログ統計情報

  • 88,796 アクセス


¥¥(コンピュータ名) を開く

\\(ComputerName) を開きたいと思い,次の様なコードを書いた.

{
	tstring	self_name = _T("\\\\") + ::GetComputerName() + _T("\\") ;
	S_Exec	se ;
	se.SetFile(self_name.c_str()) ;
	se.Execute() ;
	}

これはこれでうまく動作するが,それを perplexity に問い合わせると
::ShellExecute エクスプローラ 自分自身をネットワーク名で開く

#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;
}

そのままで動作するコードが表示されている.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

コンソール AP のアイコン

以前,コンソール AP にアイコンなどのリソースを追加する方法はいろいろとやった.
それを今回,動作時にアイコンを変更できないかと…
最初 Copilot で問合わせたがうまい情報は引っ掛からなかった.
それで今度は最近利用し始めた perplexity で…
「Windows cpp で コンソール AP のアイコンを指定する方法と動的に変更する方法」と入力.
perplexity  SetConsoleIcon
kernel32 にある SetConsoleIcon が使えるらしい.
それで次の様なコードを書いてみたが…

BOOL WINAPI SetConsoleIcon(HICON hIcon)
{
    typedef BOOL (WINAPI *SetConsoleIconFn)(HICON);
    static SetConsoleIconFn setConsoleIcon = NULL;

    if (setConsoleIcon == NULL)
    {
        HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
        if (hKernel32 == NULL) return FALSE;

        setConsoleIcon = (SetConsoleIconFn)GetProcAddress(hKernel32, "SetConsoleIcon");
        if (setConsoleIcon == NULL) return FALSE;
        }
    return setConsoleIcon(hIcon);
    }

bool    test    (c_tstring& str)
{
    std::terr << str << std::endl ;
    ::pause(10) ;
    HICON   hIcn2 = ::LoadIcon(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON2)) ;
    HICON   hIcn3 = ::LoadIcon(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON3)) ;
    {
        HWND    hWnd  = ::GetConsoleWindow() ;
        ::SendMessage(hWnd,WM_SETICON,TRUE, (LPARAM)hIcn2) ;
        ::SendMessage(hWnd,WM_SETICON,FALSE,(LPARAM)hIcn2) ;
        }
    ::pause(20) ;
    {
        SetConsoleIcon(hIcn3) ;
        }
    ::pause(30) ;
    return  true ;
    }

Win7 や 8.1 ではうまく変更できたが,Win10 や 11 では変更できなかった.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

robocopy エラー 87

IO DATA SSPA-USC500K が手に入ったので,テストを兼ねてソースなどをバックアップ.
アイ・オー・データ ポータブルSSD SSPA-USC500K
自前の「ディレクトリ以下のコピー」ツールでコピーしていると…

100%      新しいファイル                    1300        Vxx_P_A_.hxx
2024/06/23 15:44:41 エラー 87 (0x00000057) ファイル属性を変更しています \\DS220\Public\Document\Develop\_.SRC\__Iwao\P_A_gnsa.hxx
パラメーターが間違っています。
5 秒間待機しています... 再試行しています...

robocopy エラー 87 (0x00000057) ファイル属性を変更しています    
パラメーターが間違っています。
全てのファイルがこの様になるわけではない.
原因は,恐らくコピー先が exFAT のため?
ちゃんと調べたわけではないが,更新日時が古い(最近編集していない)ファイルでエラーになる模様.
これらのファイルは,昔 NT サーバなどで管理していたものを NAS に移して運用している.
その後,その NAS 上のものを編集する様になり,更新したものはエラーにはなっていない?
コピーはできているのと,同じコマンドの再実行ではエラーにはならないのでこのままとする.


エラーになったファイルは「作成日時」と「アクセス日時」がコピーしたタイミングに更新されてしまっている.


2024/07/10
改めて調べてみると,コピー元のアクセス日時が正しくない
robocopy  コピー元の作成日時が正しくない

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

::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) ;
	}

CShellEDlg::OnExecute()
ShellE  メンバ変数
ShellE.exe
https://itl.mish.work/i_Tools/Doc/blog/vc/ShellE.zip

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

SetWindowPos で最前面に

以前から CWnd::SetWindowPos などを使用してウィンドウを最前面にしているツールがいくつかある.
ほとんどの場合これでうまくいっているが,先日テストしていて最前面に移動しない現象を確認.


2 つの exe があり,A.exe から B.exe を起動している.
B.exe はダイアログベースで,そのウィンドウを A.exe のウィンドウより前面に表示するもの.


Spy++ で見ると最前面に移動できた時は WS_EX_TOPMOST がある.
WS_EX_TOPMOST
が,うまくいかない場合には WS_EX_TOPMOST がない状態.


いろいろと操作してみたが,なかなか現象が絞れなかった.
結局は B.exe を起動する時,他のウィンドウにフォーカスが移っている?と,最前面にならないみたい.
B.exe の起動をエクスプローラなどから行い,ウィンドウが表示される前にブラウザなどに切替えると最前面にならない.


今回対象のものは,最前面に移動しなくても問題ないと思われるのでこのままとする.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

mfc140ud.dll が見つからない …

「mfc140u.dll が見つからない…」の場合は
Microsoft Visual C++ 再頒布可能パッケージ


VC 2019 でデバッグビルドして実行すると,
—————————
Test.exe – システム エラー
—————————
mfc140ud.dll が見つからないため、コードの実行を続行できません。プログラムを再インストールすると、この問題が解決する可能性があります。
—————————
OK
—————————
VCRUNTIME140D.dll が見つからないため、コードの実行を続行できません。
ファイル名の所は MSVCP140D.dll などもある.
また exe は VC 2015 以降でデバッグビルドしたもの.


原因はわかっている.先日 VC 2022 のアップデートがあった.
その時 Win11 環境はうまくできたが Win10 環境では何故か失敗したため.
Microsoft.VisualCpp.Redist.14 をインストールできませんでした
どうしたものか…

「VS Installer」の「VS 2022」で「変更」を選択,そのまま進めるとダウンロード,インストールが始まった.
「VS Installer」の「VS 2022」で「変更」を選択
「修復」の方が良かったみたいだが …


「再起動が必要」の画面になり,その前にデバッグ版 exe を試すとうまく起動した.
「再起動が必要」

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

高 DPI 環境での CToolBar

vC 6 MFC プロジェクトを VC 2010 以降に更新すると,高 DPI 環境でツールバーがうまくない.
VC 10 以降でビルドした exe で,ツールバーが大きくならない
CMFCToolBar であれば OK .


個人的には 2005/06 に作成したコードを改良したものを使用している.
どこを参考にしたのかはちょっとわからない.
MFCによるWindows95プログラミング」や「INSIDE VISUAL C++ 5TH ED」などと思う.
それを簡単に利用できる様にできないかと…


コードは次の様な感じ.

BOOL	ToolBar__Resize	(CToolBar* toolBar,UINT idr)
{
	double	dpi_s = 1. ;
	{
		dpi_s = ::GetDPI_scale(toolBar->GetSafeHwnd()) ;	//  ::GetDpiForWindow() / 96.
		}
	if (dpi_s == 1.) {
		return	TRUE ;
		}
	CToolBarCtrl&	tbCtrl = toolBar->GetToolBarCtrl() ;
	CSize	btnSize(0,0) ;
	CRect	bdrRect(0,0,0,0) ;
	{	//  ボタンなどのサイズを取得
		DWORD	dwSize = tbCtrl.GetButtonSize() ;
		{
			btnSize.cx = LOWORD(dwSize) ;
			btnSize.cy = HIWORD(dwSize) ;
			}
		bdrRect        = toolBar->GetBorders() ;
		}
	CSize	newBtnSize = btnSize ;
	CRect	newBdrRect = bdrRect ;
	{	//  サイズを調整
		newBtnSize.cx    = int(btnSize.cx    *dpi_s) ;
		newBtnSize.cy    = int(btnSize.cy    *dpi_s) ;
		newBdrRect.left  = int(bdrRect.left  *dpi_s) ;
		newBdrRect.top   = int(bdrRect.top   *dpi_s) ;
		newBdrRect.right = int(bdrRect.right *dpi_s) ;
		newBdrRect.bottom= int(bdrRect.bottom*dpi_s) ;
		}
	{	//  サイズを指定
		tbCtrl.SetButtonSize(newBtnSize) ;
		toolBar->SetBorders(newBdrRect) ;
		}
	return	TRUE ;
	}

CToolBarCtrl  SetButtonSize
ツールバーボタンのビットマップのリサイズはまだ書換えができていない.
https://itl.mish.work/i_Tools/Doc/blog/migrate/Test0603.zip

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

VC6 から VC2019 への移行

今回は VC 6 ds? の VC 2019 への更新.
VS 2022 では,VC 6 からのアップグレードがなくなった


VS 2019 で dsw を開き 2019 に更新.
設定は VC 8 の時の手順とほとんど変わらない(設定値が微妙に異なる部分あり).
出力ディレクトリなどを「c:\Temp\…\$(ProjectName)\$(Configuration).142\」に.
VC 2019 出力ファイル
「文字セット」を「Unicode 文字セットを使用する」に.
VC 2019 文字セット
「プリコンパイル済み…」を「$(IntDir)$(TargetName).pch」に.
VC 2019  プリコンパイル済みヘッダ
「C/C++」の「出力ファイル」を「$(IntDir)」に.
VC 2019 C/C++ 出力ファイル
「リンカ」の「出力ファイル」を「$(OutDir)$(ProjectName).exe」に.
VC 2019 リンカ 出力ファイル
「ブラウザ情報」の「出力ファイル」を「$(OutDir)$(ProjectName).bsc」に.
VC 2019 ブラウザ情報 出力ファイル


そのままビルドすると,デバッグ版では D8016 エラーになる.
「C/C++」-「すべてのオプション」の「関数レベルでリンクする」をブランクに.
「関数レベルでリンクする」をブランクに


https://itl.mish.work/i_Tools/Doc/blog/migrate/Test0526.zip

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

VC6 プロジェクトの移行

今更の内容ではあるが,VC 6 プロジェクトを VC 8 などに移行する手順のまとめ.


私の場合,VC 6 からプロジェクトを作成して VC 2017 などでビルドした exe をリリースすることが多い.
他にも,コードの単体テストのためにコンソール AP を作成する時も VC 6 がお手軽.
Win11 でも MFC42*.dll などは入っているので,テストも exe をコピーすれば可能となる.
以前は VC 7 なども対象としていたが,関係するプロジェクトで必要がなくなり,今は使っていない.
また VC 7 形式を通すvcproj を直接編集しないといけない状態になることがある.
プロジェクトのバックアップをしやすい様に exe などの出力先は,別の所を指定している.


VC 6 で MDI プロジェクトとして作成.プロジェクト名はなるべく 5 文字以下にしている.
出力ディレクトリを変更.この時 VC のバージョンごとに出力先を分けている.
出力ディレクトリを変更

C:.
└─Test
    ├─Debug.060
    ├─Debug.080
    ├─Release.060
    └─Release.080

VC 8 で Test.dsw を開く.
文字セットを「Unicode 文字セットを使用する」に.
出力ディレクトリなどを「c:\Temp\…\$(ProjectName)\$(ConfigurationName).080」に.
VC 8 出力ディレクトリ
「プリコンパイル済み…」を「$(IntDir)/$(TargetName).pch」に.
プリコンパイル済みヘッダファイル
「C/C++」の「出力ファイル」を「$(IntDir)/」に.
C/C++  出力ファイル
「リンカ」の「出力ファイル」を「$(OutDir)/$(ProjectName).exe」に.
リンカ 出力ファイル
「プログラム データベース…」を「$(OutDir)/$(ProjectName).pdb」に.
プログラム データベース ファイルの生成
「ブラウザ情報」の「出力ファイル」を「$(OutDir)/$(ProjectName).bsc」に.
ブラウザ情報 出力ファイル
ツリーに「MIDL」が表示されている場合は「タイプライブラリ」を「$(IntDir)/$(ProjectName).tlb」に変更.
必要に応じて,それぞれの「コマンド ライン」で 060 のままの所がないか確認.


ビルドすると次のワーニングになる.

1>------ ビルド開始: プロジェクト: Test, 構成: Debug Win32 ------
1>コンパイルしています...
1>Test.cpp
1>o:\document\vc_test\migrate\test\test.cpp(61) : warning C4996: 'CWinApp::Enable3dControls': CWinApp::Enable3dControls is no longer needed. You should remove this call.
1>        c:\program files (x86)\microsoft visual studio 8\vc\atlmfc\include\afxwin.h(4477) : 'CWinApp::Enable3dControls' の宣言を確認してください。
1>リンクしています...
1>マニフェストを埋め込んでいます...
1>Test - エラー 0、警告 1
========== ビルド: 1 正常終了、0 失敗、0 更新、0 スキップ ==========

削除,または次の様に修正する.

#if(_MFC_VER >= 0x0700)
#else
#ifdef _AFXDLL
	Enable3dControls();		// 共有 DLL 内で MFC を使う場合はここをコールしてください。
#else
	Enable3dControlsStatic();	// MFC と静的にリンクする場合はここをコールしてください。
#endif
#endif

個人的によく変更する設定として
「C/C++」-「言語」-「OpenMP サポート」を「はい」に.
「リンカ」-「システム」-「大きい…アドレス」を「2GBを超える…サポートする」に.


Test.sln と Test.vcproj を Test_80.sln と Test_80.vcproj としてコピー.
Test_80.sln をエディタで開いて,Test_80.vcproj に.
sln ファイルを編集して ~_80.vcproj に


vC 9 以降に更新する場合は Test.sln を開く.
出力ディレクトリなどを「c:\Temp\…\$(ProjectName)\$(ConfigurationName).090」などに.
VC 9 出力ファイル
VC 8 の時と同様に
Test.sln と Test.vcproj を Test_90.sln と Test_90.vcproj としてコピー.
Test_90.sln をエディタで開いて,Test_90.vcproj に.


vcproj をエディタで開くと TypeLibraryName が c:\Temp\…\Test\Debug.060/Test.tlb として残っている.
そのままでも問題はなさそうだが,修正するとすれば $(IntDir)/$(ProjectName).tlb か.
https://itl.mish.work/i_Tools/Doc/blog/migrate/Test0520.zip


2024/07/26
VC 10 以降でビルドした MDI.exe で「引数が正しくありません。」となることがある.
対応方法は InitInstance に AfxOleInit() の呼出しを追加する.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

「Windows 検索」設定

Windwos Search の「インデックスのオプション」を開きたいと問い合わせが入った.
「インデックスのオプション」


以前の Windows であれば「コントロールパネル」から入ると「インデックスのオプション」があった.
Win10 以降?は「コントロールパネル」も簡単には開けない.


Windows の検索ボックスで “インデックスのオプション” と入力すれば良かったのだが…
それが思い出せず,”Windows サーチ” や “Windows 検索” と入力して,うまくたどり着けない.
“Windows Search” と入力しないとうまくないみたい.
Wiidows 検索ボックス 「Windows Search」
「Windows 検索」の「クラッシック」の下の「…検索場所をカスタマイズ…」を選ぶと表示できる.


Windows の設定などは,キーワードを英語で入力する方が良いのかもしれない.


2024/06/19
「スタート」で表示される「検索ボックス」に何か入力すると「…」(オプション メニュー)が表示される.
それを選択すると「インデックス オプション」などがある.
「検索ボックス」-「...」(オプション)


2024/06/20
「インデックス オプション」は次の様なコマンドでも可能なので,::ShellExecute で呼び出す様にした.
control.exe /name Microsoft.IndexingOptions

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

3MF データが開けない?

3D データを 3MF 出力したものが開けなくなったと問い合わせが入った.
3MF が開けない  0x80004003
開発環境では現象がなかなか確認できなかったが,自前の iZIP.exe 版の影響とわかった.
Shell の ZIP 機能を使用していた 2022/12 いっぱいぐらいはうまく動作する.
.net を使用した iZIP.exe にしてからの 3MF がうまく開けない


自前で作成している 3D ビューアなどではうまく開ける.
それぞれの 3MF を展開して,テキストエディタなどで比較しても特に違いはない.
また 3MF をバイナリで比較すると,少し異なる所があることはわかる.


まだはっきりしていないが,バイナリを見た限りではディレクトリ区切りの影響か?


2024/05/16
iZIP.exe が影響していることはわかったが,その違いがなかなかわからなかった.
iZIP.exe を起動して 3MF を展開したイメージのフォルダをドロップして確認.
3MF を展開した(ZIP 圧縮前の)データ
iZIP.exe をビルドしている VC が 2022 でないとうまくないみたい.


関連しそうなのは次の情報か?
軽減策:ZipArchiveEntry.FullName パスの区切り文字
.NET Framework 4.6.x への移行に関する変更の再ターゲット


試しに ZipFile::CreateFromDirectory に渡すファイル名を ‘/’ にしてみたが,効果はなかった.
ZipFile::CreateFromDirectory  '/'

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

DirectoryNotFoundException

以前作成した .NET の ZipFile クラス使用した exe
この iZIP.exe で System.IO.DirectoryNotFoundException .


原因は,ある環境でユーザ名に半角スペースが含まれていた.
ユーザ名に半角スペースを含む環境を作成して ZipFold.exe で同じ様な操作を行ったが,再現できない.
いろいろと調べていると,iZIP.exe に渡す時の入力のフォルダ名に半角スペースが含まれていると現象が発生する.

C:\Users\Iwao\AppData\Local\Temp\i_Tools.tmp\test>Q:\C_Temp\i_Tools\ZIP\iZIP\Release.140\iZIP.exe a "C:\Users\Iwao\AppData\Local\Temp\Send.tmp\20240416\09 22 39\" abc.zip

ハンドルされていない例外: System.IO.DirectoryNotFoundException: パス 'C:\Users\Iwao\AppData\Local\Temp\i_Tools.tmp\zip_CLI\20240416\154459\a' の一部が見つかりませんでした。
   場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   場所 System.IO.FileSystemEnumerableIterator`1.CommonInit()
   場所 System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
   場所 System.IO.DirectoryInfo.EnumerateFileSystemInfos(String searchPattern, SearchOption searchOption)
   場所 System.IO.Compression.ZipFile.DoCreateFromDirectory(String sourceDirectoryName, String destinationArchiveFileName, Nullable`1 compressionLevel, Boolean includeBaseDirectory, Encoding entryNameEncoding)
   場所 ZipFile_create(Char* fld_file, Char* zip_name) 場所 c:\program files (x86)\microsoft visual studio 14.0\vc\include\xstring:行 1017
   場所 zip_create(basic_string<wchar_t\,std::char_traits<wchar_t>\,std::allocator<wchar_t> >* , Char* zip_root) 場所 t:\develop\_.src\__mlt_\zip_func.hxx:行 47
   場所 zip_create(Char* fld_file, Char* zip_name) 場所 t:\develop\_.src\__mlt_\zip_func.hxx:行 143
   場所 call_func(Int32 argc, Char** argv) 場所 c:\program files (x86)\microsoft visual studio 14.0\vc\include\xstring:行 521
   場所 wmain(Int32 argc, Char** argv) 場所 l:\document\develop\tools\_free\ziptools\izip\izip.cpp:行 168
   場所 _wmainCRTStartup()

C:\Users\Iwao\AppData\Local\Temp\i_Tools.tmp\test>Q:\C_Temp\i_Tools\ZIP\iZIP\Release.140\iZIP.exe a "C:\Users\Iwao\AppData\Local\Temp\Send.tmp\20240416\09 22 39\" ".\20240416\1545\abc.zip"

ハンドルされていない例外: System.IO.DirectoryNotFoundException: パス 'C:\Users\Iwao\AppData\Local\Temp\i_Tools.tmp\zip_CLI\20240416\154602\a' の一部が見つかりませんでした。
   場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   場所 System.IO.FileSystemEnumerableIterator`1.CommonInit()
   場所 System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
   場所 System.IO.DirectoryInfo.EnumerateFileSystemInfos(String searchPattern, SearchOption searchOption)
   場所 System.IO.Compression.ZipFile.DoCreateFromDirectory(String sourceDirectoryName, String destinationArchiveFileName, Nullable`1 compressionLevel, Boolean includeBaseDirectory, Encoding entryNameEncoding)
   場所 ZipFile_create(Char* fld_file, Char* zip_name) 場所 c:\program files (x86)\microsoft visual studio 14.0\vc\include\xstring:行 1017
   場所 zip_create(basic_string<wchar_t\,std::char_traits<wchar_t>\,std::allocator<wchar_t> >* , Char* zip_root) 場所 t:\develop\_.src\__mlt_\zip_func.hxx:行 47
   場所 zip_create(Char* fld_file, Char* zip_name) 場所 t:\develop\_.src\__mlt_\zip_func.hxx:行 143
   場所 call_func(Int32 argc, Char** argv) 場所 c:\program files (x86)\microsoft visual studio 14.0\vc\include\xstring:行 521
   場所 wmain(Int32 argc, Char** argv) 場所 l:\document\develop\tools\_free\ziptools\izip\izip.cpp:行 168
   場所 _wmainCRTStartup()

C:\Users\Iwao\AppData\Local\Temp\i_Tools.tmp\test>

iZIP.exe  System.IO.DirectoryNotFoundException
入力のフォルダ名の “…\20240416\09 22 39\” の “09 22 39” 直後の ‘\’ を削除するとうまくいく.


デバッガで iZIP.exe に渡されるコマンドラインを確認.
iZIP.exe コマンドライン引数
デバッグ時,ダンプする様にコードを書換え.
iZIP.exe コマンドライン引数のダンプ
やはり argv がうまく解釈されていない.
argv[2]が「…\17 53 06″ c:\…」となってしまっている.
“…\17 53 06\\” の様にすれば通ることは確認できた.
perse_commandline では ‘\”‘ がダブルクォーテーションと解釈され,’\\’ はバックスラッシュ?


Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

「引数が正しくありません」

以前に書いた情報を整理.
Win10 21H1 でうまく動作しない exe
Win10 環境で,MDI exe にドキュメントをドロップすると「引数が正しくありません」となることがある.


原因は ::CoInitinalize が呼び出されていないため.
コードでの対応方法としては InitInstance の最初に以下を追加.

	// OLE ライブラリを初期化します。
	if (!AfxOleInit()) {
		AfxMessageBox(_T("OLE の初期化に失敗しました。")) ;
		return	FALSE ;
		}

また,一度「開く」ダイアログを表示すると,その後は問題ない.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

VirusTotal Trojan 472047

最近 ViruaTotal で,VC 2022 ビルドの exe が引っ掛かる様になった気がする.

Antiy-AVL          GrayWare/Win32.Wacapew
Arcabit            Trojan.Lazy.D733EF [many]
BitDefender        Gen:Variant.Lazy.472047
Emsisoft           Gen:Variant.Lazy.472047 (B)
GData              Gen:Variant.Lazy.474792
MAX                Malware (ai Score=87)
MaxSecure          Trojan.Malware.121218.susgen
McAfee             GenericRXWN-PP!71DE1C7042EF
Rising             Trojan.Generic@AI.83 (RDML:km3T2NBP/pqn91WCd2xwaA)
Skyhigh (SWG)      GenericRXWN-PP!71DE1C7042EF
Trellix (FireEye)  Gen:Variant.Lazy.472047
VIPRE              Gen:Variant.Lazy.472047

VirusTotal   Trojan  472014
VC 2015 や 2017 でビルドしたものはほぼ大丈夫だが,2019 や 2022 ではうまくない.
また,以前は検出されなかったものが,引っ掛かる様になったものもある.
誤検知と思われるが,どうしたものか…

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

プレーン テキスト フィルター ?

Windows Search でインデックスを作成するために,
[HKEY_CLASSES_ROOT\.(ext)\PersistentHandler]
@="{5E941D80-BF96-11CD-B579-08002B30BFEB}"

[HKEY_CURRENT_USER\SOFTWARE\Classes\.(ext)\PersistentHandler]
@="{5E941D80-BF96-11CD-B579-08002B30BFEB}"


いろいろ試したが,HKLM 以下が必要?
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.(ext)\PersistentHandler]
@="{5E941D80-BF96-11CD-B579-08002B30BFEB}"
反映される(インデックスが作成される)までに時間がかかるのでよくわからない.
プレーン テキスト フィルター
確実なのは「プレーン テキスト フィルター」に設定して,「インデックスの設定」タブの「再構築」か?


ネットワーク上のファイルも検索できるみたいだが…
検索場所を指定して「 *.txt MICROSOFT FOUNDATION CLASS LIBRARY 」.
「 *.txt MICROSOFT FOUNDATION CLASS LIBRARY 」で検索
ネットワークドライブとして割り当てると検索できる?
検索されるまで時間がかかるのと,サーバにより?うまく検索できないことがある.
Win10 環境で 「 *.txt MICROSOFT FOUNDATION CLASS LIBRARY 」

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

msi でインストールを実行できない

Win10 環境に msi でインストールしようとすると…
[Window Title]
Windows インストーラー
[Main Instruction]
システム管理者によって、ポリシーはこのインストールを実行できないように設定されています。
[OK]
Windows インストーラー
システム管理者によって、ポリシーはこのインストールを実行できないように設定されています。
検索すると「ローカルセキュリティポリシー」の設定などが見つかる.
ローカルセキュリティポリシー
他の Win10 を確認すると,同様に定義されていない.
この現象の環境は Windows Update があり,その更新後起動した状態のもの.


ポリシーを追加しようかと思ったが,念のため一度再起動.
すると,何もなかったかの様にインストールできる様になった.
何だったのだろう.


2024/04/17
また同じ現象に.
今度は,再起動する前に幾つかの exe を終了しながら確認.
ブラウザなど,メモリをそこそこ食っているものを終了.これは変わらずインストールできない.
「エクスプローラー」の「このディスプレイのすべてのウィンドウを閉じる」でインストールできる様になった.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

AppName.ini

何年か前に作成したツールをビルドしていて,ちょっと気になったこと.
exe 名を変更した時,設定値がうまく引き継がれない.
レジストリを使用している時は AFX_IDS_APP_TITLE を追加すれば良いが ini では効果がない.
CWinApp::SetCurrentHandles()    m_pszProfileName


最近書いたコードからは,次の様に m_pszProfileName を変更する様にしている.

BOOL	RI_Set_ProfileName		(void)
{
	CWinApp*	app = AfxGetApp() ;
	if (app == NULL)    	{	return	FALSE ;		}
	CString		nowINI = app->m_pszProfileName ;
	CString		newINI = ::INI_get_module_ini().c_str() ;
	if (nowINI == newINI)	{	return	TRUE ;		}
	free((void*)app->m_pszProfileName) ;
	app->m_pszProfileName = _tcsdup(newINI) ;
	{
		std::tout << _T("org=") << LPCTSTR(nowINI) << std::endl ;
		std::tout << _T("new=") << LPCTSTR(newINI) << std::endl ;
		}
	return	TRUE ;
	}
Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

ダイアログベース コマンドライン

ファイルの関連付けを調べていて,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) ;
		}
	}

S_asZ  2024.01


更に,幾つかのツールでうまく開けないものがあった.
InitInstance での初期化手順がうまくなかった.
i3DV  App  InitInstance

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

フォルダの更新日時の設定

以前に作成した mtime を更新するツール
データファイルなどの更新日時を揃えるために作成したもの.
更新日時の設定は CFile::SetStatus で行っている.

	CString		file = UpdateFiles[index] ;
	CFileStatus	fs ;
	CFile::GetStatus(file,fs) ;
	fs.m_mtime = newTime ;
	CFile::SetStatus(file,fs) ;

このツールではフォルダの更新日時は変更できない.


その後 Linux 環境などでも動作する様なコードを作成
utime を使用したもの.
Linux 環境ではフォルダに対してもうまく動作するが,Windows 環境では相変わらず.
DS220  utime
ここまでは,以前調べたもの


2ヶ月ほど前だったと思うが,検索していて次のページを見つけた.
ファイル・フォルダーの更新日時を変更


改めて CFile::SetStatus や _utime の中身を見ると,動作は同じで ::CreateFile と ::SetFileTime を呼出している.
デバッガで追いかけていると ::CreateFile で失敗している.errno は 13 .
::CreateFile を次の様に指定して呼出すと,ファイルの場合は問題ないがフォルダは NG .

HANDLE  hFile = ::CreateFile(file_name,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,     NULL) ;

フォルダの場合 FILE_FLAG_BACKUP_SEMANTICS が指定されていなければならないみたい.

HANDLE  hFile = ::CreateFile(file_name,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL) ;

time_t から FILETIME への変換は次の所.
https://learn.microsoft.com/ja-jp/windows/win32/sysinfo/converting-a-time-t-value-to-a-file-time
SetFTime.hxx

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

.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 が返っている.
::WritePrivateProfileString


最初現象を簡単には再現できなかったが,エクスプローラのサムネイル表示を行っていると発生しやすい.
また,今回のテスト用 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 が返ってくる.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.