Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从C代码执行的Process.StandardInput或应用程序的编码问题_C#_.net_Encoding_Utf 8_Process - Fatal编程技术网

C# 从C代码执行的Process.StandardInput或应用程序的编码问题

C# 从C代码执行的Process.StandardInput或应用程序的编码问题,c#,.net,encoding,utf-8,process,C#,.net,Encoding,Utf 8,Process,我对进程的编码有问题。标准输入编码。我在Windows窗体应用程序中使用了一些进程,但输入应该是UTF-8Process.StandardInput.Encoding是只读的,因此我无法将其设置为UTF-8,并且它会使用Windows默认编码,这会破坏UTF-8中良好的本机字符。程序中使用两个进程:一个将输出写入文件,另一个读取。因为我可以将输出编码设置为UTF-8,所以该部分工作正常,但回读是我遇到问题的部分。我将包括我使用流程的部分 ProcessStartInfo info = new P

我对
进程的编码有问题。标准输入
编码。我在Windows窗体应用程序中使用了一些进程,但输入应该是UTF-8
Process.StandardInput.Encoding
是只读的,因此我无法将其设置为UTF-8,并且它会使用Windows默认编码,这会破坏UTF-8中良好的本机字符。程序中使用两个进程:一个将输出写入文件,另一个读取。因为我可以将输出编码设置为UTF-8,所以该部分工作正常,但回读是我遇到问题的部分。我将包括我使用流程的部分

ProcessStartInfo info = new ProcessStartInfo("mysql");
info.RedirectStandardInput = true;
info.RedirectStandardOutput = false;
info.Arguments = mysqldumpstring;
info.UseShellExecute = false;
info.CreateNoWindow = true;
Process p1 = new Process();
p1.StartInfo = info;
p1.Start();
string res = file.ReadToEnd();
file.Close();

// where encoding should be Encoding.UTF8;
MessageBox.Show(p1.StandardInput.Encoding.EncodingName); 

p1.StandardInput.WriteLine(res);
p1.Close(); 
Console.InputEncoding = Encoding.UTF8;

现在可以工作了。将我的应用程序输出类型设置为console应用程序,并设法在窗体出现之前隐藏console窗口。只有当程序运行时,控制台窗口弹出并隐藏,它才能像正常一样工作

static class Program
{
    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(int dwProcessId);
    private const int ATTACH_PARENT_PROCESS = -1;

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool SetConsoleCP(
         uint wCodePageID
         );

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern uint GetConsoleCP();

    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Console.Title = "Stok";
        // redirect console output to parent process;
        // must be before any calls to Console.WriteLine()
        AttachConsole(ATTACH_PARENT_PROCESS);
        System.Console.InputEncoding = Encoding.UTF8;

        IntPtr hWnd = FindWindow(null, "Stok"); //put your console window caption here

        if (hWnd != IntPtr.Zero)
        {
            //Hide the window
            ShowWindow(hWnd, 0); // 0 = SW_HIDE
        }

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
静态类程序
{
[DllImport(“kernel32.dll”)]
静态外部布尔附件控制台(int dwProcessId);
private const int ATTACH_PARENT_PROCESS=-1;
[DllImport(“kernel32.dll”,SetLastError=true)]
公共静态外部bool SetConsoleCP(
uint wCodePageID
);
[DllImport(“kernel32.dll”,SetLastError=true)]
公共静态外部单元getConsoleP();
[DllImport(“user32.dll”)]
公共静态外部IntPtr FindWindow(字符串lpClassName,字符串lpWindowName);
[DllImport(“user32.dll”)]
静态外部布尔显示窗口(IntPtr hWnd、int nCmdShow);
/// 
///应用程序的主要入口点。
/// 
[状态线程]
静态void Main()
{
Console.Title=“Stok”;
//将控制台输出重定向到父进程;
//必须在调用Console.WriteLine()之前
附加控制台(附加父进程);
System.Console.InputEncoding=Encoding.UTF8;
IntPtr hWnd=FindWindow(null,“Stok”);//将控制台窗口标题放在这里
如果(hWnd!=IntPtr.Zero)
{
//把窗户藏起来
ShowWindow(hWnd,0);//0=SW\u隐藏
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(新Form1());
}
}

使用以下一种方式创建的StreamWriter(而不是StandardInput)可获得所需的结果:

StreamWriter utf8Writer = new StreamWriter(proc.StandardInput.BaseStream, Encoding.UTF8);
utf8Writer.Write(...);
utf8Writer.Close();

另一种解决方案是在创建流程之前设置

ProcessStartInfo info = new ProcessStartInfo("mysql");
info.RedirectStandardInput = true;
info.RedirectStandardOutput = false;
info.Arguments = mysqldumpstring;
info.UseShellExecute = false;
info.CreateNoWindow = true;
Process p1 = new Process();
p1.StartInfo = info;
p1.Start();
string res = file.ReadToEnd();
file.Close();

// where encoding should be Encoding.UTF8;
MessageBox.Show(p1.StandardInput.Encoding.EncodingName); 

p1.StandardInput.WriteLine(res);
p1.Close(); 
Console.InputEncoding = Encoding.UTF8;

我刚刚遇到这个问题,无法使用
Console.inpunecoding
技术,因为它似乎只在控制台应用程序中工作

因此,我尝试了Victor的答案,但是我遇到了与评论员MvanGeest相同的问题,其中BOM仍在添加中。过了一会儿,我发现可以创建一个禁用BOM的新UTF8Encoding实例,这样做可以停止编写BOM。下面是Victor示例的修改版本,显示了更改

StreamWriter utf8Writer = new StreamWriter(proc.StandardInput.BaseStream, new UTF8Encoding(false));
utf8Writer.Write(...);
utf8Writer.Close();

希望这能节省一些时间。

我在将StandardInput发送到“cmd.exe”时遇到了各种编码问题。我正在生成一个批处理文件,该文件使用mklink和各种非ASCII文件名

我得出的结论是,在UTF8 StreamWriter中包装StandardInput.BaseStream无法正常工作(至少在使用cmd.exe和我拥有的文件名时)。更改编码修复了一些问题,但破坏了其他问题

这就是我的工作原理:

  • 将批处理文件以UTF8 no BOM的形式保存到临时文件中,如下所示:file.writealText(“temp.bat”、batchText、新UTF8Encoding(false))
  • 将StandardOutputEncoding和StandardErrorEncoding设置为Encoding.UTF8
  • 发送至标准输入两行:“chcp 65001”+Environment.NewLine+“temp.bat”+Environment.NewLine
这仅适用于“cmd.exe”,命令“chcp 65001”告诉它使用UTF8


忘记标准输入编码吧,发送的两行是ASCII

谢谢。很好地解决了这个问题。请注意,它也适用于StandardOutput。不幸的是,这似乎不再有效-UTF16(!)BOM(FF FE)仍在数据之前写入。尼克的解决方案似乎是目前唯一丑陋的解决方案。