C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[10]: C# MoTW を実行ファイルに設定できない。


(過去ログ 177 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■101604 / inTopicNo.1)  C# MoTW を実行ファイルに設定できない。
  
□投稿者/ ゆーち (1回)-(2023/03/20(Mon) 16:00:53)
ゆーち さんの Web サイト

分類:[C#] 

お久しぶりのゆーちです。
C#でファイルのMoTW(Mark of The Web)を設定するプログラムを書いてます。
具体的には Outlook 用の Addin ソフトです。
中身は PowerShell にコマンド投げているだけです。

// "system.management.automation.dll.10.0.10586.nupkg" からインストールした System.Management.Automation を使用してます。
using System.Management.Automation;

string format = "Set-Content -Path \"{0}\" -Stream Zone.Identifier -Encoding oem -NoNewline -Value \"[ZoneTransfer]`r`nZoneId=3\"";
string cmd_line = string.Format(format, filePath);
using (var invoker = new RunspaceInvoke())
{
    Collection<PSObject> results = invoker.Invoke(cmd_line, new object[] { });
    foreach (PSObject result in results)
    {
    }
}

このコードで、xlsx ファイルや pptx ファイルなどにはちゃんと MoTW が付加されるのですが。
bat, exe などの実行ファイルでは、エラーや例外もなくMoTWが付加されない現象で悩んでおります。

PowerShell のコンソールで同じコマンドを投げると、ちゃんと設定できちゃうんです。

string set_policy = "Set-ExecutionPolicy -Scope CurrentUser RemoteSigned";
こんなコードでPowerShellを呼び出し、ポリシーを変更したりもしましたが、同様です。

ちなみに、Process.Start() では機能しなかったので System.Management.Automation.RunspaceInvoke()を使いました。

Outlook が悪さをしてるのかなぁ・・・
なにか心当たりや情報をご存知の方おられましたら、教えてくださいまし。
よろしくお願いします。

引用返信 編集キー/
■101605 / inTopicNo.2)  Re[1]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち (2回)-(2023/03/20(Mon) 16:10:47)
ゆーち さんの Web サイト
No101604 (ゆーち さん) に返信
あ、そうそう。
ずいぶん探したんですけど。
PowerShell 呼び出さずにMoTW設定できるAPIがあれば、教えてください。

引用返信 編集キー/
■101606 / inTopicNo.3)  Re[2]: C# MoTW を実行ファイルに設定できない。
□投稿者/ kiku (332回)-(2023/03/20(Mon) 17:06:11)
No101605 (ゆーち さん) に返信
> ■No101604 (ゆーち さん) に返信
> あ、そうそう。
> ずいぶん探したんですけど。
> PowerShell 呼び出さずにMoTW設定できるAPIがあれば、教えてください。

下記の記事を見つけました。
こちらでは検証していませんが、どうでしょう?
https://goodlife.tech/posts/remove-ads.html#powershell
引用返信 編集キー/
■101607 / inTopicNo.4)  Re[3]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち (3回)-(2023/03/20(Mon) 17:26:41)
ゆーち さんの Web サイト
No101606 (kiku さん) に返信
> 下記の記事を見つけました。
> こちらでは検証していませんが、どうでしょう?
> https://goodlife.tech/posts/remove-ads.html#powershell
返信ありがとうございます。
MoTWを消す方法はあちこちにあるんですよねー。
付ける方法を探してるんです。
ちなみに ':Zone.' というファイルを作ろうとしても':'があるので失敗するんですよね・・・

引用返信 編集キー/
■101608 / inTopicNo.5)  Re[4]: C# MoTW を実行ファイルに設定できない。
□投稿者/ kiku (333回)-(2023/03/20(Mon) 17:47:10)
No101607 (ゆーち さん) に返信
> ■No101606 (kiku さん) に返信
> MoTWを消す方法はあちこちにあるんですよねー。
> 付ける方法を探してるんです。
> ちなみに ':Zone.' というファイルを作ろうとしても':'があるので失敗するんですよね・・・

付ける方法なんですね。
うーん、お力になれず、すみません。
引用返信 編集キー/
■101611 / inTopicNo.6)  Re[4]: C# MoTW を実行ファイルに設定できない。
□投稿者/ 魔界の仮面弁士 (3596回)-(2023/03/20(Mon) 18:50:45)
No101607 (ゆーち さん) に返信
> ちなみに ':Zone.' というファイルを作ろうとしても':'があるので失敗するんですよね・・・

『デバイスパス指定子』で作成してみてください。
(.NET Frmework の場合は 4.6.2 以降。.NET の場合は .NET Core を含む全バージョンで利用可能)
https://learn.microsoft.com/ja-jp/dotnet/standard/io/file-path-formats


string filePath = @"C:\Folder\sample.html";
string zoneIdentifierValue = "[ZoneTransfer]\r\nZoneId=3";
using (FileStream fs = new FileStream($@"\\?\{filePath}:Zone.Identifier", FileMode.Create))
{
  byte[] bytes = Encoding.ASCII.GetBytes(zoneIdentifierValue);
  fs.Write(bytes, 0, bytes.Length);
}


ちなみにこのコードは、『C# で Mark of The Web を付与する方法』を
Bing Chat 検索に問い合わせることで得られたコードです。
引用返信 編集キー/
■101612 / inTopicNo.7)  Re[5]: C# MoTW を実行ファイルに設定できない。
□投稿者/ 魔界の仮面弁士 (3597回)-(2023/03/20(Mon) 19:00:02)
2023/03/20(Mon) 19:08:10 編集(投稿者)

No101611 (魔界の仮面弁士) に追記
> ちなみにこのコードは、『C# で Mark of The Web を付与する方法』を
> Bing Chat 検索に問い合わせることで得られたコードです。

同じアカウントでも、教えてくれたり、教えてくれなかったりするようで、
Bing さんはとても気まぐれなようです。
https://www.vb-user.net/junk/replySamples/2023.03.20.18.58/MarkOfTheWeb.png


API による実装例も教えてくれそうだったのだけれど、
途中で回答が打ち切られてしまいました。

---->
申し訳ありません。私の回答が不十分でした。.NET Framework 4.8.1 で使用する場合、以下のコードを使用して、Mark of the Web を付与することができます。

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace MarkOfTheWeb
{
class Program
{
static void Main(string[] args)
{
string filePath = @"C:\Users\UserName\Downloads\file.html";
string zoneIdentifier = "Zone.Identifier";
string zoneIdentifierValue = "3";

// Set the Mark of the Web
SetZoneIdentifier(filePath, zoneIdentifier, zoneIdentifierValue);
}

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool DeleteFile(string lpFileName);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool SetFileAttributes(string lpFileName, uint dwFileAttributes);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, uint dwFlags);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint DeleteUrlCacheEntry(string lpszUrlName);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetSetFeatureEnabled(uint FeatureEntry, uint dwFlags, bool fEnable);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetIsFeatureEnabled(uint FeatureEntry, uint dwFlags);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint UrlMkSetSessionOption(uint dwOption, IntPtr pBuffer, uint dwBufferLength, uint dwReserved);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint UrlMkGetSessionOption(uint dwOption, IntPtr pBuffer, uint dwBufferLength, out uint pdwBufferLength, uint dwReserved);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetSetZoneMapping(uint dwZone, string lpszPattern, uint dwFlags);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetGetZoneMapping(uint dwZone, string lpszPattern, out uint pdwFlags);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetCreateZoneManager(IntPtr pPolicy, out IntPtr ppZoneMgr, uint dwReserved);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetCreateSecurityManager(IntPtr pPolicy, out IntPtr ppSecMgr, uint dwReserved);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetCombineUrl(string pwzBaseUrl, string pwzRelativeUrl, uint dwCombineFlags, IntPtr pszResult, uint cchResult, out uint pcchResult, uint dwReserved);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetParseUrl(string pwzUrl, uint ParseAction, uint dwFlags, IntPtr pszResult, uint cchResult, out uint pcchResult, uint dwReserved);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetCompareUrl(string pwzUrl1, string pwzUrl2, uint dwFlags);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetGetSecurityUrl(string pwzUrl, out IntPtr ppwzSecUrl, uint dwReserved);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetGetSessionOption(uint dwOption, IntPtr pBuffer, uint dwBufferLength, out uint pdwBufferLength, uint dwReserved);

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint CoInternetSetSessionOption(uint dwOption, IntPtr pBuffer, uint dwBufferLength
<----
Bing 回答はここで途切れている
引用返信 編集キー/
■101620 / inTopicNo.8)  Re[6]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち (5回)-(2023/03/21(Tue) 08:34:14)
ゆーち さんの Web サイト
No101612 (魔界の仮面弁士 さん) に返信
ご返答ありがとうございます。
「デバイスパス指定子」初めて知りました!
やってみます。
(プロジェクトが多すぎて、.NET 4.6 から .NET 4.6.2 に上げるの、面倒ですがw)
Bing Chat 使ったことないです。
Chat GPT さんはウソばっかり教えてくれて一日つぶしてしまいましたw
引用返信 編集キー/
■101621 / inTopicNo.9)  Re[7]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち (6回)-(2023/03/21(Tue) 10:01:37)
ゆーち さんの Web サイト
本件、勘違いでしたw
実行ファイルだけ MoTW 付かないって勘違いしてましたが、実際はちゃんとついていて、その後に実行してる
Process.Start(filename);
がMoTWを無視して実行するし、MoTWを消してしまう動きをしてました。(大汗;

Process.Startでpowershellを実行してもできない、って書いていたのも勘違いで、以下のような記述でMoTW付加できました。
string arg_format = "-ExecutionPolicy ByPass Set-Content -Path \"{0}\" -Stream Zone.Identifier -Encoding oem -NoNewline -Value \"[ZoneTransfer]`r`nZoneId=3\"";
var psinfo = new ProcessStartInfo();
psinfo.FileName = "powershell";
psinfo.UseShellExecute = true;
psinfo.Arguments = string.Format(arg_format, filePath); ;
psinfo.CreateNoWindow = true;
psinfo.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(psinfo);

ちなみに、すべてのプロジェクトを .NET 4.6.2 に変更して Being Chat が導いた
new FileStream($@"\\?\{filePath}:Zone.Identifier", FileMode.Create)
を実行したら、無効な文字だって怒られましたw

Process.Start で MoTW付きの実行ファイルをちゃんと警告させるためには、Win32 API の ShellExecuteEx で SEE_MASK_NOZONECHECKS がセットされない世界で実行させればいいので、めんどくさいけど dll inport するコードを書くことにします。
と、いうことで、なさけない自己解決でしたが、クローズいたします。
今後ともよろしくお願いします。


ほんと相談すると、解決しやすいですよね。
解決済み
引用返信 編集キー/
■101626 / inTopicNo.10)  Re[8]: C# MoTW を実行ファイルに設定できない。
□投稿者/ 魔界の仮面弁士 (3601回)-(2023/03/21(Tue) 21:22:22)
2023/03/21(Tue) 23:40:21 編集(投稿者)

No101621 (ゆーち さん) に返信
> ちなみに、すべてのプロジェクトを .NET 4.6.2 に変更して Bing Chat が導いた
> new FileStream($@"\\?\{filePath}:Zone.Identifier", FileMode.Create)
> を実行したら、無効な文字だって怒られましたw

んんん? 一応、確認してから投稿したのですけれどね。
そちらの環境で例外が発生したときの StackTrace を見せてもらえますか?

手元の環境で No101611 のコードを実行したところ、.NET Framework 4.6.1 では
 『System.ArgumentException: パスに無効な文字が含まれています。』
になりますが、4.6.2 / 4.7 / 4.7.1 / 4.7.2 / 4.8 / 4.8.1 では期待通りに付与されています。
.NET Core 系列も、少なくとも 2.1 以降で動作することを確認済み。


4.6.2 というターゲットに間違いが無かったとすれば、設定ファイルにて
意図的に UseLegacyPathHandling スイッチを true に変更していたとかですかね…?
https://learn.microsoft.com/ja-jp/dotnet/framework/migration-guide/mitigation-path-normalization


なお、.NET Framework 4.6.1 と 4.6.2 のソースコードを比較してみたところ、
4.6.1 → 4.6.2 の段階で、FileStream のパスチェック処理に下記の仕様変更が追加されていました。
https://referencesource.microsoft.com/download.html

(1) パスの最大長を決める際に、BlockLongPaths スイッチの判定を追加
 
(2) "\\.\" で始まるパスを、従来は無条件で ArgumentException 例外として拒絶していたが
 その拒絶処理が UseLegacyPathHandling スイッチ判定でスキップされるようにした
 
(3) パスの先頭 2 文字を切り捨てた後の位置に ':' があった場合に ArgumentException を投げる仕様を廃止
解決済み
引用返信 編集キー/
■101642 / inTopicNo.11)  Re[9]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち (7回)-(2023/03/23(Thu) 09:52:18)
ゆーち さんの Web サイト
No101626 (魔界の仮面弁士 さん) に返信
>>ちなみに、すべてのプロジェクトを .NET 4.6.2 に変更して Bing Chat が導いた
>> new FileStream($@"\\?\{filePath}:Zone.Identifier", FileMode.Create)
>>を実行したら、無効な文字だって怒られましたw
>
> んんん? 一応、確認してから投稿したのですけれどね。
> そちらの環境で例外が発生したときの StackTrace を見せてもらえますか?

情報ありがとうございます。
あれれ?
確かにすべてを4.6.2にしてから実行したんですけどねー。
もう一度試してみてからエラー出たら報告いたします。(出なくても報告いたします)

ちょっとPowerShellに苦戦中なので後回しになるかも、です。
引用返信 編集キー/
■101646 / inTopicNo.12)  Re[10]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち (8回)-(2023/03/23(Thu) 14:13:24)
ゆーち さんの Web サイト
No101626 (魔界の仮面弁士 さん) に返信
> あれれ?
> 確かにすべてを4.6.2にしてから実行したんですけどねー。
わかりました!
開発環境が、事情により VisualStudio 2015 なんですが、.NET4.6.2にしても .NET4.8に設定しても
new FileStream()で文字が使えない例外が出ます。
同じコードを VisualStudio 2019 で動作させると、ちゃんとファイルが作られることを確認しました。

ということで、これからたくさんのプロジェクトを VisualStudio 2022(まだインストールしてないw) に移行することにします・・・
とほほ。。。



解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -