この煩わしい添付ファイルの送受信を

はっきり言って面倒なやり方です。
手間を惜しまず、パスワード付き zip ファイル等を
送受信したい方達向けです。

大雑把に言うと
メール本文に復元アプリと添付ファイル（データ）を貼付、送信
受信側は、受け取った復元アプリを実行して添付ファイルを復元

Ｅメールに特定のファイルを添付すると
ウィルス対策により、メーラーに弾かれてしまったりとか
送信出来ても受信側が受け付けない場合が有ります。

外部の送信システムを使わないで送信したい場合は
添付ファイルを「文」としてメール本文に展開して
送信を行えば手間は掛かりますが可能になります。

ただし、ファイル容量は約６０ＭＢくらいが限界です。
※ バッチで使用する Certutil コマンドの作成限界

環境は、送受信ともに Windows で
PowerShell が 実行可能であることです。

受信側は、Windows でなくても
Base64 を 復号出来る環境なら何でも大丈夫です。

送信側の作業

　送信準備-① 作業フォルダを作成してメール本文生成アプリを保存
　送信準備-② 送信する添付ファイルを１つの書庫に纏めて作業フォルダへ保存
　送信準備-③ メール本文を生成して、クリップボードに送るアプリを実行
　送信処理-④ クリップボードの中身をメール本文に貼付後、送信

　　　　　　　＊ ＊ ＊ 送信するメール本文 ＊ ＊ ＊

　　　　　　　復元アプリ①のファイル名
　　　　　　　復元アプリ①の内容

　　　　　　　復元アプリ②のファイル名
　　　　　　　復元アプリ②の内容

　　　　　　　【変換された添付ファイル】

受信側の作業

　復元準備-① 作業フォルダを作成してメール本文の復元アプリを保存
　復元処理-② メール本文の添付ファイルを復元

　作業フォルダに添付ファイルが作成されます。

---------------------------------------------------------------------------------------------------

復元するコードは、こちらを利用しています。

Base64エンコードされたデータを 実体ファイルに一括復元する「マジック生成」バッチ (PowerShellによる高速処理版)
https://qiita.com/Yunixuma/items/1db1929775e34ac7ef01

--------------------------------------------------------------------------
送信側の作業

送信準備-① 作業フォルダを作成してメール本文生成アプリを保存

　　　　　　● 作業用のフォルダを作り
　　　　　　　 「②ファイルの選択を行うダイアログ.ps1」と
　　　　　　　 「③MSGBOX.VBS」と
　　　　　　　 「①メール本文を作成してクリップボードへ送る【★ダブルクリックするのはコレ★】.cmd」
　　　　　　　 を同じフォルダにファイルを作成して
　　　　　　　 文字コード を ANSI で保存する

送信準備-② 送信する添付ファイルを１つの書庫に纏めて作業フォルダへ保存

　　　　　　● 【 7zip ※ 拡張子 7z 】・【 zip 】・【 cab 】の
　　　　　　　 どれかを選択して書庫ファイルを作成し
　　　　　　　 送信準備-①で作成した作業用フォルダに保存する

　　　　　　※ 送信対象のファイルが一つで 7zip,zip,cab 形式のどれかなら
　　　　　　　 そのまま送信準備-①で作成した作業用フォルダに保存する

　　　　　　※ エンコード（符号化）でサイズが増加し
　　　　　　　 Certutil コマンドの作成限界が約６０ＭＢなので
　　　　　　　 受信側が受取可能ならば書庫は 7zip での高圧縮が望ましい

送信準備-③ メール本文を生成して、クリップボードに送るアプリを実行

　　　　　　● 「①メール本文を作成してクリップボードへ送る【★ダブルクリックするのはコレ★】.cmd」
　　　　　　　 を ダブルクリックで実行
　　　　　　　 ファイル選択ダイアログが表示されるので
　　　　　　　 送信準備-② で用意したファイルを選択する

　　　　　　　 例　添付.zip を 選択すると 添付.zip.TXT と メール本文.txt が
　　　　　　　　　送信準備-①で作成した作業用フォルダに作成される

　　　　　　　 ファイルの選択後、クリップボードに送る内容を選択
　　　　　　　 アプリとデータを送る場合は、【 はい 】をクリック
　　　　　　　 データのみを送る場合は、【 いいえ 】をクリック
　　　　　　　 クリップボードに送らない場合は、【 キャンセル 】をクリック

　　　　　　　 送信先の復元環境が用意されていない場合は
　　　　　　　 アプリとデータを送って下さい。


送信処理-④ クリップボードの中身をメール本文に貼付後、送信
![送信.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98441/f040c17d-cae3-d361-3e1d-0c02ed56e2e7.png)
　　　　　　※ Gmail の場合、サイズが大きいと処理落ちするので
　　　　　　　 メール本文.txt をメモ帳で開き
　　　　　　　 先頭のアプリの部分を一度貼付けてから
　　　　　　　 残りを貼付けると成功しました。

---------------------------------------------------------------------
受信側の作業

復元準備-① 作業フォルダを作成してメール本文の復元アプリを保存

　　　　　　● 作業用のフォルダを作り
　　　　　　　 「①復元するアプリ【★ダブルクリックするのはコレ★】.bat」 と
　　　　　　　 「②復元するアプリ.ps1」
　　　　　　　 を同じフォルダにファイルを作成して
　　　　　　　 文字コード を ANSI で保存する


復元処理-② メール本文の添付ファイルを復元

　　　　　　● メール本文の「↓↓↓↓↓↓↓↓」の
　　　　　　　 次の行から -----END CERTIFICATE-----
　　　　　　　 までをクリップボードにコピーする

　　　　　　　 下記の例の場合

　　　　　　　 「クリップボードに送る内容」

　　　　　　　 ↓↓↓↓↓↓↓↓
　　　　　　　 添付.zip
　　　　　　　 -----BEGIN CERTIFICATE-----
　　　　　　　 r2J3btgBxX2vYndu2AFQSwUGAAAAAAEAAQByAAAAXAAAAAAA
　　　　　　　 -----END CERTIFICATE-----

　　　　　　　 の 添付.zip から ４行を選択して、
　　　　　　　 右クリックメニューでコピーする
![メール本文コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98441/cf561df8-1725-1d0b-17e4-1217dbe0eba6.png)
　　　　　　● 「①復元するアプリ【★ダブルクリックするのはコレ★】.bat」 を ダブルクリックで実行
　　　　　　　  上記の例の場合、作業用のフォルダに 添付.zip が作成される


```bat:②ファイルの選択を行うダイアログ.ps1
Set-StrictMode -version Latest

#.NET Frameworkのダイアログ関連オブジェクトの取り込み
Add-Type -assemblyName System.Windows.Forms

#ファイル選択ダイアログのオブジェクト取得
$dialog   = New-Object System.Windows.Forms.OpenFileDialog

#タイトルの設定
$dialog.Title = "エンコードするファイルを選択して下さい"

#フィルタ条件の設定
$dialog.Filter = '圧縮ファイル|*.7z;*.cab;*.zip'

#デフォルト選択ディレクトリの設定
$dialog.InitialDirectory = '.'

if ($dialog.ShowDialog() -eq "OK") {
    '"' + $dialog.FileName + '"'
  } else {
    '未選択'
}

```
```bat:③MSGBOX.VBS
Option Explicit
REM ------------------------------------------------------
REM msgbox.vbs str1 , str2 [,mode]
REM     str1:表示するメッセージ
REM     num :表示するボタンの選択
REM     str2:メッセージボックスのタイトル
REM （動作）
REM メッセージボックスを表示し、クリックされたボタンを
REM 返します。
REM str1 中の 「crlf」という文字列は改行に変換します。
REM ･･･････････････････････････････････････････････････････
REM ボタンの表示選択と動作などの設定（ボタン表示や動作などの値を合計します。）
REM     0 [OK] ボタンのみを表示します。
REM     1 [OK] ボタンと [キャンセル] ボタンを表示します。
REM     2 [中止]、[再試行]、および [無視] の 3 つのボタンを表示します。
REM     3 [はい]、[いいえ]、および [キャンセル] の 3 つのボタンを表示します。
REM     4 [はい] ボタンと [いいえ] ボタンを表示します。
REM     5 [再試行] ボタンと [キャンセル] ボタンを表示します。
REM    16 警告メッセージ アイコンを表示します。
REM    32 問い合わせメッセージ アイコンを表示します。
REM    48 注意メッセージ アイコンを表示します。
REM    64 情報メッセージ アイコンを表示します。
REM     0 第 1 ボタンを標準ボタンにします。
REM   256 第 2 ボタンを標準ボタンにします。
REM   512 第 3 ボタンを標準ボタンにします。
REM   768 第 4 ボタンを標準ボタンにします。
REM     0 アプリケーション モーダルに設定します。
REM       メッセージ ボックスに応答するまで、現在選択中のアプリケーションの実行を継続できません。
REM  4096 システム モーダルに設定します。
REM       メッセージ ボックスに応答するまで、すべてのアプリケーションが中断されます。
REM ･･･････････････････････････････････････････････････････
REM 戻り値となる文字列
REM   ボタンの名前     -> respondの戻り値
REM     [OK]           -> Ok
REM     [キャンセル]   -> Cancel
REM     [中止]         -> Stop
REM     [再試行]       -> Retry
REM     [無視]         -> Ignore
REM     [はい]         -> Yes
REM     [いいえ]       -> No
REM ------------------------------------------------------
Dim args, arg(99), v, cnt
Dim str1, str2
Dim mode
Dim respond, eLevel
Dim CRLF
REM 改行符号を設定します。
CRLF = chr(13) & chr(10)
Set args = WScript.Arguments
cnt = 1
For Each v In args
    arg(cnt) = v
    cnt = cnt + 1
Next
REM 改行文字の置き換え
arg(1) = RepExAll (arg(1), "crlf", CRLF)
eLevel = 0
Select Case args.Count
    Case 0:    mode = 0: eLevel = 1
    Case 1:    mode = MsgBox (arg(1))
    Case 2:    mode = MsgBox (arg(1), arg(2))
    Case Else: mode = MsgBox (arg(1), arg(2), arg(3))
End Select
Select Case mode
    Case 0: respond = ""
    Case 1: respond = "Ok"
    Case 2: respond = "Cancel"
    Case 3: respond = "Stop"
    Case 4: respond = "Retry"
    Case 5: respond = "Ignore"
    Case 6: respond = "Yes"
    Case 7: respond = "No"
End Select
REM 結果の表示
WScript.Echo respond
WScript.Quit (eLevel)
REM ここからサブルーチン=========================================
REM 原稿文字列を正規文字列で検索し、一致する文字をすべて置換文字列に置き換えます。
REM s : 原文字列
REM t : 正規文字列
REM d : 置換文字列
Function RepExAll ( s , t , d )
    Dim regExpression, Matches                ' 変数を作成します。
    Set regExpression = New RegExp            ' 正規表現を作成します。
    regExpression.Pattern    = t              ' パターンを設定します。
    regExpression.IgnoreCase = True           ' 大文字と小文字を区別しないように設定します。
    regExpression.Global     = True           ' 文字列全体を検索するように設定します。
    RepExAll = regExpression.Replace(s , d)   ' 置換を実行します。
End Function

```
```bat:①メール本文を作成してクリップボードへ送る【★ダブルクリックするのはコレ★】.cmd
@echo off

rem /;
rem /; ★ メール本文を生成してクリップボードへ送る
rem /;    ◆ エンコード（符号化）する圧縮書庫をダイアログで選択 ※ cab形式 zip形式 7z形式
rem /;    ◆ エンコードのファイル名を生成
rem /;    ◆ 圧縮書庫をエンコード
rem /;    ◆ メール本文を生成
rem /;    ◆ 生成されたメール本文をクリップボードへ送る
rem /;

rem /;
rem /; ◆ エンコード（符号化）する圧縮書庫をダイアログで選択 ※ cab形式 zip形式 7z形式
rem /;

for /f "delims="                   %%0 in ('Powershell -NoProfile -ExecutionPolicy unrestricted -f "%~dp0②ファイルの選択を行うダイアログ.ps1"') do (
    if  not                       "%%0"=="未選択" (
        set               ARC_File=%%0
      ) else (
        msg               console "ファイルが未選択です。OK を クリックで終了します。"
        goto              :eof
    )
)

rem /;
rem /; ◆ エンコードのファイル名を生成
rem /;
rem /;    選択されたファイルの拡張子の後ろに .TXT を付加したファイル名を作成
rem /;
rem /;    ARC_File     "c:\test\添付.zip"
rem /;                       ↓
rem /;    ARC_File_TXT  c:\test\添付.zip.TXT
rem /;

for /f "delims=" %%0 in (%ARC_File%) do set                                    "ARC_File_TXT=%%~dpnx0.TXT"

rem /;
rem /; ◆ 圧縮書庫をエンコード
rem /;
rem /;    エンコード（符号化）前に作成するファイルを削除してから
rem /;    選択されたファイルを Base64 で エンコード（符号化）
rem /;
rem /;                 "c:\test\添付.zip" ⇒  "c:\test\添付.zip.TXT"
rem /;
rem /;    添付.zip                                   > 添付.zip.TXT
rem /;    -----BEGIN CERTIFICATE-----                > メール本文.txt
rem /;
rem /;    添付.zip.TXT
rem /;    添付.zip
rem /;    -----BEGIN CERTIFICATE-----
rem /;

for /f "delims=" %%0 in (%ARC_File%) do echo;%%~nx0>                          "%ARC_File_TXT%"
del /f /q                                            "%~dp0メール本文.txt" > nul 2> nul
certutil -encode         %ARC_File%                  "%~dp0メール本文.txt"
type                                                 "%~dp0メール本文.txt" >> "%ARC_File_TXT%"

rem /;
rem /; ◆ メール本文を生成
rem /;

(
echo;①復元するアプリ【ダブルクリックするのはコレ】.bat
echo;@ECHO OFF
echo;PowerShell -ExecutionPolicy RemoteSigned -STA -File "%%~dp0②復元するアプリ.ps1" %1 "nul"
echo;DEL  /f                                             "%%~dp0②復元するアプリ.log"
echo;EXIT /B
echo;
echo;--------------------------------------------------------------------------
echo;
echo;②復元するアプリ.ps1
echo;$Host.UI.RawUI.ForeGroundColor = "Green"
echo;Add-Type -Assembly System.Windows.Forms
echo;"############# B642FHT.ps1 ##############"
echo;"# Converting data sequence             #"
echo;"#            encoded in Base64         #"
echo;"#       to real files continuously     #"
echo;"# high-throughput script by PowerShell #"
echo;"#                                      #"
echo;"#   1st release: 2019-07-07            #"
echo;"#   Last update: 2019-07-25            #"
echo;"#   Author: Y. Kosaka                  #"
echo;"#   See the web for more information   #"
echo;"#   https://qiita.com/x-ia             #"
echo;"########################################"
echo;
echo;$filenameScript = ^(Get-ChildItem $MyInvocation.MyCommand.Path^).BaseName
echo;$dirPathScript = Split-Path $MyInvocation.MyCommand.Path -Parent
echo;$Host.UI.RawUI.WindowTitle = $filenameScript
echo;$extLog = ".log"
echo;$timePause = 1500
echo;
echo;
echo;function ChDirWork^($arg^) {
echo;  if ^(Test-Path $arg.Replace^('"', '')) {
echo;    ChDir $arg
echo;    [System.IO.Directory]::SetCurrentDirectory^(^(Get-Location -PSProvider FileSystem^).Path^)
echo;  }
echo;}
echo;
echo;function GetClip {
echo;  $strClip = [Windows.Forms.Clipboard]::GetText^(^)
echo;  return $strClip
echo;}
echo;
echo;function ViewClip^($strClip^) {
echo;  $numSizeClip = $strClip.Length
echo;  $numLineClip = 0
echo;  foreach^( $strLine in $strClip -split "`r`n" ^){
echo;    ++$numLineClip
echo;  }
echo;  Write-Host "`r`nRead $($numSizeClip.ToString("#,#")) chars ($($numLineClip.ToString("#,#")) lines) from the clipboard.`r`n"
echo;  return $numLineClip
echo;}
echo;
echo;function DivText^($strClip, $numLineClip, $filenameScript, $extLog^) {
echo;  $strOut = $null
echo;  $flagOut = 0
echo;  $numOut = 0
echo;  $numProgressNext = 0
echo;  $numLineProcessed = 0
echo;  foreach^( $strLine in $strClip -split "`r`n" ^){
echo;    if ^(^($strLine -like "``````*"^) -Or ^($strLine -like "---*"^)^) {
echo;      $flagOut +=1
echo;      if ^($flagOut -eq 1^) {
echo;        $fileOut = $strLinePrev
echo;      } elseif ^($flagOut -eq 2^) {
echo;        $err = DecodeB64 $strOut $fileOut
echo;        PutLog $err $fileOut $filenameScript $extLog
echo;        $numOut += 1
echo;        $strOut = $null
echo;        $flagOut = 0
echo;      }
echo;    } elseif ^($flagOut -eq 1^) {
echo;      $strOut += $strLine
echo;    } else {
echo;    $strLinePrev = $strLine
echo;    }
echo;    $numLineProcessed += 1
echo;    $numProgress = [Math]::Floor^(100 * $numLineProcessed / $numLineClip^);
echo;    if ^($numProgress -ge $numProgressNext^) {
echo;      Write-Progress -activity "Processing the text from clipboard" `
echo;      -status "$numProgress %% processed" `
echo;      -percentComplete $numProgress `
echo;      -CurrentOperation "$($numLineProcessed.ToString("#,#")) / $($numLineClip.ToString("#,#")) lines, $numOut files created."
echo;      $numProgressNext = $numProgress + 1
echo;    }
echo;  }
echo;}
echo;
echo;function DecodeB64^($strOut, $fileOut^) {
echo;  [System.IO.File]::WriteAllBytes^($fileOut, [Convert]::FromBase64String^($strOut^)^)
echo;  return $?
echo;}
echo;
echo;function PutLog^($err, $fileOut, $filenameScript, $extLog^) {
echo;  if ^("$err" -eq "True"^) {
echo;    $strResult = "Success"
echo;    Write-Host "Suceeded to create a file $fileOut."
echo;  } else {
echo;    $strResult = "Failure"
echo;    Write-Host "Failed. An error occured."
echo;  }
echo;  $timeStampNow = ^(Get-Date^).ToString^("yyyy-MM-dd HH:mm:ss.fff"^)
echo;  $fileLog = $filenameScript + $extLog
echo;  "$timeStampNow`t$filenameScript`t$strResult`t$fileOut" ^| `
echo;  Out-File $fileLog -Encoding Default -Append
echo;  $Host.UI.RawUI.WindowTitle = "$filenameScript $strResult"
echo;}
echo;
echo;function EoF^($timePause^) {
echo;  Start-Sleep -milliseconds $timePause
echo;}
echo;
echo;ChDirWork $Args[0]
echo;$strClip = GetClip
echo;$numLineClip = ViewClip $strClip
echo;DivText $strClip $numLineClip $filenameScript $extLog
echo;EoF $timePause
echo;
echo;--------------------------------------------------------------------------
echo;
echo;「クリップボードに送る内容」
echo;
echo;↓↓↓↓↓↓↓↓
)                     >  "%~dp0メール本文.txt"

type "%ARC_File_TXT%" >> "%~dp0メール本文.txt"

rem /;
rem /; ◆ 生成されたメール本文または添付ファイルをクリップボードへ送る
rem /;

for /f "usebackq tokens=* delims=" %%0 in (`call CSCRIPT //NOLOGO "%~dp0③MSGBOX.VBS" "★ クリップボードに送る内容を選択して下さいcrlfcrlf　 【 はい 】　　　　 アプリとデータcrlfcrlf　 【 いいえ 】　　　  データのみcrlfcrlf　 【 キャンセル 】　　送らないcrlfcrlf"    259 "クリップボード設定"`) do SET 答え=%%0
if      "%答え%"=="Yes"     type                     "%~dp0メール本文.txt" | clip
if      "%答え%"=="No"      type                     "%ARC_File_TXT%"      | clip

```