お世話になります。
PowerShellのbat起動ワンライナーにおける、埋め込みC#コードについて
ReferencedAssemblies オプションによる.Net向けDxLibライブラリ(dll)の読み込みで分からないことがあり質問しました。
バッチファイルのディレクトリに存在する「DxLibDotNet.dll」を呼び出した際に、
下記のようなエラーで、実行時にエラーしてしまいます。
※「DxLib.dll」「DxLib_x64.dll」も同ディレクトリに配置しています。
コード:
"1" 個の引数を指定して "Run" を呼び出し中に例外が発生しました: "ファイルまたはアセンブリ 'DxLibDotNet, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。"
コード側の問題かもしれませんが、
正常に、読み込む方法は無いでしょうか?
コードは、下記の通りです。
► スポイラーを表示
※エラーの再現用に抜粋したものです
環境:Windows10
コード:
@setlocal enabledelayedexpansion&set a=%*&(if defined a set a=!a:"=\"!&set a=!a:'=''!)&@start /min powershell -windowstyle hidden -sta /c $i=$input;iex ('$i^|^&{$PSCommandPath=\"%~f0\";$PSScriptRoot=\"%~dp0";#'+(${%~f0}^|Out-String)+'} '+('!a!'-replace'[$(),;@`{}]','`$0'))&exit/b
<#
・C#挙動確認用テンプレート
バッチファイルのみでC#開発を行う検証
#>
<#
ユーザー向け定義
#>
# 管理者権限
set-variable -option readonly -name ENABLE_ADMIN -value "false"
<#
スクリプト向け定義
#>
# アプリケーション名
set-variable -option readonly -name APP_NAME -value "C#挙動確認用テンプレート"
# フォームサイズ
set-variable -option readonly -name FORM_SIZE -value "640, 480"
set-variable -option readonly -name FORM_MIN_SIZE -value $FORM_SIZE
# DLLパス
set-variable -option readonly -name DLL_PATH_DXLIBDOTNET -value (Join-Path $PSScriptRoot "DxLibDotNet.dll")
# アプリケーションファイル名
set-variable -option readonly -name APP_FILE_NAME -value (Split-Path -Leaf $PSCommandPath)
set-variable -option readonly -name APP_FILE_BASE_NAME -value (Get-Item $APP_FILE_NAME).BaseName
#<# -------------------------------------------------------------------------------------------------------
Add-Type -IgnoreWarnings -Language CSharpVersion3 `
-ReferencedAssemblies (
# "System",
"System.Drawing",
"System.Windows.Forms",
$DLL_PATH_DXLIBDOTNET
) `
-TypeDefinition @"
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Principal;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using DxLibDLL;
public class MainForm : Form
{
public MainForm()
{
if (Admin.IsAdmin) {
this.Text = "$APP_NAME (管理者)";
}
else {
this.Text = "$APP_NAME";
}
this.FormBorderStyle = FormBorderStyle.Sizable;
this.Size = new Size($FORM_SIZE);
this.MinimumSize = new Size($FORM_MIN_SIZE);
this.FormClosed += MainForm_FormClosed;
DX.DxLib_Init();
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
DX.DxLib_End();
}
public void MainLoop()
{
}
}
public static class Admin
{
public static bool RestartAdmin(Object[] Args)
{
if (IsAdmin) {
return true;
}
var psi = new ProcessStartInfo("cmd", string.Format("/C \"\"{0}\" {1}\"",
@"$PSCommandPath",
string.Join(" ", Args
.Select(x => string.Format("\"{0}\"", x))
.ToArray())));
psi.Verb = "runas";
try {
Process.Start(psi);
}
catch (System.ComponentModel.Win32Exception){}
return false;
}
public static bool IsAdmin
{
get {
var principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
}
public static class Entry
{
[STAThread]
public static void Run(Object[] Args)
{
#if $ENABLE_ADMIN
if (Admin.RestartAdmin(Args)) {
MainProc(Args);
}
#else
MainProc(Args);
#endif
}
static void MainProc(Object[] Args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new MainForm();
form.Show();
while( form.Created )
{
form.MainLoop();
Application.DoEvents();
}
}
}
"@
# -------------------------------------------------------------------------------------------------------#>
# アセンブリ読み込み
#Add-Type -Assembly System.Windows.Forms
try
{
# 実行
[Entry]::Run($args)
}
catch [Exception] {
# 例外
PowerShell -WindowStyle Normal -Command Exit
Write-Host $error
Write-Host "`n終了するには、任意のキーを押してください." -NoNewLine
[Console]::ReadKey() | Out-Null
}
finally {
# プロセス解放
[GC]::Collect()
}
PowerShellは興味本位で触っている程度なので、初心者です。
プログラム全般では、C++の入門書レベルが多少わかる程度です。
bat起動ワンライナーで、動作させることを目的としているので
「C# Interactiveでやれば良い」等の開発環境を変更するような
回答は、お控え頂けると助かります。
以上、よろしくお願い致します。