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

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

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.101604 の関連記事表示

<< 0 >>
■101604  C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち -(2023/03/20(Mon) 16:00:53)
>

    分類:[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 が悪さをしてるのかなぁ・・・
    なにか心当たりや情報をご存知の方おられましたら、教えてくださいまし。
    よろしくお願いします。
親記事 /過去ログ177より / 関連記事表示
削除チェック/

■101605  Re[1]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち -(2023/03/20(Mon) 16:10:47)
>
    No101604 (ゆーち さん) に返信
    あ、そうそう。
    ずいぶん探したんですけど。
    PowerShell 呼び出さずにMoTW設定できるAPIがあれば、教えてください。
記事No.101604 のレス /過去ログ177より / 関連記事表示
削除チェック/

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

    下記の記事を見つけました。
    こちらでは検証していませんが、どうでしょう?
    https://goodlife.tech/posts/remove-ads.html#powershell
記事No.101604 のレス /過去ログ177より / 関連記事表示
削除チェック/

■101607  Re[3]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち -(2023/03/20(Mon) 17:26:41)
>
    No101606 (kiku さん) に返信
    > 下記の記事を見つけました。
    > こちらでは検証していませんが、どうでしょう?
    > https://goodlife.tech/posts/remove-ads.html#powershell
    返信ありがとうございます。
    MoTWを消す方法はあちこちにあるんですよねー。
    付ける方法を探してるんです。
    ちなみに ':Zone.' というファイルを作ろうとしても':'があるので失敗するんですよね・・・
記事No.101604 のレス /過去ログ177より / 関連記事表示
削除チェック/

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

    付ける方法なんですね。
    うーん、お力になれず、すみません。
記事No.101604 のレス /過去ログ177より / 関連記事表示
削除チェック/

■101611  Re[4]: C# MoTW を実行ファイルに設定できない。
□投稿者/ 魔界の仮面弁士 -(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 検索に問い合わせることで得られたコードです。
記事No.101604 のレス /過去ログ177より / 関連記事表示
削除チェック/

■101612  Re[5]: C# MoTW を実行ファイルに設定できない。
□投稿者/ 魔界の仮面弁士 -(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 回答はここで途切れている
記事No.101604 のレス /過去ログ177より / 関連記事表示
削除チェック/

■101620  Re[6]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち -(2023/03/21(Tue) 08:34:14)
>
    No101612 (魔界の仮面弁士 さん) に返信
    ご返答ありがとうございます。
    「デバイスパス指定子」初めて知りました!
    やってみます。
    (プロジェクトが多すぎて、.NET 4.6 から .NET 4.6.2 に上げるの、面倒ですがw)
    Bing Chat 使ったことないです。
    Chat GPT さんはウソばっかり教えてくれて一日つぶしてしまいましたw
記事No.101604 のレス /過去ログ177より / 関連記事表示
削除チェック/

■101621  Re[7]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち -(2023/03/21(Tue) 10:01:37)
>
    本件、勘違いでした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 するコードを書くことにします。
    と、いうことで、なさけない自己解決でしたが、クローズいたします。
    今後ともよろしくお願いします。


    ほんと相談すると、解決しやすいですよね。
記事No.101604 のレス / END /過去ログ177より / 関連記事表示
削除チェック/

■101626  Re[8]: C# MoTW を実行ファイルに設定できない。
□投稿者/ 魔界の仮面弁士 -(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 を投げる仕様を廃止
記事No.101604 のレス / END /過去ログ177より / 関連記事表示
削除チェック/

■101642  Re[9]: C# MoTW を実行ファイルに設定できない。
□投稿者/ ゆーち -(2023/03/23(Thu) 09:52:18)
>
    No101626 (魔界の仮面弁士 さん) に返信
    >>ちなみに、すべてのプロジェクトを .NET 4.6.2 に変更して Bing Chat が導いた
    >> new FileStream($@"\\?\{filePath}:Zone.Identifier", FileMode.Create)
    >>を実行したら、無効な文字だって怒られましたw
    >
    > んんん? 一応、確認してから投稿したのですけれどね。
    > そちらの環境で例外が発生したときの StackTrace を見せてもらえますか?

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

    ちょっとPowerShellに苦戦中なので後回しになるかも、です。
記事No.101604 のレス /過去ログ177より / 関連記事表示
削除チェック/

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

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


記事No.101604 のレス / END /過去ログ177より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -