예제 #1
0
 public bool Stop(bool showlog = true)
 {
     if (running)
     {
         running = false;
         if (showlog)
         {
             LogDebug(Properties.Resources.StoppingX360);
         }
         bool anyUnplugged = false;
         for (int i = 0; i < DS4Controllers.Length; i++)
         {
             if (DS4Controllers[i] != null)
             {
                 if (DCBTatStop && !DS4Controllers[i].Charging && showlog)
                 {
                     DS4Controllers[i].DisconnectBT();
                 }
                 else
                 {
                     DS4LightBar.forcelight[i]  = false;
                     DS4LightBar.forcedFlash[i] = 0;
                     DS4LightBar.defualtLight   = true;
                     DS4LightBar.updateLightBar(DS4Controllers[i], i, CurrentState[i], ExposedState[i], touchPad[i]);
                     System.Threading.Thread.Sleep(50);
                 }
                 CurrentState[i].Battery = PreviousState[i].Battery = 0; // Reset for the next connection's initial status change.
                 x360Bus.Unplug(i);
                 anyUnplugged      = true;
                 DS4Controllers[i] = null;
                 touchPad[i]       = null;
             }
         }
         if (anyUnplugged)
         {
             System.Threading.Thread.Sleep(XINPUT_UNPLUG_SETTLE_TIME);
         }
         x360Bus.UnplugAll();
         x360Bus.Stop();
         if (showlog)
         {
             LogDebug(Properties.Resources.StoppingDS4);
         }
         DS4Devices.stopControllers();
         if (showlog)
         {
             LogDebug(Properties.Resources.StoppedDS4Windows);
         }
         ControllerStatusChanged(this);
     }
     return(true);
 }
        public bool HotPlug(SynchronizationContext uiContext)
        {
            if (running)
            {
                DS4Devices.findControllers();
                IEnumerable <DS4Device> devices = DS4Devices.getDS4Controllers();
                //foreach (DS4Device device in devices)
                for (int i = 0, devlen = devices.Count(); i < devlen; i++)
                {
                    DS4Device device = devices.ElementAt(i);

                    if (device.isDisconnectingStatus())
                    {
                        continue;
                    }

                    if (((Func <bool>) delegate
                    {
                        for (Int32 Index = 0, arlength = DS4Controllers.Length; Index < arlength; Index++)
                        {
                            if (DS4Controllers[Index] != null &&
                                DS4Controllers[Index].getMacAddress() == device.getMacAddress())
                            {
                                return(true);
                            }
                        }

                        return(false);
                    })())
                    {
                        continue;
                    }

                    for (Int32 Index = 0, arlength = DS4Controllers.Length; Index < arlength; Index++)
                    {
                        if (DS4Controllers[Index] == null)
                        {
                            LogDebug(Properties.Resources.FoundController + device.getMacAddress() + " (" + device.getConnectionType() + ")");
                            Task task = new Task(() => { Thread.Sleep(5); WarnExclusiveModeFailure(device); });
                            task.Start();
                            DS4Controllers[Index] = device;
                            device.setUiContext(uiContext);
                            device.Removal      += this.On_DS4Removal;
                            device.Removal      += DS4Devices.On_Removal;
                            device.SyncChange   += this.On_SyncChange;
                            device.SyncChange   += DS4Devices.UpdateSerial;
                            device.SerialChange += this.On_SerialChange;
                            touchPad[Index]      = new Mouse(Index, device);
                            device.LightBarColor = getMainColor(Index);
                            device.Report       += this.On_Report;
                            if (!getDInputOnly(Index) && device.isSynced())
                            {
                                int xinputIndex = x360Bus.FirstController + Index;
                                LogDebug("Plugging in X360 Controller #" + xinputIndex);
                                bool xinputResult = x360Bus.Plugin(Index);
                                if (xinputResult)
                                {
                                    LogDebug("X360 Controller # " + xinputIndex + " connected");
                                    useDInputOnly[Index] = false;
                                }
                                else
                                {
                                    LogDebug("X360 Controller # " + xinputIndex + " failed. Using DInput only mode");
                                    useDInputOnly[Index] = true;
                                }
                            }

                            TouchPadOn(Index, device);
                            CheckProfileOptions(Index, device);
                            device.StartUpdate();

                            //string filename = Path.GetFileName(ProfilePath[Index]);
                            if (File.Exists(appdatapath + "\\Profiles\\" + ProfilePath[Index] + ".xml"))
                            {
                                string prolog = Properties.Resources.UsingProfile.Replace("*number*", (Index + 1).ToString()).Replace("*Profile name*", ProfilePath[Index]);
                                LogDebug(prolog);
                                Log.LogToTray(prolog);
                            }
                            else
                            {
                                string prolog = Properties.Resources.NotUsingProfile.Replace("*number*", (Index + 1).ToString());
                                LogDebug(prolog);
                                Log.LogToTray(prolog);
                            }

                            break;
                        }
                    }
                }
            }

            return(true);
        }
        public bool Stop(bool showlog = true)
        {
            if (running)
            {
                running    = false;
                runHotPlug = false;

                if (showlog)
                {
                    LogDebug(Properties.Resources.StoppingX360);
                }

                bool anyUnplugged = false;
                for (int i = 0, arlength = DS4Controllers.Length; i < arlength; i++)
                {
                    DS4Device tempDevice = DS4Controllers[i];
                    if (tempDevice != null)
                    {
                        if (DCBTatStop && !tempDevice.isCharging())
                        {
                            if (tempDevice.getConnectionType() == ConnectionType.BT)
                            {
                                tempDevice.StopUpdate();
                                tempDevice.DisconnectBT(true);
                            }
                            else if (tempDevice.getConnectionType() == ConnectionType.SONYWA)
                            {
                                tempDevice.StopUpdate();
                                tempDevice.DisconnectDongle(true);
                            }
                        }
                        else
                        {
                            DS4LightBar.forcelight[i]  = false;
                            DS4LightBar.forcedFlash[i] = 0;
                            DS4LightBar.defaultLight   = true;
                            DS4LightBar.updateLightBar(DS4Controllers[i], i, CurrentState[i],
                                                       ExposedState[i], touchPad[i]);
                            tempDevice.IsRemoved = true;
                            Thread.Sleep(50);
                        }

                        CurrentState[i].Battery = PreviousState[i].Battery = 0; // Reset for the next connection's initial status change.
                        x360Bus.Unplug(i);
                        useDInputOnly[i]  = true;
                        anyUnplugged      = true;
                        DS4Controllers[i] = null;
                        touchPad[i]       = null;
                        lag[i]            = false;
                        inWarnMonitor[i]  = false;
                    }
                }

                if (anyUnplugged)
                {
                    Thread.Sleep(XINPUT_UNPLUG_SETTLE_TIME);
                }

                x360Bus.UnplugAll();
                x360Bus.Stop();

                if (showlog)
                {
                    LogDebug(Properties.Resources.StoppingDS4);
                }

                DS4Devices.stopControllers();

                if (_udpServer != null)
                {
                    _udpServer.Stop();
                }

                if (showlog)
                {
                    LogDebug(Properties.Resources.StoppedDS4Windows);
                }
            }

            runHotPlug = false;
            return(true);
        }
        public bool Start(object tempui, bool showlog = true)
        {
            if (x360Bus.Open() && x360Bus.Start())
            {
                if (showlog)
                {
                    LogDebug(Properties.Resources.Starting);
                }

                LogDebug("Connection to Scp Virtual Bus established");

                DS4Devices.isExclusiveMode = getUseExclusiveMode();
                if (showlog)
                {
                    LogDebug(Properties.Resources.SearchingController);
                    LogDebug(DS4Devices.isExclusiveMode ? Properties.Resources.UsingExclusive : Properties.Resources.UsingShared);
                }

                try
                {
                    DS4Devices.findControllers();
                    IEnumerable <DS4Device> devices = DS4Devices.getDS4Controllers();
                    //int ind = 0;
                    DS4LightBar.defaultLight = false;
                    //foreach (DS4Device device in devices)

                    for (int i = 0, devCount = devices.Count(); i < devCount; i++)
                    {
                        DS4Device device = devices.ElementAt(i);
                        if (showlog)
                        {
                            LogDebug(Properties.Resources.FoundController + device.getMacAddress() + " (" + device.getConnectionType() + ")");
                        }

                        Task task = new Task(() => { Thread.Sleep(5); WarnExclusiveModeFailure(device); });
                        task.Start();

                        DS4Controllers[i] = device;
                        device.setUiContext(tempui as SynchronizationContext);
                        device.Removal      += this.On_DS4Removal;
                        device.Removal      += DS4Devices.On_Removal;
                        device.SyncChange   += this.On_SyncChange;
                        device.SyncChange   += DS4Devices.UpdateSerial;
                        device.SerialChange += this.On_SerialChange;
                        touchPad[i]          = new Mouse(i, device);
                        device.LightBarColor = getMainColor(i);

                        if (!getDInputOnly(i) && device.isSynced())
                        {
                            int xinputIndex = x360Bus.FirstController + i;
                            LogDebug("Plugging in X360 Controller #" + xinputIndex);
                            bool xinputResult = x360Bus.Plugin(i);
                            if (xinputResult)
                            {
                                LogDebug("X360 Controller # " + xinputIndex + " connected");
                                useDInputOnly[i] = false;
                            }
                            else
                            {
                                LogDebug("X360 Controller # " + xinputIndex + " failed. Using DInput only mode");
                                useDInputOnly[i] = true;
                            }
                        }

                        device.Report += this.On_Report;
                        TouchPadOn(i, device);
                        CheckProfileOptions(i, device, true);
                        device.StartUpdate();
                        //string filename = ProfilePath[ind];
                        //ind++;
                        if (showlog)
                        {
                            if (File.Exists(appdatapath + "\\Profiles\\" + ProfilePath[i] + ".xml"))
                            {
                                string prolog = Properties.Resources.UsingProfile.Replace("*number*", (i + 1).ToString()).Replace("*Profile name*", ProfilePath[i]);
                                LogDebug(prolog);
                                Log.LogToTray(prolog);
                            }
                            else
                            {
                                string prolog = Properties.Resources.NotUsingProfile.Replace("*number*", (i + 1).ToString());
                                LogDebug(prolog);
                                Log.LogToTray(prolog);
                            }
                        }

                        if (i >= 4) // out of Xinput devices!
                        {
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    LogDebug(e.Message);
                    Log.LogToTray(e.Message);
                }

                running = true;

                if (_udpServer != null)
                {
                    var UDP_SERVER_PORT = 26760;

                    try
                    {
                        _udpServer.Start(UDP_SERVER_PORT);
                        LogDebug("UDP server listening on port " + UDP_SERVER_PORT);
                    }
                    catch (System.Net.Sockets.SocketException ex)
                    {
                        var errMsg = String.Format("Couldn't start UDP server on port {0}, outside applications won't be able to access pad data ({1})", UDP_SERVER_PORT, ex.SocketErrorCode);

                        LogDebug(errMsg, true);
                        Log.LogToTray(errMsg, true, true);
                    }
                }
            }
            else
            {
                string logMessage = "Could not connect to Scp Virtual Bus Driver. Please check the status of the System device in Device Manager";
                LogDebug(logMessage);
                Log.LogToTray(logMessage);
            }

            runHotPlug = true;
            return(true);
        }
예제 #5
0
        static void Main(string[] args)
        {
            //Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("ja");
            for (int i = 0, argsLen = args.Length; i < argsLen; i++)
            {
                string s = args[i];
                if (s == "driverinstall" || s == "-driverinstall")
                {
                    Application.EnableVisualStyles();
                    Application.Run(new WelcomeDialog(true));
                    return;
                }
                else if (s == "re-enabledevice" || s == "-re-enabledevice")
                {
                    try
                    {
                        i++;
                        string deviceInstanceId = args[i];
                        DS4Devices.reEnableDevice(deviceInstanceId);
                        Environment.ExitCode = 0;
                        return;
                    }
                    catch (Exception)
                    {
                        Environment.ExitCode = Marshal.GetLastWin32Error();
                        return;
                    }
                }
                else if (s == "runtask" || s == "-runtask")
                {
                    TaskService ts     = new TaskService();
                    Task        tasker = ts.FindTask("RunDS4Windows");
                    if (tasker != null)
                    {
                        tasker.Run("");
                    }

                    Environment.ExitCode = 0;
                    return;
                }
            }

            GCSettings.LatencyMode = GCLatencyMode.LowLatency;

            try
            {
                Process.GetCurrentProcess().PriorityClass =
                    System.Diagnostics.ProcessPriorityClass.High;
            }
            catch { } // Ignore problems raising the priority.

            try
            {
                // another instance is already running if OpenExsting succeeds.
                threadComEvent = EventWaitHandle.OpenExisting(SingleAppComEventName,
                                                              System.Security.AccessControl.EventWaitHandleRights.Synchronize |
                                                              System.Security.AccessControl.EventWaitHandleRights.Modify);
                threadComEvent.Set(); // signal the other instance.
                threadComEvent.Close();
                return;               // return immediatly.
            }
            catch { /* don't care about errors */ }

            // Create the Event handle
            threadComEvent = new EventWaitHandle(false, EventResetMode.ManualReset, SingleAppComEventName);
            //System.Threading.Tasks.Task.Run(() => CreateTempWorkerThread());
            //CreateInterAppComThread();
            CreateTempWorkerThread();
            //System.Threading.Tasks.Task.Run(() => { Thread.CurrentThread.Priority = ThreadPriority.Lowest; CreateInterAppComThread(); Thread.CurrentThread.Priority = ThreadPriority.Lowest; }).Wait();

            //if (mutex.WaitOne(TimeSpan.Zero, true))
            //{
            createControlService();
            //rootHub = new ControlService();
            Application.EnableVisualStyles();
            ds4form = new DS4Form(args);
            Application.Run();
            //mutex.ReleaseMutex();
            //}

            exitComThread = true;
            threadComEvent.Set();  // signal the other instance.
            while (testThread.IsAlive)
            {
                Thread.SpinWait(500);
            }
            threadComEvent.Close();
        }
예제 #6
0
        static void Main(string[] args)
        {
            //Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("he");
            for (int i = 0; i < args.Length; i++)
            {
                string s = args[i];
                if (s == "driverinstall" || s == "-driverinstall")
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new WelcomeDialog());
                    return;
                }
                else if (s == "re-enabledevice" || s == "-re-enabledevice")
                {
                    try
                    {
                        i++;
                        string deviceInstanceId = args[i];
                        DS4Devices.reEnableDevice(deviceInstanceId);
                        Environment.ExitCode = 0;
                        return;
                    }
                    catch (Exception)
                    {
                        Environment.ExitCode = Marshal.GetLastWin32Error();
                        return;
                    }
                }
            }
            System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.LowLatency;

            try
            {
                Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.High;
            }
            catch
            {
                // Ignore problems raising the priority.
            }
            try
            {
                // another instance is already running if OpenExsting succeeds.
                threadComEvent = EventWaitHandle.OpenExisting(SingleAppComEventName);
                threadComEvent.Set(); // signal the other instance.
                threadComEvent.Close();
                return;               // return immediatly.
            }
            catch { /* don't care about errors */ }
            // Create the Event handle
            threadComEvent = new EventWaitHandle(false, EventResetMode.AutoReset, SingleAppComEventName);
            CreateInterAppComThread();

            if (mutex.WaitOne(TimeSpan.Zero, true))
            {
                rootHub = new ControlService();
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new DS4Form(args));
                mutex.ReleaseMutex();
            }

            // End the communication thread.
            singleAppComThread.CancelAsync();
            while (singleAppComThread.IsBusy)
            {
                Thread.Sleep(50);
            }
            threadComEvent.Close();
        }
예제 #7
0
        public bool HotPlug()
        {
            if (running)
            {
                DS4Devices.findControllers();
                IEnumerable <DS4Device> devices = DS4Devices.getDS4Controllers();
                foreach (DS4Device device in devices)
                {
                    if (device.IsDisconnecting)
                    {
                        continue;
                    }
                    if (((Func <bool>) delegate
                    {
                        for (Int32 Index = 0; Index < DS4Controllers.Length; Index++)
                        {
                            if (DS4Controllers[Index] != null && DS4Controllers[Index].MacAddress == device.MacAddress)
                            {
                                return(true);
                            }
                        }
                        return(false);
                    })())
                    {
                        continue;
                    }
                    for (Int32 Index = 0; Index < DS4Controllers.Length; Index++)
                    {
                        if (DS4Controllers[Index] == null)
                        {
                            LogDebug(Properties.Resources.FoundController + device.MacAddress + " (" + device.ConnectionType + ")");
                            WarnExclusiveModeFailure(device);
                            DS4Controllers[Index] = device;
                            device.Removal       -= DS4Devices.On_Removal;
                            device.Removal       += this.On_DS4Removal;
                            device.Removal       += DS4Devices.On_Removal;
                            touchPad[Index]       = new Mouse(Index, device);
                            device.LightBarColor  = MainColor[Index];
                            device.Report        += this.On_Report;
                            if (!DinputOnly[Index])
                            {
                                x360Bus.Plugin(Index);
                            }
                            TouchPadOn(Index, device);
                            //string filename = Path.GetFileName(ProfilePath[Index]);
                            if (System.IO.File.Exists(appdatapath + "\\Profiles\\" + ProfilePath[Index] + ".xml"))
                            {
                                string prolog = Properties.Resources.UsingProfile.Replace("*number*", (Index + 1).ToString()).Replace("*Profile name*", ProfilePath[Index]);
                                LogDebug(prolog);
                                Log.LogToTray(prolog);
                            }
                            else
                            {
                                string prolog = Properties.Resources.NotUsingProfile.Replace("*number*", (Index + 1).ToString());
                                LogDebug(prolog);
                                Log.LogToTray(prolog);
                            }

                            break;
                        }
                    }
                }
            }
            return(true);
        }
예제 #8
0
 public bool Start(bool showlog = true)
 {
     if (x360Bus.Open() && x360Bus.Start())
     {
         if (showlog)
         {
             LogDebug(Properties.Resources.Starting);
         }
         DS4Devices.isExclusiveMode = UseExclusiveMode;
         if (showlog)
         {
             LogDebug(Properties.Resources.SearchingController);
             LogDebug(DS4Devices.isExclusiveMode ?  Properties.Resources.UsingExclusive: Properties.Resources.UsingShared);
         }
         try
         {
             DS4Devices.findControllers();
             IEnumerable <DS4Device> devices = DS4Devices.getDS4Controllers();
             int ind = 0;
             DS4LightBar.defualtLight = false;
             foreach (DS4Device device in devices)
             {
                 if (showlog)
                 {
                     LogDebug(Properties.Resources.FoundController + device.MacAddress + " (" + device.ConnectionType + ")");
                 }
                 WarnExclusiveModeFailure(device);
                 DS4Controllers[ind]  = device;
                 device.Removal      -= DS4Devices.On_Removal;
                 device.Removal      += this.On_DS4Removal;
                 device.Removal      += DS4Devices.On_Removal;
                 touchPad[ind]        = new Mouse(ind, device);
                 device.LightBarColor = MainColor[ind];
                 if (!DinputOnly[ind])
                 {
                     x360Bus.Plugin(ind);
                 }
                 device.Report += this.On_Report;
                 TouchPadOn(ind, device);
                 //string filename = ProfilePath[ind];
                 ind++;
                 if (showlog)
                 {
                     if (System.IO.File.Exists(appdatapath + "\\Profiles\\" + ProfilePath[ind - 1] + ".xml"))
                     {
                         string prolog = Properties.Resources.UsingProfile.Replace("*number*", ind.ToString()).Replace("*Profile name*", ProfilePath[ind - 1]);
                         LogDebug(prolog);
                         Log.LogToTray(prolog);
                     }
                     else
                     {
                         string prolog = Properties.Resources.NotUsingProfile.Replace("*number*", (ind).ToString());
                         LogDebug(prolog);
                         Log.LogToTray(prolog);
                     }
                 }
                 if (ind >= 4) // out of Xinput devices!
                 {
                     break;
                 }
             }
         }
         catch (Exception e)
         {
             LogDebug(e.Message);
             Log.LogToTray(e.Message);
         }
         running = true;
     }
     return(true);
 }
예제 #9
0
        public bool Start(object tempui, bool showlog = true)
        {
            if (x360Bus.Open() && x360Bus.Start())
            {
                if (showlog)
                {
                    LogDebug(Properties.Resources.Starting);
                }

                LogDebug("Connection to Scp Virtual Bus established");

                DS4Devices.isExclusiveMode = getUseExclusiveMode();
                if (showlog)
                {
                    LogDebug(Properties.Resources.SearchingController);
                    LogDebug(DS4Devices.isExclusiveMode ? Properties.Resources.UsingExclusive : Properties.Resources.UsingShared);
                }

                try
                {
                    DS4Devices.findControllers();
                    IEnumerable <DS4Device> devices = DS4Devices.getDS4Controllers();
                    //int ind = 0;
                    DS4LightBar.defaultLight = false;
                    //foreach (DS4Device device in devices)

                    for (int i = 0, devCount = devices.Count(); i < devCount; i++)
                    {
                        DS4Device device = devices.ElementAt(i);
                        if (showlog)
                        {
                            LogDebug(Properties.Resources.FoundController + device.getMacAddress() + " (" + device.getConnectionType() + ")");
                        }

                        Task task = new Task(() => { Thread.Sleep(5); WarnExclusiveModeFailure(device); });
                        task.Start();

                        DS4Controllers[i] = device;
                        device.setUiContext(tempui as SynchronizationContext);
                        device.Removal      += this.On_DS4Removal;
                        device.Removal      += DS4Devices.On_Removal;
                        device.SyncChange   += this.On_SyncChange;
                        device.SyncChange   += DS4Devices.UpdateSerial;
                        device.SerialChange += this.On_SerialChange;
                        if (device.isValidSerial() && containsLinkedProfile(device.getMacAddress()))
                        {
                            ProfilePath[i] = getLinkedProfile(device.getMacAddress());
                        }
                        else
                        {
                            ProfilePath[i] = OlderProfilePath[i];
                        }
                        LoadProfile(i, false, this, false, false);
                        touchPad[i]          = new Mouse(i, device);
                        device.LightBarColor = getMainColor(i);

                        if (!getDInputOnly(i) && device.isSynced())
                        {
                            int xinputIndex = x360Bus.FirstController + i;
                            LogDebug("Plugging in X360 Controller #" + xinputIndex);
                            bool xinputResult = x360Bus.Plugin(i);
                            if (xinputResult)
                            {
                                useDInputOnly[i] = false;
                                LogDebug("X360 Controller # " + xinputIndex + " connected");
                            }
                            else
                            {
                                useDInputOnly[i] = true;
                                LogDebug("X360 Controller # " + xinputIndex + " failed. Using DInput only mode");
                            }
                        }

                        int tempIdx = i;
                        device.Report += (sender, e) =>
                        {
                            this.On_Report(sender, e, tempIdx);
                        };
                        TouchPadOn(i, device);
                        CheckProfileOptions(i, device, true);
                        device.StartUpdate();
                        //string filename = ProfilePath[ind];
                        //ind++;
                        if (showlog)
                        {
                            if (File.Exists(appdatapath + "\\Profiles\\" + ProfilePath[i] + ".xml"))
                            {
                                string prolog = Properties.Resources.UsingProfile.Replace("*number*", (i + 1).ToString()).Replace("*Profile name*", ProfilePath[i]);
                                LogDebug(prolog);
                                Log.LogToTray(prolog);
                            }
                            else
                            {
                                string prolog = Properties.Resources.NotUsingProfile.Replace("*number*", (i + 1).ToString());
                                LogDebug(prolog);
                                Log.LogToTray(prolog);
                            }
                        }

                        if (i >= 4) // out of Xinput devices!
                        {
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    LogDebug(e.Message);
                    Log.LogToTray(e.Message);
                }

                running = true;
            }
            else
            {
                string logMessage = "Could not connect to Scp Virtual Bus Driver. Please check the status of the System device in Device Manager";
                LogDebug(logMessage);
                Log.LogToTray(logMessage);
            }

            runHotPlug = true;
            return(true);
        }
예제 #10
0
        static void Main(string[] args)
        {
            //Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("ja");
            for (int i = 0, argsLen = args.Length; i < argsLen; i++)
            {
                string s = args[i];
                if (s == "driverinstall" || s == "-driverinstall")
                {
                    Application.EnableVisualStyles();
                    Application.Run(new Forms.WelcomeDialog(true));
                    return;
                }
                else if (s == "re-enabledevice" || s == "-re-enabledevice")
                {
                    try
                    {
                        i++;
                        string deviceInstanceId = args[i];
                        DS4Devices.reEnableDevice(deviceInstanceId);
                        Environment.ExitCode = 0;
                        return;
                    }
                    catch (Exception)
                    {
                        Environment.ExitCode = Marshal.GetLastWin32Error();
                        return;
                    }
                }
                else if (s == "runtask" || s == "-runtask")
                {
                    TaskService ts     = new TaskService();
                    Task        tasker = ts.FindTask("RunDS4Windows");
                    if (tasker != null)
                    {
                        tasker.Run("");
                    }

                    Environment.ExitCode = 0;
                    return;
                }
                else if (s == "command" || s == "-command")
                {
                    i++;

                    IntPtr hWndDS4WindowsForm = IntPtr.Zero;

                    if (args[i].Length > 0 && args[i].Length <= 256)
                    {
                        // Find the main DS4Form window handle and post WM_COPYDATA inter-process message. IPCClasName.dat file was created by the main DS4Windows process
                        // and it contains the name of the DS4Form .NET window class name string (the hash key part of the string is dynamically generated by .NET engine and it may change,
                        // so that's why the main process re-creates the file if the window class name is changed by .NET framework). Finding the WND handle usig both class name and window name
                        // limits chances that WM_COPYDATA message is sent to a wrong window.

                        hWndDS4WindowsForm = FindWindow(ReadIPCClassNameMMF(), "DS4Windows");
                        if (hWndDS4WindowsForm != IntPtr.Zero)
                        {
                            COPYDATASTRUCT cds;
                            cds.lpData = IntPtr.Zero;

                            try
                            {
                                cds.dwData = IntPtr.Zero;
                                cds.cbData = args[i].Length;
                                cds.lpData = Marshal.StringToHGlobalAnsi(args[i]);
                                SendMessage(hWndDS4WindowsForm, Forms.DS4Form.WM_COPYDATA, IntPtr.Zero, ref cds);
                            }
                            finally
                            {
                                if (cds.lpData != IntPtr.Zero)
                                {
                                    Marshal.FreeHGlobal(cds.lpData);
                                }
                            }
                        }
                        else
                        {
                            Environment.ExitCode = 2;
                        }
                    }
                    else
                    {
                        Environment.ExitCode = 1;
                    }

                    return;
                }
            }

            try
            {
                Process.GetCurrentProcess().PriorityClass =
                    System.Diagnostics.ProcessPriorityClass.High;
            }
            catch { } // Ignore problems raising the priority.

            // Force Normal IO Priority
            IntPtr ioPrio = new IntPtr(2);

            Util.NtSetInformationProcess(Process.GetCurrentProcess().Handle,
                                         Util.PROCESS_INFORMATION_CLASS.ProcessIoPriority, ref ioPrio, 4);

            // Force Normal Page Priority
            IntPtr pagePrio = new IntPtr(5);

            Util.NtSetInformationProcess(Process.GetCurrentProcess().Handle,
                                         Util.PROCESS_INFORMATION_CLASS.ProcessPagePriority, ref pagePrio, 4);

            try
            {
                // another instance is already running if OpenExsting succeeds.
                threadComEvent = EventWaitHandle.OpenExisting(SingleAppComEventName,
                                                              System.Security.AccessControl.EventWaitHandleRights.Synchronize |
                                                              System.Security.AccessControl.EventWaitHandleRights.Modify);
                threadComEvent.Set(); // signal the other instance.
                threadComEvent.Close();
                return;               // return immediatly.
            }
            catch { /* don't care about errors */ }

            // Create the Event handle
            threadComEvent = new EventWaitHandle(false, EventResetMode.ManualReset, SingleAppComEventName);
            //System.Threading.Tasks.Task.Run(() => CreateTempWorkerThread());
            //CreateInterAppComThread();
            CreateTempWorkerThread();
            //System.Threading.Tasks.Task.Run(() => { Thread.CurrentThread.Priority = ThreadPriority.Lowest; CreateInterAppComThread(); Thread.CurrentThread.Priority = ThreadPriority.Lowest; }).Wait();

            //if (mutex.WaitOne(TimeSpan.Zero, true))
            //{
            createControlService();
            //rootHub = new ControlService();
            Application.EnableVisualStyles();
            ds4form = new Forms.DS4Form(args);
            Application.Run();
            //mutex.ReleaseMutex();
            //}

            exitComThread = true;
            threadComEvent.Set();  // signal the other instance.
            while (testThread.IsAlive)
            {
                Thread.SpinWait(500);
            }
            threadComEvent.Close();

            if (ipcClassNameMMA != null)
            {
                ipcClassNameMMA.Dispose();
            }
            if (ipcClassNameMMF != null)
            {
                ipcClassNameMMF.Dispose();
            }
        }