I am trying to Impersonate and show the Pdf files from another computer in my network. The problem is, webbrowser goes and finds the pdf files but returns as a gray window. I guess it means that it can see the pdf but cannot load or something like that. Because when I change the path it says "The page cannot be reached". I searched about it for a couple days but couldn't find solution. I think there is no problem on impersonation because I can copy or delete or recreate the files with my program but cannot see :D Another interesting thing is when I navigate to a image file, no problem occurs. It works perfectly. Here is my code:
public class Impersonate : IDisposable
{
private static string m_UserName = "myUserName";
private static string m_Password = "mypassword";
private static string m_Domain = "myDomain";
private IntPtr token = IntPtr.Zero;
WindowsImpersonateContext person;
public void Dispose()
{
Undo();
}
public WindowsImpersonateContext Person()
{
bool success = LogonUser(m_userName, m_Domain, m_Password, 9, 0,
ref token)
if(success)
{
person = new WindowsIdentity(token).Impersonate();
return person;
}
}
public void Undo()
{
person.Undo();
Closehandle(token);
}
}
using(Impersonate imp = new Impersonate())
{
imp.Person();
string fpath = "Path_to_the_pdf_file";
newWebBrs.Navigate(new Uri(fpath));
newWebBrs.Show();
newWebbrs.Refresh();
}
The 'using' part is under a button. Any help or idea will be appreciated :D
Related
I am trying to drag from another windows application (EM Client, thunderbird or outlook) onto my form. When an email is dragged from the other application to windows explore it will drop as a file. If the user drags onto my application I would like to get the file contents as a file stream.
I was able to get this working with a UWP app, but I need to get it working in a Windows Form app so it will work in Windows 7.
I have found lots of examples of going the other way (dragging from App to windows).
The thing that makes this so annoying is it is easy in the UWP app.
Here is how I did it in the UWP app, the results of which is I get a new file saved in the roaming folder at name "email.eml":
XAML
<Grid AllowDrop="True" DragOver="Grid_DragOver" Drop="Grid_Drop"
Background="LightBlue" Margin="10,10,10,353">
<TextBlock>Drop anywhere in the blue area</TextBlock>
</Grid>
XAML.CS
namespace App1
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Grid_DragOver(object sender, DragEventArgs e)
{
e.AcceptedOperation = DataPackageOperation.Copy;
}
private async void Grid_Drop(object sender, DragEventArgs e)
{
if (e.DataView.Contains(StandardDataFormats.StorageItems))
{
var items = await e.DataView.GetStorageItemsAsync();
if (items.Count > 0)
{
var storageFile = items[0] as StorageFile;
var reader = (await storageFile.OpenAsync(FileAccessMode.Read));
IBuffer result = new byte[reader.Size].AsBuffer();
var test = await reader.ReadAsync(result, result.Length,Windows.Storage.Streams.InputStreamOptions.None);
Windows.Storage.StorageFolder storageFolder =
Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile = await storageFolder.CreateFileAsync("email.eml",Windows.Storage.CreationCollisionOption.ReplaceExisting);
await Windows.Storage.FileIO.WriteBufferAsync(sampleFile, test);
}
}
}
}
}
I have read every article that that is listed on this answer, plus more:
Trying to implement Drag and Drop gmail attachment from chrome
Basically no matter how I attack it I end up with one of 3 results:
a exception for "Invalid FORMATETC structure (Exception from HRESULT: 0x80040064(DV_E_FORMATETC))"
my MemoryStream is null
I get a security violation
This is the Code that gets a security violation:
MemoryStream ClipboardMemoryStream = new MemoryStream();
BinaryFormatter bft = new BinaryFormatter();
bft.Serialize(ClipboardMemoryStream, e.Data.GetData("FileGroupDescriptorW", false));
byte[] byteArray = ClipboardMemoryStream.ToArray();
My guess is that I need to implement the e.Data.GetData("FileGroupDesciptorW") is returning a IStorage Class, and I need to implement that class, but I am loss on how to do it, plus I am not sure that is the case
e.Data.GetType shows its a marshalbyrefobject, I have attempted to do the Remoting manually, but I got stuck on not having an open channel.
https://learn.microsoft.com/en-us/windows/desktop/api/objidl/nn-objidl-istorage
https://learn.microsoft.com/en-us/windows/desktop/shell/datascenarios#dragging-and-dropping-shell-objects-asynchronously
So After reaching out to a professional for help I have a working example. The trick was to get "FileDescriptorW" working in the Custom ComObject class. You will find a version of this class in the Drag from Outlook example but it does not work when dragging from EM Client, this does.
Here is the Code:
Code is too Big to post
Then You can use it like this:
MyDataObject obj = new MyDataObject(e.Data);
string[] fileNames = { };
//ThunderBird Does a FileDrop
if (obj.GetDataPresent(DataFormats.FileDrop, true))
{
string[] tempFileNames = (string[])obj.GetData(DataFormats.FileDrop);
List<string> tempFileNameList = new List<string>();
foreach(string f in tempFileNames)
{
tempFileNameList.Add(Path.GetFileName(f));
}
fileNames = tempFileNameList.ToArray();
} else if (fileNames.Length == 0)
{
//EM Client uses "FileGroupDescriptorW"
fileNames = (string[])obj.GetData("FileGroupDescriptorW");
}else if (fileNames.Length == 0)
{
//Outlook Uses "FileGroupDescriptor"
fileNames = (string[])obj.GetData("FileGroupDescriptor");
}
int index = 0;
foreach (string f in fileNames)
{
File.WriteAllBytes("C:\\FilePath\\"+f, obj.GetData("FileContents", index).ToArray());
index++;
}
I am using Cefsharp v63.0.3 NuGet package, in C# Windows Form App, I have a file upload button (HTML form input type file). I need the absolute path of the browsed file from file upload button using CefSharp. After looking some articles I found "IDialogHandler" work with file uploading but I am confused how to achieve my goal with this. Please help me out.
Form1.cs
public void InitializeChromium()
{
CefSettings settings = new CefSettings();
settings.CefCommandLineArgs.Add("enable-media-stream", "1");
Cef.Initialize(settings);
chromeBrowser = new ChromiumWebBrowser("localhost/myproject/index.html");
this.Controls.Add(chromeBrowser);
chromeBrowser.DialogHandler = new TempFileDialogHandler();
chromeBrowser.Dock = DockStyle.Fill;
}
TempFileDialogHandler.cs
public class TempFileDialogHandler : IDialogHandler
{
public bool OnFileDialog(IWebBrowser browserControl, IBrowser browser, CefFileDialogMode mode, string title, string defaultFilePath, List<string> acceptFilters, int selectedAcceptFilter, IFileDialogCallback callback)
{
//callback.Continue(selectedAcceptFilter, new List<string> { Path.GetRandomFileName() });
return true;
}
}
Thanks in advance!
I created an application to run, but build an External Tool from the application for Visual Studio. Up until 15.4.0 the application worked fine, but they modified the registry. Based on Microsoft's changes, the External Tools are saved under this sub key:
SOFTWARE\Microsoft\VisualStudio\14.0_Config\External Tools
When you observe the key, you clearly see folders (sub keys) of tools, Guid, Error Lookup, and a couple others that are included with Visual Studio. The issue though, if you manually create the tool in Visual Studio the key information is dumped directly to the root External Tool key.
So if I do either of these approaches:
var user = RegistryKey.OpenBaseKey(RegistryHive.CurrenUser, RegistryView.Default);
var tools = user.OpenSubKey(#"SOFTWARE\Microsoft\VisualStudio\14.0_Config\External Tools", true);
var path = Environment.GetCommandLineArgs()[0];
tools.SetValue("ToolArg", "$(ItemPath)");
tools.SetValue("ToolCmd", path);
tools.SetValue("ToolDir", String.Empty);
tools.SetValue("ToolOpt", 0x12);
tools.SetValue("ToolsSourceKey", String.Empty);
tools.SetValue("ToolTitle", "My Tool");
var user = RegistryKey.OpenBaseKey(RegistryHive.CurrenUser, RegistryView.Default);
var tools = user.OpenSubKey(#"SOFTWARE\Microsoft\VisualStudio\14.0_Config\External Tools", true);
var sub = tools.CreateSubKey("MyTool");
var path = Environment.GetCommandLineArgs()[0];
sub.SetValue("ToolArg", "$(ItemPath)");
sub.SetValue("ToolCmd", path);
sub.SetValue("ToolDir", String.Empty);
sub.SetValue("ToolOpt", 0x12);
sub.SetValue("ToolsSourceKey", String.Empty);
sub.SetValue("ToolTitle", "My Tool");
The tool doesn't appear in the list, or toolbar. Is there something different for Visual Studio 2017 15.5.* that makes this no longer work from code? To make matters worst, the key doesn't always appear when created in Visual Studio 2017 manually.
In Visual Studio 2017, External Tools are stored in a private registry hive in the user's local application data folder. If you run Sysinternals Process Monitor tool, you'll see Visual Studio reading/writing to a key that starts with \REGISTRY\A\ - that's how you know it's a private registry hive. To update them, you will need to load that registry hive by P/Invoking RegLoadAppKey and attaching to the resulting handle. An example of that can be found here:
RegLoadAppKey working fine on 32-bit OS, failing on 64-bit OS, even if both processes are 32-bit
The title may seem misleading at first, but the example given in the question shows exactly how to call RegLoadAppKey and open a sub key underneath.
The next thing you'll have to contend with is finding the private registry hive. Visual Studio stores the private registry hive in a sub folder of the user's local application data folder. The sub folder name will start with Microsoft\VisualStudio\15.0_ and will then be followed by a 32-bit hexadecimal value. I'm not really sure what that value is, or how to gracefully discover it. It's different for each user. My approach was to select the newest folder that starts with "15.0" and assume it's correct. If someone has a better way to identify this folder, I would love to see it.
I've dubbed the combination of version number and hexadecimal string a "version tag". You'll need to keep track of it, because the version tag will be used again as a sub key in the private registry hive.
Putting it all together, I created a VisualStudioContext class that locates the private registry hive and loads the root key.
public class VisualStudioContext : IDisposable
{
public string VersionTag { get; }
public string UserFolder { get; }
public string PrivateRegistryPath { get; }
public SafeRegistryHandle RegistryHandle { get; }
public RegistryKey RootKey { get; }
private static readonly Lazy<VisualStudioContext> LazyInstance = new Lazy<VisualStudioContext>(() => new VisualStudioContext());
public static VisualStudioContext Instance => LazyInstance.Value;
private VisualStudioContext()
{
try
{
string localAppDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string vsFolder = $"{localAppDataFolder}\\Microsoft\\VisualStudio";
var vsFolderInfo = new DirectoryInfo(vsFolder);
DateTime lastDateTime = DateTime.MinValue;
foreach (DirectoryInfo dirInfo in vsFolderInfo.GetDirectories("15.0_*"))
{
if (dirInfo.CreationTime <= lastDateTime)
continue;
UserFolder = dirInfo.FullName;
lastDateTime = dirInfo.CreationTime;
}
if (UserFolder == null)
throw new Exception($"No Visual Studio folders found in \"{vsFolder}\"");
}
catch (Exception ex)
{
throw new Exception("Unable to open Visual Studio folder", ex);
}
VersionTag = Path.GetFileName(UserFolder);
PrivateRegistryPath = $"{UserFolder}\\privateregistry.bin";
int handle = RegistryNativeMethods.RegLoadAppKey(PrivateRegistryPath);
RegistryHandle = new SafeRegistryHandle(new IntPtr(handle), true);
RootKey = RegistryKey.FromHandle(RegistryHandle);
}
public void Dispose()
{
RootKey?.Close();
RegistryHandle?.Dispose();
}
public class Exception : ApplicationException
{
public Exception(string message) : base(message)
{
}
public Exception(string message, Exception innerException) : base(message, innerException)
{
}
}
internal static class RegistryNativeMethods
{
[Flags]
public enum RegSAM
{
AllAccess = 0x000f003f
}
private const int REG_PROCESS_APPKEY = 0x00000001;
// approximated from pinvoke.net's RegLoadKey and RegOpenKey
// NOTE: changed return from long to int so we could do Win32Exception on it
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int RegLoadAppKey(String hiveFile, out int hKey, RegSAM samDesired, int options, int reserved);
public static int RegLoadAppKey(String hiveFile)
{
int hKey;
int rc = RegLoadAppKey(hiveFile, out hKey, RegSAM.AllAccess, REG_PROCESS_APPKEY, 0);
if (rc != 0)
{
throw new Win32Exception(rc, "Failed during RegLoadAppKey of file " + hiveFile);
}
return hKey;
}
}
}
You can use it open the External Tools key like this:
using (var context = VisualStudioContext.Instance)
{
RegistryKey keyExternalTools =
context.RootKey.OpenSubKey($"Software\\Microsoft\\VisualStudio\\{context.VersionTag}\\External Tools", true);
// Do something interesting here
}
It seems you can register external tools in VS 2017 and 2019 by adding a <UserCreatedTool> in the <ExternalTools> section of the Settings/CurrentSettings.vssettings file in the local %AppData% directory of the respective VS version.
Simply create an external tool in VS manually, and search for the entry you created.
This describes how I found out ;)
I am using coded UI platform for automation. If test case fails system automatic take screen shot but once it pass system is not able to capture screenshot of the test case. I am using C# selenium commands in the script.
Environment
Visual studio premium 2012.
I tried following thing.
Enable a log trace in QTAgent32.exe.config ( ).
LoggerOverrideState = HtmlLoggerState.AllActionSnapshot; but getting error in LoggerOverrideState.
[TestMethod]
public void demo2()
{
TestContext.WriteLine("Go to URL\n");
driver.Navigate().GoToUrl("http://www.test.com/");
driver.Manage().Window.Maximize();
// Enter username
TestContext.WriteLine("TestContext Writeline: test context \n");
js.ExecuteScript("arguments[0].setAttribute('value','username')", driver.FindElement(By.XPath("//*[#id='txtUsername']")));
//Enter password
js.ExecuteScript("arguments[0].setAttribute('value','password')", driver.FindElement(By.XPath("//*[#id='txtPassword']")));
// Click on the login Button
js.ExecuteScript("arguments[0].click();", driver.FindElement(By.XPath("//*[#id='btLoginNow']")));
You could put something like the following in your code to take a screenshot at any given point:
Image SubmissionPic = UITestControl.Desktop.CaptureImage();
SubmissionPic.Save(#"C:\AutomatedScreenShots\SubmissionPage_" + TestContext.DataRow["Division"].ToString() + "_" + DateTime.Now.ToString("yyyy-MM-dd") + ".bmp");
Note: The filename formatting I've used above can be changed to whatever suits your needs. I just pulled this code from a test I'd written a while back.
After every Testcase you can call the Take Screen shot in both the case either Pass or Fail
ex.
Suppose Test Method to do Successful Login
#Test
public void ValidUserNamePasswordLoginTest() {
// Your code to do Assertion
}
Now use #AfterMethod in your call which will execute as soon as your test perform
#AfterMethod
public void takeScreenShot(ITestResult testResult) throws IOException
{
if(testResult.getStatus() == ITestResult.SUCCESS)
{
File src = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(src, new File("Screensot\\"+filename+".jpg"));
}
if(testResult.getStatus() == ITestResult.FAILURE)
{
File src = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(src, new File("Screensot\\"+filename+".jpg"));
}
}
Couldn't you just use the [TestCleanup] and create a method using that Attribute that will take a screenshot, that way you will always get a Screenshot not matter the result? Is that what you require?
So, You could so this on the WebDriver setup:
public static IWebDriver SetUp()
{
private static IWebDriver _webDriver;
firingDriver = new EventFiringWebDriver(new ChromeDriver()); //Or whatever driver you want. You could also use the Activator class and create a Generic instance of a WebDriver.
var screenshot = new CustomScreenshot(firingDriver);
firingDriver.ScriptExecuted += screenshot.TakeScreenshotOnExecute;
_webDriver = firingDriver;
return _webDriver;
}
Then for the screenshot something like:
public class CustomScreenshot
{
private IWebDriver _webDriver;
public CustomScreenshot(IWebDriver webDriver)
{
_webDriver = webDriver;
}
public void TakeScreenshotOnExecute(object sender, WebDriverScriptEventArgs e)
{
var filePath = "Where you want to save the file.";
try
{
_webDriver.TakeScreenshot().SaveAsFile(filePath, ImageFormat.Png);
}
catch (Exception)
{
//DO something
}
}
}
The whole issue of taking a screen shot of a browser window & naming it based on unique properties (e.g., browser title, date-time stamp, etc) proved to be extremely difficult because of the tool (CodedUI) not what I wanted to do. I won't editorialize concerning my opinion of the functionality (lack of) of this tool but it is definitely not as robust as Selenium. So how I accomplished this was I got a high level 'browser title' from this-> and used the following for taking & storing the screen shot in my MyTestCleanup() method.
public void MyTestCleanup()
{
//Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.AllThreads;
//--------------------------------------------------------------------------------------------
DateTime time = DateTime.Now;
this.UIMap
var ttest = time.Millisecond.ToString();
var timeSecs = DateTime.Now.Millisecond;
var Window = this;
var ext = ".png";
Image screen = UITestControl.Desktop.CaptureImage();
string dirPath = string.Format("C\\:Users\\smaretick\\Desktop\\SCREENS\\{0}{1}", ttest, ext);
string dirPathN = string.Format("/C copy C:\\Users\\smaretick\\Desktop\\SCREENS\\CUIT.png C:\\Users\\smaretick\\Desktop\\SCREENS\\{0}{1}", ttest, ext);
string dirPathF = string.Format("/C copy C:\\Users\\smaretick\\Desktop\\SCREENS\\CUIT.png C:\\Users\\smaretick\\Desktop\\SCREENS\\{0}{1}{2}", Window, ttest, ext);
//string dirPathF = string.Format("/C copy C:\\Users\\smaretick\\Desktop\\SCREENS\\{0}{1}{2}", Window, ttest, ext);
UITestControl.Desktop.CaptureImage().Save("C:\\Users\\smaretick\\Desktop\\SCREENS\\CUIT.png");
string cmdF = string.Format("C\\:Users\\smaretick\\Desktop\\SCREENS\\{0}{1}", ttest, ext);
Process.Start("CMD.exe", dirPathF);
//--------------------------------------------------------------------------------------------
LogOut();
contact me if you need any more help (scottmaretick51#gmail.com)
I am trying to open a web browser via the following methods. However, when the browser opens the url / file path, the fragment piece gets mangled (from "#anchorName" to "%23anchorName") which does not seem to get processed. So basically, the file opens but does not jump to the appropriate location in the document. Does anyone know how to open the file and have the fragment processed? Any help on this would be greatly appreciated.
an example path to open would be "c:\MyFile.Html#middle"
// calls out to the registry to get the default browser
private static string GetDefaultBrowserPath()
{
string key = #"HTTP\shell\open\command";
using(RegistryKey registrykey = Registry.ClassesRoot.OpenSubKey(key, false))
{
return ((string)registrykey.GetValue(null, null)).Split('"')[1];
}
}
// creates a process and passes the url as an argument to the process
private static void Navigate(string url)
{
Process p = new Process();
p.StartInfo.FileName = GetDefaultBrowserPath();
p.StartInfo.Arguments = url;
p.Start();
}
Thanks to all that tried to help me with this issue. I have since found a solution that works. I have posted it below. All you need to do is call navigate with a local file path containing a fragment. Cheers!
private static string GetDefaultBrowserPath()
{
string key = #"HTTP\shell\open\command";
using(RegistryKey registrykey = Registry.ClassesRoot.OpenSubKey(key, false))
{
return ((string)registrykey.GetValue(null, null)).Split('"')[1];
}
}
private static void Navigate(string url)
{
Process.Start(GetDefaultBrowserPath(), "file:///{0}".FormatWith(url));
}
All you need is:
System.Diagnostics.Process.Start(url);
Try relying on the system to resolve things correctly:
static void Main(string[] args)
{
Process p = new Process();
p.StartInfo.UseShellExecute = true;
p.StartInfo.FileName = "http://stackoverflow.com/questions/tagged/c%23?sort=newest&pagesize=50";
p.StartInfo.Verb = "Open";
p.Start();
}
I am not a C# programmer, but in PHP I would do a urlencode. When I did a Google search on C# and urlencode it gave this page here at StackOverflow... url encoding using C#