GVKun编程网logo

什么是程序终止自己的进程的正确方法(Windows)(程序终止运行)

11

本篇文章给大家谈谈什么是程序终止自己的进程的正确方法,以及Windows的知识点,同时本文还将给你拓展C++不能获得进程ID(Windows)、c#–从Windows服务发送电子邮件的正确方法、Coc

本篇文章给大家谈谈什么是程序终止自己的进程的正确方法,以及Windows的知识点,同时本文还将给你拓展C + +不能获得进程ID(Windows)、c# – 从Windows服务发送电子邮件的正确方法、Cocos2d-x 2.2.X 创建新工程的方法(Windows)、dependency-injection – 在Windows客户端(WPF)应用程序中执行依赖注入的正确方法等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

什么是程序终止自己的进程的正确方法(Windows)(程序终止运行)

什么是程序终止自己的进程的正确方法(Windows)(程序终止运行)

C#.NET 3.5

我有一个控制台应用程序被另一个应用程序在计算机上调用。 这个控制台应用程序连续运行,并从“父”进程监听stdin上的数据。

但是,当父母停止或杀死,它启动的控制台应用程序继续。 在正常情况下,它使用最less的资源坐着等待来自stdin的input。 但是,一旦父母离开,这个控制台应用程序就会触发cpu,并以接近100%的利用率挨饿运行的核心。 这继续下去,直到我手动杀死进程。

理想情况下,主叫家长会自行清理,尤其是因为这是在正常(非常规)“停止”条件下发生的。 不幸的是,这个父母过程不在我的手中。

运行WPF程序时防止Windows工作站(桌面)locking

如何安全地保存文件到磁盘没有Windows拒绝的风险呢?

在本地运行Azure模拟器进行生产

限制在MS脚本引擎中使用名称空间

后台线程上的Windows Mobile C#数据集更新

我的第一个想法是从控制台应用程序中获取调用的父级,并监视其PID。 如果父进程消失,我的控制台应用程序会自行终止。 目前,我正在做这个:

Process process = Process.GetCurrentProcess(); m_ParentPID = 0; using (ManagementObject mgmtObj = new ManagementObject("win32_process.handle='" + process.Id.ToString() + "'")) { mgmtObj.Get(); m_ParentPID = Convert.ToInt32(mgmtObj["ParentProcessId"]); } string parentProcessName = Process.GetProcessById(m_ParentPID).ProcessName; Log("Parent Process: " + parentProcessName + Environment.NewLine); // Create a timer for monitoring self. Timer timer = new Timer(new TimerCallback(sender => { if (m_ParentPID != 0) { Process parent = System.Diagnostics.Process.GetProcessById(m_ParentPID); if (parent == null) { Log("Parent process stopped/killed. Terminating self."); System.Environment.Exit(0); } } })); // Kick on the timer timer.Change(m_ExitWatcherFrequency,m_ExitWatcherFrequency);

这只是部分工作,但它阻止了cpu的峰值,但是如果我从Sysinternals美妙的进程监视器看我的进程,我可以看到DW20.exe运行 – “微软应用程序错误报告”程序。 它只是…坐在那里,控制台应用程序仍然在内存中。

我应该在这里做些什么来正确地终止这个过程,以避免这个连续的cpu峰值和未释放的内存? 最终这需要在没有干预的情况下运行。

PS我在这里使用命令行应用程序作为“长时间运行的程序”而不是Windows服务或Web服务,因为父程序只能configuration为执行命令行应用程序,通过stdin传递数据。 (对于那些好奇,这是ejabberd,使用外部authentication)。

编辑:

等待来自stdin的input的代码是:

// Read data from stdin char[] charray = new char[maxbuflen]; read = Console.In.Read(charray,2);

我之前提到,当父节点终止,控制台应用程序在cpu上疯狂。 我从Visual Studio中附加了一个debugging器,实际上它仍然在Console.In.Read中。 理论上,当自我监视计时器触发并且看到父母不在时,当另一个线程在该Read()行上时,它将尝试System.Environment.Exit(0)。

Dotnet核心应用程序在生产中找不到appsettings.json

生成机器指纹的最佳方法是什么?

创build一个Windows钩子来检测菜单点击

我可以使用没有.NET库的Windows身份validation使用WCF REST服务吗?

在registry中创build子上下文菜单项

这听起来像你的进程正在进入一个硬回路,因为当父母退出时,控制台输入流被关闭。 你是否从Console.In.Read检查返回值? 当流关闭时它将返回零。 在这一点上打破了循环,让你的Main()方法本身退出。

而如果你正在运行多个线程,则必须先使用Thread.Join或等价的方法完成。

要监视进程退出,请使用Process类,并订阅Exited事件。

编辑:删除交互评论。

编辑(回复评论):

大多数情况下,在这种情况下完成的是将一些数据传回来,这样就可以在Console.In.Read方法调用中停止阻塞。

所以,当你发现父进程已经完成时,假设你设置了一个标志IsDone为true。 现在,因为你等待的过程不再发送任何东西,你仍然需要接收标准输入的东西,否则你将永远阻止。 所以,在你的事件处理程序/计时器代码中,写一些东西给你自己的进程的标准输入(如果你愿意的话,它甚至可以是一个特殊的值来表示你完成了)。 这会让你通过Console.In.Read方法。 一旦出来,检查是否设置了IsDone标志 – 如果是,停止处理并从主方法返回 – 不需要System.Environment.Exit 。

我会通过添加一个线程到您的控制台应用程序,基本上监视进程表中调用应用程序的存在来解决这个问题。 这是我的头顶,但这里有一些伪代码:

using System.Thread; using System.Diagnostics; main(){ Thread monitoringThread = new Thread(new ThreadStart(monitor)); monitoringThread.Name = "Monitor"; monitoringThread.Start(); }

并在功能监视器中:

void monitor(){ Process[] theCallers = Process.GetProcessesByName("CallingProcessName"); theCallers[0].WaitForExit(); Process.GetCurrentProcess().Kill(); }

假设在进程列表中只有一个调用进程,只要进程结束,这个也是一样。 你也可以为自己的进程提供更好的清理代码,而不是让它突然结束。

我喜欢mmr从孩子那里看父母的过程。 如果你有办法在命令行上传递父进程的PID,那就更好了。 从父进程内部,你可以得到PID:

System.Diagnostics.Process.GetCurrentProcess().Id

C + +不能获得进程ID(Windows)

C + +不能获得进程ID(Windows)

我有一个像这样的函数来获取一个进程的id是它的名字,然而它总是返回0,我试着每一个进程:

DWORD GetProcessId(std::string ProcessName) { HANDLE hsnap; PROCESSENTRY32 pt; DWORD PiD; hsnap = Createtoolhelp32Snapshot(TH32CS_SNAPPROCESS,0); pt.dwSize = sizeof(PROCESSENTRY32); do { if (!strcmp(pt.szExeFile,ProcessName.c_str())) { CloseHandle(hsnap); PiD = pt.th32ProcessID; return PiD; if (PiD != NULL) { return 0; } } } while (Process32Next(hsnap,&pt)); return 1; }

主要function:

int main() { DWORD pid = GetProcessId("calc.exe"); std::cout << pid; if (pid == 0) { printf("error 1"); getchar(); }//error return 0; }

通过Windows API函数replace对AfxGetInstanceHandle()的调用

从任务计划的Windowsbatch file中杀死进程树

写入超过2.5GB后性能下降。 为什么?

在shmdt()和shmctl(shmid,ipc_RMID,0)之前的进程中访问共享内存

从信号处理程序打印堆栈跟踪

如何build立提升python 3.4共享库win8.1 64位与msvc 10.0

在Python中查找每个正在运行的进程的path

没有溢出投在x64上

在Linux上更快地分配大型进程?

如何“docker运行”在最小的Linux安装一个shell会话,并立即拆除容器?

这里有几个问题。

首先, GetProcessId是一个Windows API函数的名称,它将一个HANDLE作为参数。 HANDLE通常被定义为void* ,所以这意味着任何指针都将满足函数签名。

你自己的GetProcessId需要一个std::string但是通过传递一个指向字符串常量的指针来调用它。 通常情况下,这样做可以, std::string可以由此构造,但是因为GetProcessId的Windows API版本已经匹配了编译器优先调用的函数签名。 所以基本上你自己的功能从来没有被实际调用过。

你自己的功能也有一些问题。 首先,通过循环的第一次迭代是与垃圾内存进行比较 – 您忘记调用Process32First ,所以pt在第一次通过时是未初始化的。 其次,如果这个过程没有找到,你正在泄漏hsnap句柄。

尝试以下操作:

DWORD MyGetProcessId(LPCTSTR ProcessName) // non-conflicting function name { PROCESSENTRY32 pt; HANDLE hsnap = Createtoolhelp32Snapshot(TH32CS_SNAPPROCESS,0); pt.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hsnap,&pt)) { // must call this first do { if (!lstrcmpi(pt.szExeFile,ProcessName)) { CloseHandle(hsnap); return pt.th32ProcessID; } } while (Process32Next(hsnap,&pt)); } CloseHandle(hsnap); // close handle on failure return 0; } int main() { DWORD pid = MyGetProcessId(TEXT("calc.exe")); std::cout << pid; if (pid == 0) { printf("error 1"); getchar(); }//error return 0; }

编辑:我已经改变了函数不再使用一个std::string ,并使用lstrcmpi意味着它将作为一个Ansi或Unicode版本。 正如下面的评论员所建议的那样,现在你真的应该使用Unicode。

这里是C代码,在Windows上工作正常。 用进程名调用PID_GetProcessId,返回进程名的进程号

int PID_GetProcessId(char * name,PDWORD pid) { DWORD aProcesses[1024],cbNeeded,cProcesses; UINT32 i; if (!EnumProcesses( aProcesses,sizeof(aProcesses),&cbNeeded ) ) { //Error } /* Calculate how many process identifiers were returned. */ cProcesses = cbNeeded / sizeof(DWORD); /* Print the name and process identifier for each process. */ for ( i = 0; i < cProcesses; i++ ) { if( aProcesses[i] != 0 ) { if(PID_PrintProcessNameAndID( aProcesses[i],name ) == 1) { *pid = aProcesses[i]; break; } } } return 0; } int PID_PrintProcessNameAndID(DWORD processID,char * name) { char szProcessName[MAX_PATH]; HANDLE hProcess=NULL; char buff[200]=""; hProcess = OpenProcess( PROCESS_QUERY_informatION |PROCESS_VM_READ,FALSE,processID ); /* Get the process name. */ if (NULL != hProcess ) { HMODULE hMod; DWORD cbNeeded; if ( EnumProcessmodulees( hProcess,&hMod,sizeof(hMod),&cbNeeded) ) { GetmoduleeBaseNameA( hProcess,hMod,(LPSTR)szProcessName,sizeof(szProcessName)/sizeof(TCHAR) ); } } if(lstrcmpiA(szProcessName,name) == 0) { CloseHandle(hProcess); return 1; } return 0; CloseHandle( hProcess ); }

c# – 从Windows服务发送电子邮件的正确方法

c# – 从Windows服务发送电子邮件的正确方法

我需要按计划发送大量电子邮件(可能每天数百封).
我想要这样做的方式如下,但问题是我的Body字段可以变得非常大,如果我将它添加为字符串,它会变得难看.
SmtpClient client = new SmtpClient(); //host and port picked from web.config
        client.EnableSsl = true;

        MailMessage message = new MailMessage();

        message.Body = "test from winservice"; // HERE IS MY PROBLEM
        message.IsBodyHtml = true;
        message.From = new MailAddress("donotreply@abcde.com");
        message.Subject = "My subject";
        message.To.Add(new MailAddress("piniusha@abcde.com"));
        try
        {
            client.Send(message);
        }
        catch (Exception)
        {

        }

当我不得不从我使用的aspx页面做到这一点

MailDeFinition message = new MailDeFinition();  

    message.BodyFileName = @"~\EmailTemplate\Template1.htm";
    ListDictionary replacements = new ListDictionary();
    replacements.Add("<% Name %>",this.txtName.Text);
    replacements.Add("<% PhoneOrEmail %>",this.txtPhoneOrEmail.Text);
    replacements.Add("<% Message %>",this.txtMessage.Text);
    MailMessage msgHtml = message.CreateMailMessage(RECIPIENTS,replacements,new LiteralControl());

我认为这是优雅的解决方案,但我不想引用System.Web.UI.WebControls.MailDeFinition
因为我在winservice.

我的问题是:

>什么是发送批量的最佳方式
来自winservice的电子邮件?
>从gmail发送它是否可行
帐户?或者他们会阻止
我过了一会儿?

谢谢你的帮助.

解决方法

为什么不使用与MailDeFinition使用完全相同的概念?从模板文件加载正文,用另一个列表中的文本替换一些标记 – 邮件合并样式?

您所做的只是对要与模板合并的信息数据集进行预测.加载合并数据,循环合并数据,用当前合并记录替换模板中的标记.将邮件正文设置为当前构建的邮件.将消息附加到消息队列或立即发送,无论您选择哪个.

这不是火箭科学.您已经获得了创建消息的代码,因此只需加载合并数据并循环遍历它.我已经简化了演示这个概念,并且我使用了CSV作为合并数据,并假设没有字段包含任何逗号:

message.IsBodyHtml = true;
message.From = new MailAddress("MailSender@MyCompany.com");
message.Subject = "My bogus email subject";

string[] lines = File.ReadAllLines(@"~\MergeData.csv");
string originalTemplate = File.ReadAllText(@"~\Template.htm");

foreach(string line in lines)
{
    /* Split out the merge data */
    string[] mergeData = line.Split(',');

    /* Reset the template - to revert changes made in prevIoUs loop */
    string currentTemplate = originalTemplate;

    /* Replace the merge tokens with actual data */
    currentTemplate = currentTemplate.Replace("[[FullNametoken]]",mergeData[0]); 
    currentTemplate = currentTemplate.Replace("[[FirstNametoken]]",mergeData[1]);
    currentTemplate = currentTemplate.Replace("[[OtherToken]]",mergeData[2]);

    /*... other token replacements as necessary.
     * tokens can be specified as necessary using whatever Syntax you choose
     * just make sure that there's something denoting the token so you can
     * easily replace it */

    /* Transfer the merged template to the message body */
    message.Body = currentTemplate;

    /* Clear out the address from the prevIoUs loop before adding the current one */
    message.To.Clear();
    message.To.Add(new MailAddress(mergeData[3]));
    client.Send(message);
}

Cocos2d-x 2.2.X 创建新工程的方法(Windows)

Cocos2d-x 2.2.X 创建新工程的方法(Windows)

Cocos2d-X 作为一款跨平台的游戏引擎,版本众多,而每种版本的创建方法各不相同,以下将介绍我初次接触Cocos2d-X,遇到的创建新工程方面的问题,供大家借鉴吧

以下步骤以可以成功运行HelloWord为前提!


1. 安装Python (就是因为这个卡了好久,希望大家看到能少走弯路,我安装的是2.7)

下载地址什么的大家可以百度,有很多

2. 配置环境变量

在我的电脑点击右键-》属性-》高级系统设置-》环境变量.打开后将Python的安装目录添加到Path

3. 在“PATHEXT“的变量值中添加 .PY;.PYM


4. 打开cmd控制台,输入 python,如果出现如下提示,则说明python安装成功。

5. 打开Cmd界面,将目录切换到 ..\cocos2d-x-2.2.X\tools\project-creator文件夹


6. 运行以下指令create_project.py -project myTest -package com.myPackage -language cpp


7. 查看目录你会发现在“Cocos2d-x-2.2.X”文件夹中生成了“projetcs”新文件,同时在“Cocos2d-x-2.2.X/projects”目录中会出现新建的“myTest”新项目。依次打开“ myTest/proj.win32 ”文件夹,“ myTest.sln ”解决方案,单击运行项目。

dependency-injection – 在Windows客户端(WPF)应用程序中执行依赖注入的正确方法

dependency-injection – 在Windows客户端(WPF)应用程序中执行依赖注入的正确方法

我已经习惯了Web应用程序中的IoC / DI – 主要是带有MVC3的Ninject.我的控制器是为我创建的,充满了所有依赖关系,子依赖关系等.

但是,胖客户端应用程序的情况有所不同.我必须创建自己的对象,或者我必须恢复到服务定位器样式方法,我要求内核(可能通过某个接口,允许可测试性)给我一个完整的依赖项对象.

但是,我已经看到Service Locator被描述为反模式的几个地方.

所以我的问题是 – 如果我想在我的胖客户端应用程序中受益于Ninject,是否有更好/更正确的方法来获得所有这些?

>可测试性
>适当的DI / IoC
>可能的耦合量最小

请注意,我不只是在这里讨论MVVM并将视图模型放入视图中.这特别是需要从内核提供存储库类型对象,然后从该存储库中获取的实体注入了功能(当然数据来自数据库,但它们也需要一些对象作为参数,具体取决于状态世界,Ninject知道如何提供).我可以以某种方式做到这一点,而不会将存储库和实体都作为不可测试的混乱吗?

如果有什么不清楚,请告诉我.谢谢!

编辑7月14日

我确信提供的两个答案可能是正确的.然而,我身体的每一根纤维都在对抗这种变化;其中一些可能是由于缺乏知识造成的,但也有一个具体原因导致我无法看到这种做事方式的优雅;

我没有在原始问题中解释得这么好,但问题是我正在编写一个库,将被几个(首先是4-5,可能更晚)的WPF客户端应用程序使用.这些应用程序都在相同的域模型等上运行,因此将它们保存在一个库中是保持DRY的唯一方法.但是,该系统的客户也有可能编写自己的客户端 – 我希望他们有一个简单,干净的库来与之交谈.我不想强迫他们在他们的作文根中使用DI(在他的书中使用像Mark Seeman这样的术语) – 因为与他们相比,只需要新建一个MyCrazySystemAdapter()并使用它就可以使事情复杂化.

现在,MyCrazySystemAdapter(因为我知道人们会在这里不同意我选择的名称)需要由子组件组成,并使用DI组合在一起. MyCrazySystemAdapter本身不需要注入.它是客户端与系统通信所需的唯一接口.所以一个客户应该得到其中的一个,DI就像幕后的魔法一样,而对象是由许多不同的对象使用最佳实践和原则组成的.

我确实意识到这将是一种有争议的想要做事的方式.但是,我也知道将成为此API客户的人员.如果他们发现他们需要学习并连接DI系统,并在他们的应用程序入口点(Composition Root)中提前创建他们的整个对象结构,而不是新建一个对象,他们会给我中指和直接搞乱数据库并以你难以想象的方式搞砸了.

TL; DR:为客户端提供结构合理的API太麻烦了.我的API需要提供一个单独的对象 – 使用DI和适当的实践在幕后构建 – 他们可以使用.现实世界有时胜过为了坚持模式和实践而向后建造一切的愿望.

我建议看一下像Caliburn这样的MVVM框架.它们提供与IoC容器的集成.

基本上,您应该在app.xaml中构建完整的应用程序.如果稍后需要创建某些部分,因为您还不知道在启动时创建它们的所有内容,则将工厂注入接口(请参阅下文)或Func(请参阅Does Ninject support Func (auto generated factory)?)到需要创建此实例的类中.两者都将在下一个Ninject版本中得到本地支持.

例如

public interface IFooFactory { IFoo CreateFoo(); }
public class FooFactory : IFooFactory
{
    private IKernel kernel;
    FooFactory(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public IFoo CreateFoo()
    {
        this.kernel.Get<IFoo>();
    }
}

请注意,工厂实现在逻辑上属于容器配置,而不属于业务类的实现.

关于什么是程序终止自己的进程的正确方法Windows的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于C + +不能获得进程ID(Windows)、c# – 从Windows服务发送电子邮件的正确方法、Cocos2d-x 2.2.X 创建新工程的方法(Windows)、dependency-injection – 在Windows客户端(WPF)应用程序中执行依赖注入的正确方法的相关知识,请在本站寻找。

本文标签: