【问题标题】:Passing args array to C# Main in Powershell script在 Powershell 脚本中将 args 数组传递给 C# Main
【发布时间】:2021-12-05 15:53:30
【问题描述】:

我有以下在 VS 中运行良好的 C# 代码。我是 Powershell 的新手,我很难将字符串数组传递给 Main 方法。 (我收到一个愚蠢的错误,说我的帖子主要是代码,所以我必须输入一些更无用的文本。那么,你所在的天气怎么样?

$code = @"
// omitted section

public class AsynchronousFtpUpLoader
{
    // Command line arguments are two strings:
    // 1. The url that is the name of the file being uploaded to the server.
    // 2. The name of the file on the local machine.
    //
    public static void Main(string[] args)
    {
        // Create a Uri instance with the specified URI string.
        // If the URI is not correctly formed, the Uri constructor
        // will throw an exception.
        ManualResetEvent waitObject;

        Uri target = new Uri(args[0]);
        string fileName = args[1];
        FtpState state = new FtpState();
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target);
        request.Method = WebRequestMethods.Ftp.UploadFile;

        // This example uses anonymous logon.
        // The request is anonymous by default; the credential does not have to be specified.
        // The example specifies the credential only to
        // control how actions are logged on the server.

        request.Credentials = new NetworkCredential("anonymous", "anonymous");

        // Store the request in the object that we pass into the
        // asynchronous operations.
        state.Request = request;
        state.FileName = fileName;

        // Get the event to wait on.
        waitObject = state.OperationComplete;

        // Asynchronously get the stream for the file contents.
        request.BeginGetRequestStream(
            new AsyncCallback(EndGetStreamCallback),
            state
        );

        // Block the current thread until all operations are complete.
        waitObject.WaitOne();

        // The operations either completed or threw an exception.
        if (state.OperationException != null)
        {
            throw state.OperationException;
        }
        else
        {
            Console.WriteLine("The operation completed - {0}", state.StatusDescription);
        }
    }
    private static void EndGetStreamCallback(IAsyncResult ar)
    {
        FtpState state = (FtpState)ar.AsyncState;

        Stream requestStream = null;
        // End the asynchronous call to get the request stream.
        try
        {
            requestStream = state.Request.EndGetRequestStream(ar);
            // Copy the file contents to the request stream.
            const int bufferLength = 2048;
            byte[] buffer = new byte[bufferLength];
            int count = 0;
            int readBytes = 0;
            FileStream stream = File.OpenRead(state.FileName);
            do
            {
                readBytes = stream.Read(buffer, 0, bufferLength);
                requestStream.Write(buffer, 0, readBytes);
                count += readBytes;
            }
            while (readBytes != 0);
            Console.WriteLine("Writing {0} bytes to the stream.", count);
            // IMPORTANT: Close the request stream before sending the request.
            requestStream.Close();
            // Asynchronously get the response to the upload request.
            state.Request.BeginGetResponse(
                new AsyncCallback(EndGetResponseCallback),
                state
            );
        }
        // Return exceptions to the main application thread.
        catch (Exception e)
        {
            Console.WriteLine("Could not get the request stream.");
            state.OperationException = e;
            state.OperationComplete.Set();
            return;
        }
    }

    // The EndGetResponseCallback method
    // completes a call to BeginGetResponse.
    private static void EndGetResponseCallback(IAsyncResult ar)
    {
        FtpState state = (FtpState)ar.AsyncState;
        FtpWebResponse response = null;
        try
        {
            response = (FtpWebResponse)state.Request.EndGetResponse(ar);
            response.Close();
            state.StatusDescription = response.StatusDescription;
            // Signal the main application thread that
            // the operation is complete.
            state.OperationComplete.Set();
        }
        // Return exceptions to the main application thread.
        catch (Exception e)
        {
            Console.WriteLine("Error getting response.");
            state.OperationException = e;
            state.OperationComplete.Set();
        }
    }
}
}
"@

Add-Type -TypeDefinition $code -Language CSharp 

$url = "ftp://anonymous-site.com/Uploads/cert_$env:username.pfx"
$sourceFilePath = $home + "\cert_$env:username.pfx"
$cmd = "[FTPFileUpload.AsynchronousFtpUpLoader]::Main(**Need help here**)"
iex $cmd

【问题讨论】:

  • 你不需要iex[FTPFileUpload.AsynchronousFtpUpLoader]::Main(@($url, $sourceFilePath)) 就可以了
  • 有义务。要传入的数组的形成把我扔了(;^D>

标签: c# powershell


【解决方案1】:

如 cmets 中所述,您不需要 Invoke-Expression(或其别名 iex)来调用该方法 - 您只需确保将字符串数组作为单个参数参数传递给它:

[FTPFileUpload.AsynchronousFtpUpLoader]::Main(@($url, $sourceFilePath))

如果您实际上并不打算将其作为独立的控制台应用程序启动,您不妨更改方法签名:

public static void UploadFile(Uri target, string fileName)
{
    ManualResetEvent waitObject;

    FtpState state = new FtpState();
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target);
    request.Method = WebRequestMethods.Ftp.UploadFile;

    // ... etc.
}

为了在 PowerShell 中获得更少尴尬的调用体验:

[FTPFileUpload.AsynchronousFtpUpLoader]::UploadFile($url, $sourceFilePath)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 2014-08-22
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多