SEBWIN-312: Implemented basic handling of whitelisted applications.
This commit is contained in:
parent
3d55bd6ff4
commit
35dd3dd4c2
19 changed files with 313 additions and 33 deletions
|
@ -30,19 +30,29 @@ namespace SafeExamBrowser.Applications.Contracts
|
|||
/// </summary>
|
||||
event IconChangedEventHandler IconChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the application instance has been terminated.
|
||||
/// </summary>
|
||||
event InstanceTerminatedEventHandler Terminated;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the name or (document) title of the application instance has changed.
|
||||
/// </summary>
|
||||
event NameChangedEventHandler NameChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the application instance has been terminated.
|
||||
/// </summary>
|
||||
event InstanceTerminatedEventHandler Terminated;
|
||||
|
||||
/// <summary>
|
||||
/// Makes this instance the currently active one and brings it to the foreground.
|
||||
/// </summary>
|
||||
void Activate();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the application instance.
|
||||
/// </summary>
|
||||
void Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Terminates the application instance.
|
||||
/// </summary>
|
||||
void Terminate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,16 +14,19 @@ using SafeExamBrowser.Applications.Contracts;
|
|||
using SafeExamBrowser.Core.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Settings.Applications;
|
||||
using SafeExamBrowser.WindowsApi.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Applications
|
||||
{
|
||||
public class ApplicationFactory : IApplicationFactory
|
||||
{
|
||||
private ILogger logger;
|
||||
private IModuleLogger logger;
|
||||
private IProcessFactory processFactory;
|
||||
|
||||
public ApplicationFactory(ILogger logger)
|
||||
public ApplicationFactory(IModuleLogger logger, IProcessFactory processFactory)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.processFactory = processFactory;
|
||||
}
|
||||
|
||||
public FactoryResult TryCreate(WhitelistApplication settings, out IApplication application)
|
||||
|
@ -62,7 +65,7 @@ namespace SafeExamBrowser.Applications
|
|||
{
|
||||
var icon = new IconResource { Type = IconResourceType.Embedded, Uri = new Uri(executablePath) };
|
||||
var info = new ApplicationInfo { IconResource = icon, Name = settings.DisplayName, Tooltip = settings.Description ?? settings.DisplayName };
|
||||
var application = new ExternalApplication(executablePath, info);
|
||||
var application = new ExternalApplication(executablePath, info, logger.CloneFor(settings.DisplayName), processFactory);
|
||||
|
||||
return application;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Applications
|
||||
{
|
||||
internal class ApplicationInstanceIdentifier : InstanceIdentifier
|
||||
{
|
||||
internal int ProcessId { get; private set; }
|
||||
|
||||
public ApplicationInstanceIdentifier(int processId)
|
||||
{
|
||||
ProcessId = processId;
|
||||
}
|
||||
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
if (other is ApplicationInstanceIdentifier id)
|
||||
{
|
||||
return ProcessId == id.ProcessId;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ProcessId.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"({ProcessId})";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,38 +6,64 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Applications.Contracts.Events;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.WindowsApi.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Applications
|
||||
{
|
||||
internal class ExternalApplication : IApplication
|
||||
{
|
||||
private string executablePath;
|
||||
private IModuleLogger logger;
|
||||
private IList<IApplicationInstance> instances;
|
||||
private IProcessFactory processFactory;
|
||||
|
||||
public ApplicationInfo Info { get; }
|
||||
|
||||
public event InstanceStartedEventHandler InstanceStarted;
|
||||
|
||||
internal ExternalApplication(string executablePath, ApplicationInfo info)
|
||||
internal ExternalApplication(string executablePath, ApplicationInfo info, IModuleLogger logger, IProcessFactory processFactory)
|
||||
{
|
||||
this.executablePath = executablePath;
|
||||
this.Info = info;
|
||||
this.logger = logger;
|
||||
this.instances = new List<IApplicationInstance>();
|
||||
this.processFactory = processFactory;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
|
||||
// Nothing to do here for now.
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
|
||||
logger.Info("Starting application...");
|
||||
|
||||
var process = processFactory.StartNew(executablePath);
|
||||
var id = new ApplicationInstanceIdentifier(process.Id);
|
||||
var instance = new ExternalApplicationInstance(id, logger.CloneFor($"{Info.Name} {id}"), process);
|
||||
|
||||
instance.Initialize();
|
||||
instances.Add(instance);
|
||||
InstanceStarted?.Invoke(instance);
|
||||
}
|
||||
|
||||
public void Terminate()
|
||||
{
|
||||
|
||||
if (instances.Any())
|
||||
{
|
||||
logger.Info("Terminating application...");
|
||||
}
|
||||
|
||||
foreach (var instance in instances)
|
||||
{
|
||||
instance.Terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
115
SafeExamBrowser.Applications/ExternalApplicationInstance.cs
Normal file
115
SafeExamBrowser.Applications/ExternalApplicationInstance.cs
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Timers;
|
||||
using SafeExamBrowser.Applications.Contracts;
|
||||
using SafeExamBrowser.Applications.Contracts.Events;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.WindowsApi.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Applications
|
||||
{
|
||||
internal class ExternalApplicationInstance : IApplicationInstance
|
||||
{
|
||||
private const int ONE_SECOND = 1000;
|
||||
|
||||
private ILogger logger;
|
||||
private string name;
|
||||
private IProcess process;
|
||||
private Timer timer;
|
||||
|
||||
public InstanceIdentifier Id { get; }
|
||||
public string Name { get; }
|
||||
|
||||
public event IconChangedEventHandler IconChanged { add { } remove { } }
|
||||
public event NameChangedEventHandler NameChanged;
|
||||
public event InstanceTerminatedEventHandler Terminated;
|
||||
|
||||
public ExternalApplicationInstance(InstanceIdentifier id, ILogger logger, IProcess process)
|
||||
{
|
||||
this.Id = id;
|
||||
this.logger = logger;
|
||||
this.process = process;
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
var success = process.TryActivate();
|
||||
|
||||
if (!success)
|
||||
{
|
||||
logger.Warn("Failed to activate instance!");
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
process.Terminated += Process_Terminated;
|
||||
|
||||
timer = new Timer(ONE_SECOND);
|
||||
timer.Elapsed += Timer_Elapsed;
|
||||
timer.Start();
|
||||
|
||||
logger.Info("Initialized application instance.");
|
||||
}
|
||||
|
||||
public void Terminate()
|
||||
{
|
||||
const int MAX_ATTEMPTS = 5;
|
||||
const int TIMEOUT_MS = 500;
|
||||
|
||||
timer.Elapsed -= Timer_Elapsed;
|
||||
timer?.Stop();
|
||||
|
||||
var terminated = process.HasTerminated;
|
||||
|
||||
for (var attempt = 0; attempt < MAX_ATTEMPTS && !terminated; attempt++)
|
||||
{
|
||||
terminated = process.TryClose(TIMEOUT_MS);
|
||||
}
|
||||
|
||||
for (var attempt = 0; attempt < MAX_ATTEMPTS && !terminated; attempt++)
|
||||
{
|
||||
terminated = process.TryKill(TIMEOUT_MS);
|
||||
}
|
||||
|
||||
if (terminated)
|
||||
{
|
||||
logger.Info("Successfully terminated application instance.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn("Failed to terminate application instance!");
|
||||
}
|
||||
}
|
||||
|
||||
private void Process_Terminated(int exitCode)
|
||||
{
|
||||
logger.Info($"Application instance has terminated with exit code {exitCode}.");
|
||||
Terminated?.Invoke(Id);
|
||||
}
|
||||
|
||||
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
var success = process.TryGetWindowTitle(out var title);
|
||||
var hasChanged = name?.Equals(title, StringComparison.Ordinal) != true;
|
||||
|
||||
// TODO: Use this and ensure log window doesn't hang on shutdown (if it is open)!
|
||||
// logger.Warn($"Success: {success} HasChanged: {hasChanged}");
|
||||
|
||||
if (success && hasChanged)
|
||||
{
|
||||
name = title;
|
||||
NameChanged?.Invoke(name);
|
||||
}
|
||||
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -55,7 +55,9 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ApplicationFactory.cs" />
|
||||
<Compile Include="ApplicationInstanceIdentifier.cs" />
|
||||
<Compile Include="ExternalApplication.cs" />
|
||||
<Compile Include="ExternalApplicationInstance.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -75,6 +77,10 @@
|
|||
<Project>{30b2d907-5861-4f39-abad-c4abf1b3470e}</Project>
|
||||
<Name>SafeExamBrowser.Settings</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.WindowsApi.Contracts\SafeExamBrowser.WindowsApi.Contracts.csproj">
|
||||
<Project>{7016f080-9aa5-41b2-a225-385ad877c171}</Project>
|
||||
<Name>SafeExamBrowser.WindowsApi.Contracts</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -53,9 +53,9 @@ namespace SafeExamBrowser.Browser
|
|||
|
||||
public event DownloadRequestedEventHandler ConfigurationDownloadRequested;
|
||||
public event IconChangedEventHandler IconChanged;
|
||||
public event InstanceTerminatedEventHandler Terminated;
|
||||
public event NameChangedEventHandler NameChanged;
|
||||
public event PopupRequestedEventHandler PopupRequested;
|
||||
public event InstanceTerminatedEventHandler Terminated;
|
||||
|
||||
public BrowserApplicationInstance(
|
||||
AppConfig appConfig,
|
||||
|
@ -85,13 +85,13 @@ namespace SafeExamBrowser.Browser
|
|||
window?.BringToForeground();
|
||||
}
|
||||
|
||||
internal void Initialize()
|
||||
public void Initialize()
|
||||
{
|
||||
InitializeControl();
|
||||
InitializeWindow();
|
||||
}
|
||||
|
||||
internal void Terminate()
|
||||
public void Terminate()
|
||||
{
|
||||
window?.Close();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace SafeExamBrowser.Browser
|
|||
{
|
||||
internal class BrowserInstanceIdentifier : InstanceIdentifier
|
||||
{
|
||||
public int Value { get; private set; }
|
||||
internal int Value { get; private set; }
|
||||
|
||||
public BrowserInstanceIdentifier(int id)
|
||||
{
|
||||
|
|
|
@ -96,7 +96,8 @@ namespace SafeExamBrowser.Client
|
|||
taskbar = BuildTaskbar();
|
||||
terminationActivator = new TerminationActivator(ModuleLogger(nameof(TerminationActivator)));
|
||||
|
||||
var applicationFactory = new ApplicationFactory(ModuleLogger(nameof(ApplicationFactory)));
|
||||
var processFactory = new ProcessFactory(ModuleLogger(nameof(ProcessFactory)));
|
||||
var applicationFactory = new ApplicationFactory(ModuleLogger(nameof(ApplicationFactory)), processFactory);
|
||||
var applicationMonitor = new ApplicationMonitor(TWO_SECONDS, ModuleLogger(nameof(ApplicationMonitor)), nativeMethods, new ProcessFactory(ModuleLogger(nameof(ProcessFactory))));
|
||||
var displayMonitor = new DisplayMonitor(ModuleLogger(nameof(DisplayMonitor)), nativeMethods, systemInfo);
|
||||
var explorerShell = new ExplorerShell(ModuleLogger(nameof(ExplorerShell)), nativeMethods);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" x:Name="ApplicationName" Background="#99D3D3D3" FontWeight="Bold" Padding="5" TextAlignment="Center" />
|
||||
<ContentControl Grid.Row="1" x:Name="ApplicationButton" />
|
||||
<ContentControl Grid.Row="1" x:Name="ApplicationButton" FontWeight="Bold" />
|
||||
<StackPanel Grid.Row="2" x:Name="InstancePanel" Background="#99D3D3D3" Orientation="Vertical" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
|
@ -23,6 +23,6 @@
|
|||
</ScrollViewer>
|
||||
</Border>
|
||||
</Popup>
|
||||
<Button x:Name="Button" Background="{StaticResource BackgroundBrush}" Click="Button_Click" Padding="4" Template="{StaticResource TaskbarButton}" Width="50" />
|
||||
<Button x:Name="Button" Background="{StaticResource BackgroundBrush}" Padding="4" Template="{StaticResource TaskbarButton}" Width="50" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" x:Name="ApplicationName" Background="#99D3D3D3" FontWeight="Bold" Padding="5" TextAlignment="Center" />
|
||||
<ContentControl Grid.Row="1" x:Name="ApplicationButton" />
|
||||
<ContentControl Grid.Row="1" x:Name="ApplicationButton" FontWeight="Bold" />
|
||||
<StackPanel Grid.Row="2" x:Name="InstancePanel" Background="#99D3D3D3" Orientation="Vertical" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
|
@ -23,6 +23,6 @@
|
|||
</ScrollViewer>
|
||||
</Border>
|
||||
</Popup>
|
||||
<Button x:Name="Button" Background="{StaticResource BackgroundBrush}" Click="Button_Click" Padding="4" Template="{StaticResource TaskbarButton}" Width="60" />
|
||||
<Button x:Name="Button" Background="{StaticResource BackgroundBrush}" Padding="4" Template="{StaticResource TaskbarButton}" Width="60" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
|
@ -40,6 +40,12 @@ namespace SafeExamBrowser.WindowsApi.Contracts
|
|||
/// </summary>
|
||||
event ProcessTerminatedEventHandler Terminated;
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to activate the process (i.e. bring its main window to the foreground). This may only work for interactive processes which have
|
||||
/// a main window. Returns <c>true</c> if the process was successfully activated, otherwise <c>false</c>.
|
||||
/// </summary>
|
||||
bool TryActivate();
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to gracefully terminate the process by closing its main window. This will only work for interactive processes which have a main
|
||||
/// window. Optionally waits the specified amount of time for the process to terminate. Returns <c>true</c> if the process has terminated,
|
||||
|
@ -47,6 +53,12 @@ namespace SafeExamBrowser.WindowsApi.Contracts
|
|||
/// </summary>
|
||||
bool TryClose(int timeout_ms = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to retrieve the title of the main window of the process. This will only work if for interactive processes which have a main
|
||||
/// window. Returns <c>true</c> if the title was successfully retrieved, otherwise <c>false</c>.
|
||||
/// </summary>
|
||||
bool TryGetWindowTitle(out string title);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to immediately kill the process. Optionally waits the specified amount of time for the process to terminate. Returns <c>true</c>
|
||||
/// if the process has terminated, otherwise <c>false</c>.
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace SafeExamBrowser.WindowsApi
|
|||
internal class Kernel32
|
||||
{
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
|
|
|
@ -11,9 +11,12 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.WindowsApi.Constants;
|
||||
using SafeExamBrowser.WindowsApi.Contracts;
|
||||
using SafeExamBrowser.WindowsApi.Contracts.Events;
|
||||
using SafeExamBrowser.WindowsApi.Types;
|
||||
|
||||
namespace SafeExamBrowser.WindowsApi
|
||||
{
|
||||
|
@ -62,6 +65,31 @@ namespace SafeExamBrowser.WindowsApi
|
|||
this.originalNameInitialized = true;
|
||||
}
|
||||
|
||||
public bool TryActivate()
|
||||
{
|
||||
try
|
||||
{
|
||||
var success = User32.BringWindowToTop(process.MainWindowHandle);
|
||||
var placement = new WINDOWPLACEMENT();
|
||||
|
||||
placement.length = Marshal.SizeOf(placement);
|
||||
User32.GetWindowPlacement(process.MainWindowHandle, ref placement);
|
||||
|
||||
if (placement.showCmd == (int) ShowWindowCommand.ShowMinimized)
|
||||
{
|
||||
success &= User32.ShowWindow(process.MainWindowHandle, (int) ShowWindowCommand.Restore);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error("Failed to activate process!", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryClose(int timeout_ms = 0)
|
||||
{
|
||||
try
|
||||
|
@ -90,6 +118,25 @@ namespace SafeExamBrowser.WindowsApi
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool TryGetWindowTitle(out string title)
|
||||
{
|
||||
title = default(string);
|
||||
|
||||
try
|
||||
{
|
||||
process.Refresh();
|
||||
title = process.MainWindowTitle;
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error("Failed to retrieve title of main window!", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryKill(int timeout_ms = 0)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Management" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -91,6 +92,7 @@
|
|||
<Compile Include="Types\RECT.cs" />
|
||||
<Compile Include="Types\STARTUPINFO.cs" />
|
||||
<Compile Include="Types\Window.cs" />
|
||||
<Compile Include="Types\WINDOWPLACEMENT.cs" />
|
||||
<Compile Include="User32.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
22
SafeExamBrowser.WindowsApi/Types/WINDOWPLACEMENT.cs
Normal file
22
SafeExamBrowser.WindowsApi/Types/WINDOWPLACEMENT.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Drawing;
|
||||
|
||||
namespace SafeExamBrowser.WindowsApi.Types
|
||||
{
|
||||
internal struct WINDOWPLACEMENT
|
||||
{
|
||||
public int length;
|
||||
public int flags;
|
||||
public int showCmd;
|
||||
public Point ptMinPosition;
|
||||
public Point ptMaxPosition;
|
||||
public Rectangle rcNormalPosition;
|
||||
}
|
||||
}
|
|
@ -24,7 +24,6 @@ namespace SafeExamBrowser.WindowsApi
|
|||
internal static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CloseClipboard();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
|
@ -34,15 +33,15 @@ namespace SafeExamBrowser.WindowsApi
|
|||
internal static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags, uint dwDesiredAccess, IntPtr lpsa);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool BringWindowToTop(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool EmptyClipboard();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool EnumDesktops(IntPtr hwinsta, EnumDesktopDelegate lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool EnumWindows(EnumWindowsDelegate enumProc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
|
@ -60,6 +59,9 @@ namespace SafeExamBrowser.WindowsApi
|
|||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool GetUserObjectInformation(IntPtr hObj, int nIndex, IntPtr pvInfo, int nLength, ref int lpnLengthNeeded);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
|
||||
|
||||
|
@ -70,15 +72,12 @@ namespace SafeExamBrowser.WindowsApi
|
|||
internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool OpenClipboard(IntPtr hWndNewOwner);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
|
@ -91,25 +90,21 @@ namespace SafeExamBrowser.WindowsApi
|
|||
internal static extern IntPtr SetWindowsHookEx(HookType hookType, HookDelegate lpfn, IntPtr hMod, uint dwThreadId);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool SwitchDesktop(IntPtr hDesktop);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, ref RECT pvParam, SPIF fWinIni);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SystemParametersInfo(SPI uiAction, int uiParam, string pvParam, SPIF fWinIni);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool UnhookWinEvent(IntPtr hWinEventHook);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool UnhookWindowsHookEx(IntPtr hhk);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue