我有一个用 .NET 编写的应用程序。它需要保持运行并访问 UAC 对话窗口打开的桌面,并使用键盘和鼠标事件与该桌面交互。
它有点像 VNC 程序。想象一下,您正在运行一个 VNC 程序并弹出一个 UAC 窗口,您希望您的 VNC 程序仍然能够控制 带有 UAC 窗口的桌面,以便用户可以移动鼠标并单击UAC 对话框上的确定按钮。谁能告诉我该怎么做?
谢谢
最佳答案
我建议您先阅读 documentation .我想也许你可以打开窗口站并将你的进程附加到它,但我对 Windows 的这个领域不是很熟悉。
编辑 1:
在 Windows XP 中,当以 SYSTEM 身份运行时,我能够通过 OpenDesktop 访问安全桌面(“winlogon”);安全桌面上的 ACL 只允许访问 SYSTEM 帐户。打开它后,我可以一一列举上面的 window ,尽管只有少数几个。也许您可以设置一个窗口 Hook 并监听特定对话框的创建。我不确定 Vista 是否更改了此模型,所以它可能不起作用;我面前没有用于测试的 Vista 机器。
编辑 2:
好的,我找到了大部分可用的东西(在 Windows 7 上测试过)。首先,您必须有一个以 SYSTEM 身份运行的服务。从该服务,您需要在用户 session 中启动一个单独的应用程序。为此,枚举所有查找 winlogon.exe 的进程,打开其 token ,然后创建 ProcessAsUser。为 STARTUPINFO 的 lpDesktop 参数指定“WinSta0\Winlogon”。现在,您在“Winlogon”桌面上的用户 session 中有一个以 SYSTEM 身份运行的进程。在新流程中,您可以为所欲为;我用 EnumDesktopWindows 做了一个快速测试,我能够获得各种 UAC 相关窗口的窗口类和文本(“$$$Secure UAP Background Window”、“$$$Secure UAP Background Fake Client Window”等)。不过,我不确定如何确定何时显示 UAC 提示;作为快速破解,您可以每 100 毫秒运行一个循环来寻找 UAC 窗口或其他东西。如果有帮助,我可以粘贴一些代码。
编辑 3:
好的。我编写了一个采用以下参数的 Win32 服务:
/install - 安装服务
/uninstall - 卸载服务
/service - 作为服务运行;通过 SCM 调用
/client - 作为客户端运行;通过 CreateProcessAsUser 调用
唯一有趣的代码是/service 和/client 模式。
在/service 模式下,它通过 EnumProcesses 和 GetModuleFileNameEx 枚举正在运行的进程,寻找“winlogon.exe”。当它找到一个时,它会打开它的 token 并通过 CreateProcessAsUser 在/client 模式下启动自己:
HANDLE hProcess = ...;
// winlogon.exe runs as SYSTEM in user's session; we need to run the same way
HANDLE hToken = NULL;
if(OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &hToken))
{
TCHAR szCommandLine[MAX_PATH];
GetModuleFileName(NULL, szCommandLine, MAX_PATH);
PathQuoteSpaces(szCommandLine);
// run in /client mode
_tcscat_s(szCommandLine, MAX_PATH, _T(" /client"));
STARTUPINFO StartupInfo;
ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
StartupInfo.cb = sizeof(STARTUPINFO);
// run on the Winlogon desktop
StartupInfo.lpDesktop = _T("WinSta0\\Winlogon");
PROCESS_INFORMATION ProcessInformation;
ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
if(CreateProcessAsUser(hToken, NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInformation))
{
CloseHandle(ProcessInformation.hThread);
ProcessInformation.hThread = NULL;
CloseHandle(ProcessInformation.hProcess);
ProcessInformation.hProcess = NULL;
}
CloseHandle(hToken);
hToken = NULL;
}
在/client 模式下,它通过一系列 FindWindow 和 FindWindowEx 调用单击 UAC 提示符上的"is"按钮。您可以使用 Spy++ 找出窗口层次结构。
HWND hWnd = ...;
HWND hWndButton = FindWindowEx(hWnd, NULL, _T("Button"), NULL);
if(hWndButton != NULL)
{
// see if this is the "Yes" button
TCHAR szText[32];
if(GetWindowText(hWndButton, szText, 32) && _tcsicmp(szText, _T("&Yes")) == 0)
{
// click it
SendMessage(hWndButton, BM_CLICK, 0, 0);
}
}
我测试这个的方法是坚持 sleep (5000);在/client 代码中。然后我启动服务并立即执行触发 UAC 提示的操作(即运行 regedit)。 5 秒后/client 代码将唤醒并找到并单击"is"按钮。可以在Winlogon桌面上运行其他进程; cmd.exe 和 spyxx.exe (Spy++) 最有用。不幸的是,explorer.exe 在 Winlogon 桌面上运行时会出现很多问题,而且不是很有用。要进入 Winlogon 桌面,您可以运行 regedit,然后按 Alt+Tab 切换到其他应用程序。如果你想变得有趣,你可以编写自己的桌面切换实用程序(使用 SwitchDesktop 函数),这样你就不必触发 UAC 提示符就可以进入 Winlogon 桌面。如果你真的很喜欢,你可以设置一个全局窗口钩子(Hook)来监控窗口的创建;当即将显示 UAC 对话框时,您可以准备单击其"is"按钮。不过,我并没有走那么远。
关于.net - 如何在显示 UAC 对话框窗口时运行我的应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2821667/
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende