private async void ServerThread() { while (!Cancellation.IsCancellationRequested) { try { using (NamedPipeServerStream pipeServer = new NamedPipeServerStream("ConvertZZ_Pipe", PipeDirection.InOut)) { await pipeServer.WaitForConnectionAsync(Cancellation.Token); Console.WriteLine("Client connected."); StreamString ss = new StreamString(pipeServer); string[] Args = (await ss.ReadStringAsync()).Split('|'); Window_DialogHost window_DialogHost = new Window_DialogHost(Args[0] == "/file" ? Enums.Enum_Mode.Mode.File_FileName : Enums.Enum_Mode.Mode.AutioTag, Args.Skip(1).ToArray()); window_DialogHost.Show(); await ss.WriteStringAsync("ACK"); pipeServer.WaitForPipeDrain(); pipeServer.Close(); } } catch (IOException e) { Console.WriteLine("ERROR: {0}", e.Message); } } }
private async void ReceiveLoopAsync(CancellationToken token) { try { while (!token.IsCancellationRequested && IsAlive) { string s = await _streamString.ReadStringAsync(token).ConfigureAwait(false); OnMessage(s); } } catch (ArgumentException) { _threwException = true; OnClosed(); } catch (Exception ex) { Util.TraceException("Error receiving data from pipe.", ex); _threwException = true; OnClosed(); } }
private async void ReceiveLoop(CancellationToken token) { try { while (!token.IsCancellationRequested && IsOpen) { string s = await _ss.ReadStringAsync(token); IpcMessage msg = null; if (s == null) { throw new Exception("Got null string from server."); } try { msg = JsonConvert.DeserializeObject <IpcMessage>(s, new DictionaryDeserializer()); } catch (JsonException ex) { Util.TraceException("Error parsing incoming JSON", ex); } if (msg != null) { OnMessageReceived(msg); } } } catch (ArgumentException) { OnClosed(); } catch (Exception ex) { Util.TraceException("Error receiving data from pipe.", ex); OnError(ex); } }
private async void Application_Startup(object sender, StartupEventArgs e) { App.Reload(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ConvertZZ.json")); ShutdownMode = ShutdownMode.OnMainWindowClose; if (e.Args.Length > 0) { if (e.Args[0] == "/file" || e.Args[0] == "/audio") { var ps = Process.GetProcessesByName("ConvertZZ"); IntPtr hwndTest = IntPtr.Zero; if (ps.Length > 1) { long mini = ps.ToList().Min(x => x.StartTime.Ticks); hwndTest = ps.Where(x => x.StartTime.Ticks == mini).First().Handle; } else { ShowUI(); Window_DialogHost window_DialogHost = new Window_DialogHost(e.Args[0] == "/file" ? Enums.Enum_Mode.Mode.File_FileName : Enums.Enum_Mode.Mode.AutioTag, e.Args.Skip(1).ToArray()); window_DialogHost.Show(); return; } try { using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "ConvertZZ_Pipe", PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { Console.WriteLine("Connecting to server...\n"); await pipeClient.ConnectAsync(1000); StreamString ss = new StreamString(pipeClient); // The client security token is sent with the first write. // Send the name of the file whose contents are returned // by the server. await ss.WriteStringAsync(string.Join("|", e.Args)); pipeClient.WaitForPipeDrain(); string returns = await ss.ReadStringAsync(); pipeClient.Close(); }; } catch { } Shutdown(1); return; } Encoding[] encoding = new Encoding[2]; bool EncodingSetted = false; int ToChinese = 0; string path1 = null, path2 = null; Regex Regex_path1 = null; int VocabularyCorrection = -1; Enum_Engine Engine = App.Settings.Engine; for (int i = 0; i < e.Args.Length; i++) { switch (e.Args[i]) { case "/i:ule": encoding[0] = Encoding.Unicode; EncodingSetted = true; break; case "/i:ube": encoding[0] = Encoding.BigEndianUnicode; EncodingSetted = true; break; case "/i:utf8": encoding[0] = Encoding.UTF8; EncodingSetted = true; break; case "/i:gbk": encoding[0] = Encoding.GetEncoding("GBK"); EncodingSetted = true; break; case "/i:big5": encoding[0] = Encoding.GetEncoding("Big5"); EncodingSetted = true; break; case "/o:ule": encoding[1] = Encoding.Unicode; break; case "/o:ube": encoding[1] = Encoding.BigEndianUnicode; break; case "/o:utf8": encoding[1] = Encoding.UTF8; break; case "/o:gbk": encoding[1] = Encoding.GetEncoding("GBK"); break; case "/o:big5": encoding[1] = Encoding.GetEncoding("Big5"); break; case "/f:t": ToChinese = 1; break; case "/f:s": ToChinese = 2; break; case "/f:d": ToChinese = 0; break; case "/d:t": VocabularyCorrection = 1; break; case "/d:f": VocabularyCorrection = 0; break; case "/d:s": VocabularyCorrection = -1; break; case "/e:l": Engine = Enum_Engine.Local; break; case "/e:f": Engine = Enum_Engine.Fanhuaji; break; default: if (path1 == null) { path1 = e.Args[i]; Regex_path1 = new Regex($"{Regex.Replace(path1.Replace("*", "(.*?)").Replace("\\", "\\\\"), "[\\/]", "[\\\\/]")}$"); } else { path2 = e.Args[i]; } break; } } if (VocabularyCorrection == 1 || (VocabularyCorrection == -1 && App.Settings.VocabularyCorrection)) { await LoadDictionary(Engine); } string s = ""; List <string> file = new List <string>(); bool ModeIsOneFile = true; if (path1.Contains("*")) { ModeIsOneFile = false; Directory.GetFiles(Path.GetDirectoryName(path1), Path.GetFileName(path1)).ToList().ForEach(x => file.Add(x) ); } else { if (File.Exists(path1)) { file.Add(path1); } else { Console.WriteLine($"檔案\"{path1}\" 不存在"); Console.Read(); Shutdown(1); return; } } if (encoding[1] == null || string.IsNullOrWhiteSpace(path1)) { Console.WriteLine("參數錯誤(目標編碼為空或來源檔案路徑未填寫)"); Console.Read(); Shutdown(1); return; } if (string.IsNullOrWhiteSpace(path2)) { path2 = path1; } if (path1.Count(x => x == '*') != path2.Count(x => x == '*') && path2.Contains("*")) { Console.WriteLine("參數錯誤(輸出路徑的萬用字元術與輸入路徑不同)"); Console.Read(); Shutdown(1); return; } if (path1.Contains("*") && !path2.Contains("*") && File.Exists(path2)) { Console.WriteLine("參數錯誤(輸入路徑具有萬用字元,但輸出路徑卻指向一個檔案)"); Console.Read(); Shutdown(1); return; } foreach (var f in file) { using (Stream stream = new FileStream(f, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (StreamReader streamReader = new StreamReader(stream, encoding[0], false)) { s = streamReader.ReadToEnd(); } } if (!EncodingSetted) { switch (EncodingAnalyzer.Analyze(s)) { case -1: encoding[0] = Encoding.Default; break; case 0: case 1: encoding[0] = Encoding.GetEncoding("BIG5"); break; case 2: case 3: encoding[0] = Encoding.GetEncoding("GBK"); break; } } try { s = await ConvertHelper.FileConvert(s, encoding, ToChinese, VocabularyCorrection); } catch (Fanhuaji.FanhuajiException ex) { Console.WriteLine($"[Error][{DateTime.Now.ToString()}][{ex.Message}] {f}"); continue; } if (ModeIsOneFile) { using (StreamWriter streamWriter = new StreamWriter(path2, false, encoding[1] == Encoding.UTF8 ? new UTF8Encoding(App.Settings.FileConvert.UnicodeAddBom) : encoding[1])) { streamWriter.Write(s); streamWriter.Flush(); } } else { var m1 = Regex_path1.Match(f); if (m1.Success) { if (path2.Contains("*")) { var array = path2.Split('*'); string @string = ""; for (int i = 0; i < array.Length; i++) { @string += array[i]; if (i + 1 <= m1.Groups.Count - 1) { @string += m1.Groups[i + 1].Value; } } Directory.CreateDirectory(Path.GetDirectoryName(@string)); using (StreamWriter streamWriter = new StreamWriter(@string, false, encoding[1] == Encoding.UTF8 ? new UTF8Encoding(App.Settings.FileConvert.UnicodeAddBom) : encoding[1])) { streamWriter.Write(s); streamWriter.Flush(); } } else { Directory.CreateDirectory(Path.GetDirectoryName(path2)); using (StreamWriter streamWriter = new StreamWriter(Path.Combine(Path.GetDirectoryName(path2), Path.GetFileName(f)), false, encoding[1] == Encoding.UTF8 ? new UTF8Encoding(App.Settings.FileConvert.UnicodeAddBom) : encoding[1])) { streamWriter.Write(s); streamWriter.Flush(); } } } } } Shutdown(1); return; } else { if ((Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)) { MessageBox.Show("應用程式 " + Process.GetCurrentProcess().ProcessName + " 己在執行中,請先關閉舊視窗。", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); Shutdown(1); return; } ShowUI(); } }
private async void CreatePipeAsync(string id, PipeDirection direction, CancellationToken token) { try { if (direction == PipeDirection.InOut) { throw new ArgumentException("InOut is not a valid value. Use In OR Out!"); } id = direction == PipeDirection.In ? $"i_{id}" : $"o_{id}"; NamedPipeServerStream pipeServer = new NamedPipeServerStream( direction == PipeDirection.In ? Settings.ServerInputPipeName : Settings.ServerOutputPipeName, PipeDirection.InOut, _maxConnections); Trace.TraceInformation($"Server {id} waiting for connection ..."); SemaphoreSlim semaphore = direction == PipeDirection.In ? _semaphoreStartInputConnections : _semaphoreStartOutputConnections; await semaphore.WaitAsync(token); try { await pipeServer.WaitForConnectionAsync(token); } catch (Exception e) { Trace.TraceError("Error waiting for pipe connection: {0}", e.Message); pipeServer.Dispose(); return; } finally { semaphore.Release(); } Trace.TraceInformation($"Client connected on id: {id}"); try { StreamString ss = new StreamString(pipeServer, null); string clientId = await ss.ReadStringAsync(token); lock (_syncRootClients) { if (_pendingClients.TryGetValue(clientId, out NamedPipeIpcClient val)) { if (direction == PipeDirection.In) { if (val.InputPipe == null) { val.InputPipe = pipeServer; } else { Trace.TraceWarning( $"Client {val.Id} tried to register two input pipes, closing ..."); } } else { if (val.OutputPipe == null) { val.OutputPipe = pipeServer; } else { Trace.TraceWarning( $"Client {val.Id} tried to register two output pipes, closing ..."); } } if (val.InputPipe != null && val.OutputPipe != null) { Trace.TraceInformation($"Client {val.Id} successfully connected two pipes."); _clients.Add(val.Id, val); _pendingClients.Remove(val.Id); OnClientConnected(val); } else { pipeServer.Close(); pipeServer.Dispose(); } } else { Trace.TraceInformation($"Client {clientId} registered on {id}"); NamedPipeIpcClient npic = new NamedPipeIpcClient(clientId); if (direction == PipeDirection.In) { npic.InputPipe = pipeServer; } else { npic.OutputPipe = pipeServer; } npic.Closed += NamedPipeIpcClient_Closed; _pendingClients.Add(clientId, npic); } } } catch (IOException e) { Trace.TraceError(e.Message); } catch (ArgumentException) { Trace.TraceInformation($"Client disconnected before he sent an Id on connection {id}."); pipeServer.Dispose(); } } catch (Exception ex) { Util.TraceException("Error creating pipe", ex); OnError(ex); } }
public async Task ConnectAsync(CancellationToken ct) { await _stateLock.WaitAsync(ct); try { switch (_state) { case State.Disconnected: _state = State.Connecting; break; case State.Connecting: case State.Connected: return; case State.Disconnecting: throw new InvalidOperationException("Cannot connect while disconnecting."); } } finally { _stateLock.Release(); } _cts = new CancellationTokenSource(); try { _token = "cs.api.referencelib." + Guid.NewGuid(); _streamIn = new NamedPipeClientStream(Settings.ServerOutputPipeName); _streamOut = new NamedPipeClientStream(Settings.ServerInputPipeName); await Task.WhenAll( _streamIn.ConnectAsync(2000, ct), _streamOut.ConnectAsync(2000, ct) ).ConfigureAwait(false); await Task.WhenAll( StreamString.WriteStringAsync(_streamIn, _token, ct), StreamString.WriteStringAsync(_streamOut, _token, ct) ).ConfigureAwait(false); _ss = new StreamString(_streamIn, _streamOut); string res = await _ss.ReadStringAsync(ct).ConfigureAwait(false); if (Settings.ConnectionSuccessString.Equals(res)) { await ThrowIfNotStateAndSetNewState(State.Connecting, State.Connected, ct); OnOpened(); ReceiveLoop(_cts.Token); } else { throw new AuthenticationException("Couldn't successfully authenticate with server."); } } catch (Exception ex) { OnError(ex); } }