创建一个应用程序

创建一个应用程序

本文介绍了创建一个应用程序,对同一个 Web 应用程序具有多个视图,但具有不同的凭据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望 tp 构建一个 WPF(或 Windows 窗体,如果它可以解决问题),它可以同时显示具有不同凭据的同一网页(它是具有复杂用户操作流程的 Web 应用程序的测试工具).

I want tp build a WPF (or Windows Forms if it can solve the problem) that can display simultaneously the same web page with different credentials (it's testing tool for a web application with complex user action flow).

我现在有一个非常简单的 WPF 应用程序:

I have, by now, a very simple WPF app :

<Window x:Class="TestTool.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="600" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <WebBrowser Margin="8" Source="http://theapptotest" />
        <WebBrowser Margin="8" Source="http://theapptotest" Grid.Column="1" />
    </Grid>
</Window>

这不是应用程序的目标布局,但可以测试我的目标是否可行.

This is not the target layout of the application, but it will allows to test if my goal is possible.

正如预期的那样,该应用程序并排显示同一个 Web 应用程序.但是,如果我登录第一个 Web 浏览器控件,第二个也会登录.我猜是因为 cookie 是为当前用户共享的.

The application, as expected, display side by side the same web app. However, if I log in in the first web brower control, the second is logged in too. I guess it's because the cookies are shared for the current user.

我查看了 WebBrowser 类文档 但我没有发现任何有用的东西.

I checked into the WebBrowser class documentation but I did not find anything useful.

我怎样才能达到我的目标?

How can I reach my goal?

是否可以将一个浏览器与其他浏览器隔离"起来?

Is it possible to "isolate" one webbrowser from the others?

是否可以模拟"用户控件?就像某些应用程序(主要是 Web 浏览器)生成不同的进程一样,我可以在不同的帐户下生成"进程并将其显示在我的主窗口中吗?

Is it possible to "impersonate" a user control? Like some applications (web browser mostly) are spawning different processes, can I "spawn" processes under a different account and display it in my main window ?

请注意,我不必与网页进行交互.我只想通过更改我的应用程序的选项卡(每个用户一个选项卡)来切换用户.

Please note that I don't have to interact with the web pages. I just want to able to switch user by changing a tab of my application (one tab per user).

PS:我不坚持使用 Internet Explorer 引擎,如果存在替代浏览器的解决方案,请告诉我

PS: I'm not stick to Internet Explorer engine, if a solution exists with alternatives browsers, let me know

PS:目标应用程序使用两种身份验证机制.用户可以使用 Windows 帐户或基于自定义表单的身份验证进行身份验证.如果需要,我只能使用表单身份验证(如果我可以插入它,一个单独的 cookie 容器可以完成这项工作).

PS: the target application use two authentication mechanisms. A user can authenticate with Windows account, or a custom Form based authentication. if required, I can use only forms authentication (a separate cookie container would do the job, if I can plug it).

我试图用其他用户凭据生成 Internet Explorer 的新实例,然后通过将其父窗口设置为我的窗体主机之一来附加进程主窗口.然而,这是非常不可靠的(进程经常崩溃,如果任何现有的 IE 实例正在运行,则无法工作等.

I've tried to spawn with other users credentials new instances of Internet Explorer, then attach the process main window by settings its parent to one of my windows form host. This is however, very unreliable (process often crash, can't work if any existing instance of IE is running, etc.

推荐答案

好的,在 Simon Mourrier 之前的回答.

我创建了一个自定义用户控件:

I've created a custom user control:

XML 部分:

<UserControl x:Class="WpfApplication1.AppIsolatedView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" SizeChanged="UserControl_SizeChanged"
             d:DesignHeight="300" d:DesignWidth="300" Loaded="UserControl_Loaded" Unloaded="UserControl_Unloaded">
    <Grid>
        <WindowsFormsHost Margin="12" Name="windowsFormsHost1" />

    </Grid>
</UserControl>

后面有这段代码:

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    public partial class AppIsolatedView : UserControl
    {
        public AppIsolatedView()
        {
            InitializeComponent();
            _panel = new System.Windows.Forms.Panel();
            windowsFormsHost1.Child = _panel;
        }

        string url = "http://theapptotest";
        System.Windows.Forms.Panel _panel;
        Process _process;

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (IsInDesignModeStatic) return; // Avoid consumer of the control to explode when in design mode

            ProcessStartInfo psi = new ProcessStartInfo("iexplore.exe", "-noframemerging -private \"" + url + "\"");
            _process = Process.Start(psi);
            _process.WaitForInputIdle();
            Thread.Sleep(2000);
            SetParent(_process.MainWindowHandle, _panel.Handle);

            // remove control box
            int style = GetWindowLong(_process.MainWindowHandle, GWL_STYLE);
            style = style & ~WS_CAPTION & ~WS_THICKFRAME;
            SetWindowLong(_process.MainWindowHandle, GWL_STYLE, style);

            // resize embedded application & refresh
            ResizeEmbeddedApp();

        }

        private void UserControl_Unloaded(object sender, RoutedEventArgs e)
        {
            if (_process != null)
            {
                _process.Refresh();
                _process.Close();
            }

        }

        private void ResizeEmbeddedApp()
        {
            if (_process == null)
                return;

            SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, (int)_panel.ClientSize.Width, (int)_panel.ClientSize.Height, SWP_NOZORDER | SWP_NOACTIVATE);
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            Size size = base.MeasureOverride(availableSize);
            ResizeEmbeddedApp();
            return size;
        }

        private static bool? _isInDesignMode;

        /// <summary>
        /// Gets a value indicating whether the control is in design mode (running in Blend
        /// or Visual Studio).
        /// </summary>
        public static bool IsInDesignModeStatic
        {
            get
            {
                if (!_isInDesignMode.HasValue)
                {
#if SILVERLIGHT
            _isInDesignMode = DesignerProperties.IsInDesignTool;
#else
                    var prop = DesignerProperties.IsInDesignModeProperty;
                    _isInDesignMode
                        = (bool)DependencyPropertyDescriptor
                        .FromProperty(prop, typeof(FrameworkElement))
                        .Metadata.DefaultValue;
#endif
                }

                return _isInDesignMode.Value;
            }
        }

        private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            ResizeEmbeddedApp();

        }
        #region pinvoke stuff
        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32")]
        private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent);

        [DllImport("user32")]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

        private const int SWP_NOZORDER = 0x0004;
        private const int SWP_NOACTIVATE = 0x0010;
        private const int GWL_STYLE = -16;
        private const int WS_CAPTION = 0x00C00000;
        private const int WS_THICKFRAME = 0x00040000;
        #endregion
        }
}

我必须作弊:

  • 我必须在触发 IExplore.exe 时添加 -noframemerging 以避免内部 IE 会话共享.
  • 启动进程后我必须睡一会儿.不知道确切的原因,但 MainWindowHandle 属性在几毫秒后发生变化(我猜 iexplore 有一个引导程序进程可以连接到现有进程或生成一个新进程,带有新句柄,或类似这个).
  • I have to add -noframemerging when firing IExplore.exe in order to avoid internal IE session sharing.
  • I have to sleep a bit after having launch the process. Don't know exactly why, but the MainWindowHandle property change after some few milliseconds (I guess iexplore has a bootstrapper process to either connect to existing process or spawn a new one, with new handle, or something like this).

我仍然需要扩展用户控件以接受输入参数(url 是硬编码的),但想法就在这里.我只需要专注于应用本身.

I still have to extend the user control to accept input parameters (url is hardcoded), but the idea is here. I just have to concentrate on the app itself.

这篇关于创建一个应用程序,对同一个 Web 应用程序具有多个视图,但具有不同的凭据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 10:20