【问题标题】:Open a Document as Another User以其他用户身份打开文档
【发布时间】:2011-06-24 01:50:35
【问题描述】:

如何以其他用户身份打开文档?

文档类型未知(可能是 pdf、.xls、.doc、图像等)。 文档在网络共享上,用户名、域和密码都是已知的。

我已经彻底研究了这个问题,我不相信这个问题已经在这里得到了回答。请证明我错了。

这个问题很接近 Open a shared file under another user and domain?

但不幸的是,它将文件打开到文件流,我需要在其关联的应用程序中打开文件。

【问题讨论】:

  • 你的意思是你想从你的程序中打开它?否则标签是干什么用的?
  • 您好 Karl - 我希望我的 winforms 应用程序允许用户使用 openfiledialog 选择一个文档,然后打开该文件。但是,该文件将位于网络共享上。我可以使用模拟显示 openfiledialog。但是一旦用户选择了文件,我就不确定如何打开它,因为启动过程不会在模拟帐户下运行。
  • @Reafidy:您的 WinForms 应用程序是用 C# 编写的吗?为什么要标记这个问题c++
  • @ildjarn 我认为具有 C++ 经验的人可能能够提供解决方案。如果您对此有异议,我很乐意将其删除。
  • @Reafidy :问题是我不能只使用 C++ 发布答案并且在这里可以接受,因为 C# 和 C++ 有非常不同的习语。对于 C++,您将使用 LogonUserEx + ShellExecuteEx(我可以告诉您——为 LogonUserEx 编写 P/Invoke 代码并不好玩)而对于 C#,您将使用 WindowsIdentity.Impersonate + Process.Start(使用 @ 987654328@)。在这种特殊情况下,我真的认为c++ 标签不合适。

标签: c# .net vb.net winforms


【解决方案1】:

查看Runas

runas /user:somedomain\someuser "cmd /c start c:\somedocument.pdf"

它位于C:\Windows\System32\runas.exe

要从 C# 应用程序打开它,您可以使用 Process.Start,并带有适当的标志。

编辑

好吧,您可以完全跳过 Runas 的使用,因为 Process.Start 可以完成相同的工作,并且仍然允许您指定您喜欢的密码(内部硬编码,或通过 UI)。

只需使用cmd.exe /c start <pathToFile> 通过带有关联程序的shell 启动文件:

string cmdPath = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.System),
    "cmd.exe");
string workingDirectory = @"C:\users\public";
string pathToFile = Path.Combine(workingDirectory, "somefile.png");
string arguments = string.Format("/c start {0}", pathToFile);
var password = new SecureString();
foreach (char c in "usersPassword")
    password.AppendChar(c);

var processStartInfo = new ProcessStartInfo()
{
    FileName = cmdPath,
    Arguments = arguments,
    WorkingDirectory = workingDirectory,
    UserName = "TestUser",
    Domain = Environment.MachineName, // Could use domain
    Password = password,
    UseShellExecute = false,
};
Process.Start(processStartInfo);

【讨论】:

  • 要使用用户名和密码启动进程,我必须将 UseShellExecute 设置为 false,然后这样做只允许您运行 .exe。我需要打开文档类型,即 PDF。
  • @Reafidy:runas.exe是一个exe,它又可以运行cmd.exe。 Cmd.exe 有一个start 命令,可以在shell 中打开它。我在想,如果你以不同的用户身份运行 cmd.exe,那么start 将使用同一个用户,但我可能是错的。
  • Runas 不允许输入密码,我不想提示用户输入密码,因为他们无论如何都没有密码。
  • @Reafidy:我在 SO 和其他地方看了很多,发现不使用 shim 有点痛苦。您可以编写自己的 Windows 应用程序,只需调用 Process.Start,用 UseShellExecute = true 替换 cmd.exe。或者您可以忍受弹出的窗口:) 其余选项涉及大量 p/Invoke,并且真的很痛苦,而且我个人会对错误的安全细节感到紧张。一个见stackoverflow.com/questions/33594/…
  • @Reafidy:您将在主应用程序中执行 l/p,而 shim 不需要 l/p,因为您已经以该用户身份运行。垫片将在我的答案示例代码中替换 cmd.exe,以避免弹出窗口。你会在两个不同的程序中做两次Process.Start :)
【解决方案2】:

您是否考虑过简单地将文件复制到本地并以当前用户身份打开它?

推理:

  • 我不知道有任何文档编辑应用程序本机允许以其他用户身份打开文档。因此,您最好启动应用程序以以其他用户身份查看文档。
  • 并非所有应用程序在不同用户下(即使用“运行方式”或 CreateProcessWithLogonW)在同一桌面上执行时都能正常运行,并且大多数处理与文档交互的应用程序都未经过测试以在“运行方式”上下文中使用。
  • 如果另一个副本已经在同一个桌面上运行,一些应用程序会简单地忽略它尝试在不同用户下启动的事实。

*Desktop 用于 Win32 意义。

【讨论】:

  • 操作中哪里提到了“运行方式”功能?如果此答案引用了另一个答案,则在该答案而不是另一个答案上发表评论更为合适。
  • 好点。看起来所有形式的“运行方式”是满足 OP 要求的唯一解决方案......因此将帖子标记为社区 wiki 以允许更好的格式和更多关于“运行方式”场景的 cmets 发布,而无需积累声誉。
  • 我已经考虑了您的第一点 - 我忽略了它,因为我必须编写代码让用户在保存更改后再次上传它。再想一想,虽然我认为你的观点很好。正如您猜想的那样,我正在创建一个文档管理器,您是否认为我应该允许用户保存到临时目录,或者要求他们指定要保存到的目录,而不是作为另一个用户打开?在进行更改之后,他们必须将文档重新上传到服务器……这是您期望看到的吗?
  • 我不希望用户使用其他人的凭据上传文件——这完全是错误的。显然这是您的电话,但请考虑您将如何跟踪谁进行了哪些更改...无论如何,如果您想将所有文档存储在一个用户下共享 - 以特殊用户身份在本地复制,以当前用户身份打开,监控文件更改时在特殊用户下更改和上传。 (除非您出于教育目的,否则请在推出自己的文档管理系统之前检查现有的文档管理系统。)
  • 谢谢,点了。我的意图是为该应用程序设置一个特殊的用户帐户。因此,只有应用程序才能使用共享,在用户复制、编辑和更改文档时更新 sql 数据库。从而防止用户手动更改会导致与数据库不一致的文件。我认为这是不正确的,您希望如何完成?
【解决方案3】:

您可以使用一些具有完全权限的服务器端 Web 服务,您可以尝试调用该 Web 服务来检查是否允许通过的用户编辑文档,如果是,则 Web 服务可以检索该文档并将其发送过去。

这样您就可以在两者之间放置许可层/层,而不必在您的客户端应用程序上处理它。客户端应用程序只需发送用户名,其余的由 webservice 处理

【讨论】:

  • 另一个很好的答案。 Web 服务将需要额外的 IT 工作来设置 Web 服务。我想看看我是否可以先通过文件系统处理它。不过,这是一个不错的选择 - 谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-02-21
  • 2018-01-24
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多