问题 帮助重复代码

科林斯5286

会员
已加入
2018年11月8日
留言内容
12
编程经验
Beginner
我已经编写了一些代码来更改Windows计算机上的电源设置。我不是软件开发人员,但我怀疑有比我编写的更好的编码方法。基本上,将代码重复6次以对系统运行每次更改。我确信必须有一种方法可以编写一个代码块并将修改后的参数传递给它6次...

我已经复制了前两节,但是它又重复了4次,只是参数不同。

Duplicate Code:
using System.Diagnostics;

namespace VolatileDataCapture.Services
{
    class PowerControlService
    {
        public void ChangePowerSettings()
        {
            ChangeStandbyTimeAC();
            ChangeStandbyTimeDC();
            ChangeHibernateTimeAC();
            ChangeHibernateTimeDC();
            ChangeMonitorTimeAC();
            ChangeMonitorTimeDC();
        }
        private void ChangeStandbyTimeAC()
        {
            using (var cmdPwrCfg = new Process())
            {
                cmdPwrCfg.StartInfo.FileName = "powercfg";
                cmdPwrCfg.StartInfo.UseShellExecute = false;
                cmdPwrCfg.StartInfo.CreateNoWindow = true;
                cmdPwrCfg.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                cmdPwrCfg.StartInfo.Arguments = "-change -standby-timeout-ac 0";
                cmdPwrCfg.StartInfo.RedirectStandardOutput = true;
                cmdPwrCfg.Start();
            }
        }
        private void ChangeStandbyTimeDC()
        {
            using (var cmdPwrCfg = new Process())
            {
                cmdPwrCfg.StartInfo.FileName = "powercfg";
                cmdPwrCfg.StartInfo.UseShellExecute = false;
                cmdPwrCfg.StartInfo.CreateNoWindow = true;
                cmdPwrCfg.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                cmdPwrCfg.StartInfo.Arguments = "-change -standby-timeout-dc 0";
                cmdPwrCfg.StartInfo.RedirectStandardOutput = true;
                cmdPwrCfg.Start();
            }
        }
 

约翰·H

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
1,039
地点
挪威
编程经验
10+
这些方法的唯一区别是字符串值,因此您可以将字符串参数添加到方法中以传递该值。 传递参数-C#编程指南|微软文档

快速提示,如果您将字符串分配更改为新的变量名称,则可以使用快速操作菜单让它为您生成参数:

1572529614475.png
 
Last edited:
已加入
2011年4月23日
留言内容
177
地点
密歇根州兰辛;美国
编程经验
10+
我已经编写了一些代码来更改Windows计算机上的电源设置。我不是软件开发人员,但我怀疑有比我编写的更好的编码方法。基本上,将代码重复6次以对系统运行每次更改。我确信必须有一种方法可以编写一个代码块并将修改后的参数传递给它6次...

我已经复制了前两节,但是它又重复了4次,只是参数不同。
欢迎进行重构,如果您发现两个或多个例程在代码中非常接近,那么您认为需要做些什么才能使它成为带参数的1调用?
看一下您已经在此处提供的两个,您认为该参数应该是什么使它们成为相同的调用?
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,521
地点
弗吉尼亚州切萨皮克
编程经验
10+
在我看来,使用所有这些设置,您只是在尝试阻止屏幕保护程序启动,并使机器进入睡眠状态。有一种更有效的方法可以防止这种情况的发生。使用 SetThreadExecutionState()。 PowerPoint和各种媒体播放器使用相同的API,以防止屏幕保护程序启动或使计算机进入睡眠状态。

ThreadExecutionState.csNativeMethods.cs 从我的 唤醒回购.
 
Last edited:
已加入
2011年4月23日
留言内容
177
地点
密歇根州兰辛;美国
编程经验
10+
在我看来,使用所有这些设置,您只是在尝试阻止屏幕保护程序启动,并使机器进入睡眠状态。有一种更有效的方法可以防止这种情况的发生。使用 SetThreadExecutionState()。 PowerPoint和各种媒体播放器使用相同的API,以防止屏幕保护程序启动或使计算机进入睡眠状态。

ThreadExecutionState.csNativeMethods.cs 从我的 唤醒回购.
我怀疑他只是在为他的应用程序更改Windows中的“电源选项”设置。我认为他正在组建一个应用程序,以更自动化的方式更改这些设置,实际上,这也是我每次安装Windows(XP和更高版本)时所做的事情。

我一直都知道您可以在代码中更改类似的内容,而不是打开控制面板并单击任何地方以更改全部内容,因此我可能会抓住此代码作为制作自己的脚本的起点,这样我就可以在每次全新安装后运行我的脚本。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,521
地点
弗吉尼亚州切萨皮克
编程经验
10+
如果这是为了更改计算机映像,则只需更改映像一次并部署即可。如果这是针对已经部署的计算机的现有环境,则使用组策略。但是,基于OP关于转储注册表的其他线程,看来OP需要此作为他对某些产品/软件进行安装前和安装后测试的另一个方面。

无论如何,通过代码更改所有这些电源设置的更好方法是直接调用电源管理API,而不是启动进程。那或者只是使用批处理文件。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
现在,你们都在总结你 思考 该代码用于,而不是 询问OP 他实际上是什么 试图完成 与他们拥有的代码。

当然,我们大多数人都知道有更好的方法来完成某些事情,但是除非我们实际上知道OP想要做什么,否则在彼此之间思考代码应该做什么是毫无意义的。您不认为只是要求清楚更好吗?

@ colins5286 您能解释一下您要做什么吗?您的代码打算做什么,为什么?

回答这些问题将有助于他们为您提供更清晰的答案。
 

科林斯5286

会员
已加入
2018年11月8日
留言内容
12
编程经验
Beginner
我写了一个小实用程序,可以从计算机中提取各种信息。收集的某些数据需要第三方应用程序才能运行,这可能需要一些时间,在某些情况下,计算机将进入睡眠状态或磁盘将旋转下来等。
我曾经使用各种批处理文件来提取数据并修改电源设置,但是现在我将它们捆绑在一个小型C#应用程序中。

我接受会有更好的方法来做我想做的事情-但是这些命令是我知道的唯一方法,已经从批处理文件中复制了它们。我已经完成了编码方面的速成课程,以使我的应用程序到达当前位置。

我只需要将“磁盘/屏幕/待机/休眠”时间更改为“从不”。这样,其他所有进程都可以运行,而不必担心机器进入休眠状态。无法设置组策略,因为它们是单独的计算机,有时应用程序无法打开,因此PowerPoint的API无效。如果有人可以向我解释,我愿意尝试另一种方法,但否则,只有这样,我才能确定它可以按编程方式更改上述设置的值。
谢谢
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
好的,这有点清楚,只是您没有以正确的方式进行操作。您在哪里分配/获取GUIDS?您在哪里获得电源选项列表?

从编码的角度来看,您尝试执行这些参数是不正确的。在我看来,通过执行流程来做到这一点只是错误的方法,如果您完成了速成课程,那么本文档将很容易理解- Powercfg命令行选项。但是,另一种方法是使用pinvoke并通过powrprof.dll操纵Win32 API调用,这样可以防止关机和休眠。看 pinvoke.net:搜索结果。注意:您也可以使用powershell进行此操作。由于我正要出门,所以稍后我需要与您联系以举例说明,或者这些家伙很乐意为您提供帮助。 :凉爽的:
 

科林斯5286

会员
已加入
2018年11月8日
留言内容
12
编程经验
Beginner
调用dll有点超出我的深度。我已经测试了当前代码,它会更改活动GUID上的正确电源设置。
我只是希望稍微清理一下代码,而不会调用同一代码6次(禁止输入参数)。
 

科林斯5286

会员
已加入
2018年11月8日
留言内容
12
编程经验
Beginner
好的-我已经阅读了一些在线教程,并且一团糟。这是我更新的代码。它可以满足我的要求,并且只有一个实际代码实例可以执行,它调用了6次,每次都传递不同的参数。这样做可能仍然很丑陋,但是它减少了几百行代码。

Refactored Code:
using System;
using System.Diagnostics;
using System.IO;


namespace VolatileDataCapture.Services
{
    class PowerControlService
    {
        public void RunPowerSettingChanges()
        {
            File.AppendAllText(GlobalVariables.logFile, Environment.NewLine + "Windows Power Settings Changed " + DateTime.Now);
            CurrentPowerSettings();
            ChangePowerSettings(powerArgs: "-change -standby-timeout-ac 0");
            ChangePowerSettings(powerArgs: "-change -standby-timeout-dc 0");
            ChangePowerSettings(powerArgs: "-change -hibernate-timeout-ac 0");
            ChangePowerSettings(powerArgs: "-change -hibernate-timeout-dc 0");
            ChangePowerSettings(powerArgs: "-change -monitor-timeout-ac 0");
            ChangePowerSettings(powerArgs: "-change -monitor-timeout-dc 0");
            ChangePowerSettings(powerArgs: "-change -disk-timeout-ac 0");
            ChangePowerSettings(powerArgs: "-change -disk-timeout-dc 0");
        }

        private void ChangePowerSettings(string powerArgs)
        {
            using (var cmdPwrCfg = new Process())
            {
                cmdPwrCfg.StartInfo.FileName = "powercfg";
                cmdPwrCfg.StartInfo.UseShellExecute = false;
                cmdPwrCfg.StartInfo.CreateNoWindow = true;
                cmdPwrCfg.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                cmdPwrCfg.StartInfo.Arguments = powerArgs;
                cmdPwrCfg.StartInfo.RedirectStandardOutput = true;
                cmdPwrCfg.Start();
            }
        }

        private void CurrentPowerSettings()
        {
            using (var cmdPwrCfg = new Process())
            {
                cmdPwrCfg.StartInfo.FileName = "powercfg";
                cmdPwrCfg.StartInfo.UseShellExecute = false;
                cmdPwrCfg.StartInfo.CreateNoWindow = true;
                cmdPwrCfg.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                cmdPwrCfg.StartInfo.Arguments = "-query";
                cmdPwrCfg.StartInfo.RedirectStandardOutput = true;
                cmdPwrCfg.Start();
                string powerOutput = cmdPwrCfg.StandardOutput.ReadToEnd();
                File.AppendAllText(GlobalVariables.powerLogFile, powerOutput);
            }
        }
    }
}
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,521
地点
弗吉尼亚州切萨皮克
编程经验
10+
有时应用程序未打开,因此PowerPoint的API无效
您不需要安装该应用程序。您只需要能够运行您的代码即可,就像您需要运行当前代码一样。不需要安装PowerPoint。我为您提供的API已内置在操作系统中。您只需要P / Invoke它,因为它是非托管API,而不是托管.NET Framework库中的API。
 

科林斯5286

会员
已加入
2018年11月8日
留言内容
12
编程经验
Beginner
您不需要安装该应用程序。您只需要能够运行您的代码即可,就像您需要运行当前代码一样。不需要安装PowerPoint。我为您提供的API已内置在操作系统中。您只需要P / Invoke它,因为它是非托管API,而不是托管.NET Framework库中的API。

OK-因此,如果我调用API,那么我的应用程序也就足够了-它是否仍可使计算机保持清醒状态?
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,521
地点
弗吉尼亚州切萨皮克
编程经验
10+
我不知道。当我在运行代码时需要唤醒计算机时,我总是调用它。我从来没有尝试过调用API,然后退出我的代码。

另一方面,为什么您需要退出应用程序?您说应用程序的重点是收集信息:
我写了一个小实用程序,可以从计算机中提取各种信息。收集的某些数据需要第三方应用程序才能运行,这可能需要一些时间,在某些情况下,计算机将进入睡眠状态或磁盘将旋转下来等。
您的应用程序不需要运行来收集信息吗?
 

科林斯5286

会员
已加入
2018年11月8日
留言内容
12
编程经验
Beginner
我不知道。当我在运行代码时需要唤醒计算机时,我总是调用它。我从来没有尝试过调用API,然后退出我的代码。

另一方面,为什么您需要退出应用程序?您说应用程序的重点是收集信息:

您的应用程序不需要运行来收集信息吗?

我的应用程序还调用其他可执行文件,可能是用户关闭了该应用程序,然后稍后又返回该应用程序。我需要掩盖所有基础。
 

科林斯5286

会员
已加入
2018年11月8日
留言内容
12
编程经验
Beginner
感谢大家的答复-我已经使用上面的代码进行了重构,这已经满足了我现在的需要。
我很欣赏它可能不够优雅或使用正确的电话。

谢谢大家
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,521
地点
弗吉尼亚州切萨皮克
编程经验
10+
我知道了。因此,您也可以使用P / Invoke为其他设置而不是仅为执行线程设置值。 powercfg.exe只是调用相同的API。

在这种情况下,请提前在Windows映像中设置值,而不要在测试开始时进行设置。为什么还要在将图像放入机器后进行设置?

无论如何,这是您的代码。您需要投入多少精力。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+

科林斯5286

会员
已加入
2018年11月8日
留言内容
12
编程经验
Beginner
我知道了。因此,您也可以使用P / Invoke为其他设置而不是仅为执行线程设置值。 powercfg.exe只是调用相同的API。

在这种情况下,请提前在Windows映像中设置值,而不要在测试开始时进行设置。为什么还要在将图像放入机器后进行设置?

无论如何,这是您的代码。您需要投入多少精力。

我无法控制图像。我向客户求助,并使用我的工具-他们随心所欲地设置他们的机器。我必须处理我面前的事情。我还没有遇到过P / Invoke的问题,所以我将对其进行研究,看看我是否了解它是如何工作的。谢谢
 
最佳 底部