I was hoping for maybe some suggestions on how to get selenium working in following case. I am trying to implement smooth update of chromedriver with limited permissions on environment.
The problem occurs when Google Chrome is upgraded by third party to a newer version and the chromedriver stays the old version. The real problem is because the new version of application requires a new build, new documentation ... etc.
During development I run VS as admin, so no problem when downloading chromedriver.exe. Also normal user can execute it since it is already downloaded.
I tried different ways:
Embed driver into dll, extract it when needed, delete it when not needed any more. The problem is I don't have sufficient permissions to extract or create. I need admin privileges but I don't have it.
Load driver from local/remote location. Here is the problem that the program (chromedriver.exe) is blocked by a group policy.
Loading driver using DriverManager. Since VS is run as Admin, chrome driver detects version and download it beside application. It stop working when applicaiton is not runned as Admin. I tried to download it into users Downloads folder but it is blocked by a group policy.
There is another idea which I am not sure if it is possible. Emmbed chromedriver.exe as Resource in dll and call it. Here is the problem that I need a path for Constructor (ChromeDriver), but I don't have it since it is packed in dll. The idea is when browser is upgraded, new dll is built with new chrome driver and added as dll beside "first" application.
The question is: is it possible to implement the 4th idea or do you maybe have another idea/example?
Related
I'm working on a MacOS application built in Unity3D. I'm using a native file browser plugin to open native MacOS file dialogs for selecting files.
In order to generate PDFs, my app relies on using Chromium's Headless/command line functionality.
On Windows, I can easily get the path to the included Microsoft Edge as that's standard, but on Mac, unless I guess and check (which I already do), there isn't a way to guarantee a Mac user has a Chromium-based browser installed.
So I intend on allowing the user to set the path manually by selecting the .app file with a file dialog. But even when I specify .app to be a valid extension, they still don't appear selectable.
I assume this is some sort of MacOS-specific limitation or default permissions, though I can't find much info on this online.
Using C#/DotNet s there any way of allowing this behavior as needed?
For some more info: I'm just running the application using System.Diagnostics.Process.Start() with command line arguments.
Based on my experiments searching for Google Chrome (though Edge or Opera are just as usable), the path I'm looking for is:
/Applications/ {{APP NAME}}.app/Contents/MacOS/{{APP NAME}}
Because Contents isn't accessible by most users, I figured I would just automatically go in and grab the binary with the correct name.
I know I could include some lightweight version of ChromeDriver with my app, but I'd rather keep everything as self-contained as possible, especially as so many people already have Chrome (or Opera, Edge, etc) installed. The challenge is that not everyone has it installed in the same place, hence my need to make it customizable.
Any ideas or help would be appreciated!
Thanks!
After doing some testing: It seems that this limitation is only when running inside the Unity Editor. Once the app is built into a standalone Mac application, the file dialog does allow the selection of .app files and it works as expected.
Not a 100% solution to this problem, but definitely clears up some concerns.
I'm having a hard time trying to figure out what is causing this odd issue.
So I've created a very basic .msi by following the WiX v3 Setup Project documentation, pretty much just the provided template, but no matter what i try, whenever i go to uninstall it via the Windows 10 Apps & Features interface, i keep getting this:
However, when i uninstall via Control Panel\Programs\Programs and Features or by right-clicking and hitting Uninstall in the .msi's Context Menu, it uninstalls fine.
What am i missing here, should i be implementing something within the installer project to support the Apps & Features uninstall?
Thanks in advance.
AVG Anti Virus: In this case it was AVG anti virus. Uninstalling this product made the uninstall run correctly when
invoked from the new settings GUI in Windows 10.
Blocking: Errors like these often mean something is blocking the uninstall. Please disable or uninstall any anti-virus and / or security software and try again.
General Check List: Please check this answer for a "deployment check list" or "mnemonic" to debug similar problems: Deployment Mnemonic (mid-page). Also see comments above. Sweep for malware with Windows Defender Offline.
Microsoft Tips: Windows cannot access the specified device, path, or file...
Make Log File: To debug, always make an MSI log file:
FireGiant: MSI log "how-to"
Installsite: MSI log "how-to"
Exact Error Message: "Error: Windows cannot access the specified device, path, or file. You may not have the appropriate permission to access the item"
I've got an application written with C# which is installed via InnoSetup.
With enabled Controlled Folder Access of Windows 10's Defender, the setup fails to create a desktop icon (showing the message PersistFile::Save failed, code 0x80070002) -- despite running with administrative privileges.
Furthermore the installed application (which is NOT run with administrative privileges) fails to write to folders of the user, e.g. Documents.
This happens even for new files or folders, which do not overwrite anything existing. For ransomware protection I'd expect that only modifying existing files is considered dangerous.
The first question that comes to my mind is: Why is my application considered to be harmful and is thus being blocked?
I've done extensive research to get an answer, but could not find anything that helps:
Web resources from Mircosoft describing which applications are considered harmful and why cannot be found -- only guesswork there.
Signing my application with an Extended Validation Certificate (which helps suppressing SmartScreen warnings) does not change Windows Defender's behavior.
I let the Windows App Certification Kit analyze the installer -- which reported several warnings and one critical error. I fixed all issues the Kit complained about (except the warning regarding /SAFESEH which is not possible with InnoSetup), but this did not change Windows Defender's behavior regarding access blocking.
So, my refined question is: How can I bypass the access blocking of Windows Defender for my setup and my application in a valid way?
To give insights to the problem and to provide a basis for experiments I've set up a small sample application in C# which
creates new (and afterwards removes) directories in the public desktop path, user's desktop path, pulic documents path and user's documents path
is bundled by an InnoSetup script to a signed installer
Using Visual Studio to build the solution and InnoSetup to package the build, it should be easy to reproduce the behavior with enabled Controlled Folder Access. (Make sure to have a look at README.md for a description of the build steps!)
Please check out the sample project.
I have a click-once application, which is correctly signed, correctly configured and installs itself without any problem.
It is set to run offline, but install from a specific URL, and if I download and run the setup.exe, it installs updates.
So, it's basically all working... except I cannot print out the version number, or trigger an update from in code. If I try, I get the dreaded: 'Application identity is not set.'
2017-01-10 13:43:14.8367 ERROR System.Deployment.Application.InvalidDeploymentException: Application identity is not set.
at System.Deployment.Application.ApplicationDeployment.get_CurrentDeployment()
at LibDataAgent.Internal.Services.UpdateService.Deployment() System.Deployment.Application.InvalidDeploymentException: Application identity is not set.
at System.Deployment.Application.ApplicationDeployment.get_CurrentDeployment()
at LibDataAgent.Internal.Services.UpdateService.Deployment()
I am not running in debug mode, or using a debug build.
So here's my actual question:
How, does the click-once code in System.Deployment.Application, at runtime, determine what the application identity is?
So, there are whole lot other questions around this, but please don't close this as a duplicate, as far as I can tell it is not one.
Here's a list of things I do not want answers for:
How to sign a click-one application.
How to set the application identity as you build.
How to find where the click-once application is installed.
How to make a click-once application work while debugging.
How to check for updates using ApplicationDeployment.
Just very plainly, exactly what does a click-once application do, at runtime that lets it determine the application identity.
Help!
Notes
My (thus far fruitless) attempts to solve this have yielded these notes:
I'm certain this has something to do with how the application is launched, because executing applications from the command line has never worked with click-once; but executing the same application from the start menu will correctly return IsNetworkDeployed as true.
However, I've not been able to determine what the technical difference is, or why one detects the install correctly and one doesn't. (or indeed, why this specific application doesn't work from the start menu, when others with no obvious difference do).
Things I've tried that make no difference include:
the working directory for the application.
launching the application .exe directly or via a shell
launching the application from a new shortcut
There is some kind magic to the 'MyApplication.appref-ms' that goes into the start menu; the appref-ms is just a url to the install path:
http://s3-ap-southeast-1.amazonaws.com/blahblah/Dev/MyApplication.application#MyApplication.application, Culture=neutral, PublicKeyToken=fdasdfsafads, processorArchitecture=x86
...which somehow launches a 'click once aware' instance of the application. But how?
I'll still happily accept an answer that explains how the guts of launching the application actually sets the application context up with an identity, but for now here's my best stab at what's going on for anyone else who finds this question later:
ClickOnce applications are launched by hitting the install url, or by using the .appref-ms file on the start menu, which contains the url.
The application/x-ms-application MIME type handler is invoked for the downloaded file, which launches the 'ClickOnce aware' instance of the application.
At runtime, the ApplicationContext.Identity is used to determine what the ClickOnce details are, and setup the CurrentDeployment object.
As far as anyone knows, directly launching the deployed executable for a ClickOnce application (in C:\Users\Administrator\AppData\Local\Apps\2.0\b107ee1... or whatever the install folder is) will always return IsNetworkDeployed as false, and will not be able to self update.
Practically speaking, this means:
You're looking for the install folder and path to your .exe? Don't bother. Even when you know where it is, it won't have the correct ApplicationContext when you run it.
To spawn a new 'ClickOnce aware' instance of your application launch internet explorer at its install url. You cannot pass command line arguments to it.
eg.
var url = "http://s3-ap-southeast-1.amazonaws.com/blahblah/Dev/MyApplication.application#MyApplication.application, Culture=neutral, PublicKeyToken=fdasdfsafads, processorArchitecture=x86";
var psi = new ProcessStartInfo
{
FileName = #"iexplore",
Arguments = $"\"{url}\"",
};
Process.Start(psi);
(if you want to find the URL, hunt through the start menu for the appref-ms file for the application; the url is contained in it)
...and how does the executable get launched with an identity?
No idea; but this is as far as anyone seems to ever have got with understanding it:
(tldr; magic. Probably something to do with how CreateProcess is invoked to spawn the appliciation using the ApplicationContext api, in some combination of DFsvc.exe. DFshim.dll and DFdll.dll)
(The rest of this information is taken from this old blog post by Ian Picknel: http://ianpicknell.blogspot.com.au/2010/03/launching-clickonce-application.html)
Once the deployment manifest has been
stored in the Temporary Internet Files folder, Internet Explorer then
attempts to establish how it should handle the file with the (assumed
and actual) .application extension. It checks the user-specific file
types at HKCU\Software\Classes and, if it fails to find an
.application sub-key there, checks for machine-specific file types at
HKCR. Via this means it establishes that the .application extension
denotes an Application.Manifest file. It then uses this information to
check the user-specific HKCU\Software\Classes\Application.Manifest and
machine-specific HKCR\Application.Manifest keys to establish the CLSID
of a library which handles Application.Manifest files and yields the
result {98af66e4-aa41-4226-b80f-0b1a8f34eeb4}. Finally, it looks up
this CLSID in the user-specific
HKCU\Software\Classes\CLSID{98af66e4-aa41-4226-b80f-0b1a8f34eeb4} and
machine-specific HKCR\CLSID{98af66e4-aa41-4226-b80f-0b1a8f34eeb4}
paths to establish that .application files are handled by
C:\WINDOWS\system32\DFshim.dll.
This is where things start to get a little complicated. I said earlier
that no 'magic' was happening behind the scenes. Well, whilst that was
true for the process of retrieving the deployment manifest it most
certainly is not true of the process of actually launching the
ClickOnce application once the deployment manifest has been retrieved
and the handler, DFshim.dll, has been identified.
DFshim.dll is described in the registry as the 'Manifest mime handler'
although its file properties describe it as the 'Application
Deployment Support Library'. It implements the Internet Explorer MIME
handler COM interface. It is a native 32-bit DLL, written in Microsoft
Visual C++ 2005, and was installed into C:\Windows\system32 when the
.NET Framework 2.0 was installed.
DFshim.dll has a hard-coded reference to DFdll.dll, which it locates
by checking the values of
HKLM\SOFTWARE\Microsoft.NETFramework\InstallRoot (typically
C:\Windows\Microsoft.NET\Framework) and the keys beneath
HKLM\SOFTWARE\Microsoft.NETFramework\Policy\AppPatch (typically
v2.0.50727, even if a later version of the Framework is installed).
DFdll.dll too is a native 32-bit DLL written in Microsoft Visual C++
2005.
DFdll.dll uses COM services exposed by DFsvc.exe, which is also
located in the .NET Framework folder. DFsvc.exe is a standard .NET
MSIL assembly. DFsvc contains a single Main method (within the
System.Deployment.Application namespace) which simply calls the
internal System.Deployment.Application.DFServiceEntryPoint.Initialize
method within System.Deployment.dll. The Initialize method registers
System.Deployment.Application.DeploymentServiceCom with COM via
System.Runtime.InteropServices.RegistrationServices (i.e. it performs
the equivalent of CoRegisterClassObject in COM) using the CLSID
{33246f92-d56f-4e34-837a-9a49bfc91df3}. This is the means by which its
services are made available to DFdll.dll.
The COM service exposed by
System.Deployment.Application.DeploymentServiceCom delegates the
majority of its methods to other non-ComVisible classes within the
System.Deployment.Application namespace. For example, the public
ActivateDeployment method calls ActivateDeployment on a new
System.Deployment.Application.ApplicationActivator instance, the
public CheckForDeploymentUpdate method calls CheckForDeploymentUpdate
on System.Deployment.Application.SubscriptionStore, etc.
It is clear that the vast majority of the work surrounding the actual
installation and launch of the ClickOnce application is undertaken by
classes within the System.Deployment namespace, hosted within
DFsvc.exe. DFshim.dll and DFdll.dll appear to primarily be responsible
for arbitrating between the COM-based world of Internet Explorer and
the .NET-based world of ClickOnce.
I recently cleaned up my Windows 7 64-bit PC, and after it ABCpdf8 started giving me an error, when I try to export HTML to PDF.
The error is "Failed to initiate IE compatibility mode: Failed to load all required assemblies."
at WebSupergoo.ABCpdf8.Internal.IECompatibility.Activate()
at line
theID = theDoc.AddImageUrl(input.Text);
of the test application, and I have no idea why, because I did not remove any assemblies from my machine.
If I run the compiled application on another workstation with the same config (Windows 7 64-bit), it works fine. Dependency Walker images showed no difference in DLLs sets from my machine and from another.
How else can I identify the source of the problem?
It is definitely neither a missing DLL, nor the user access to the system folders, because, I checked user rights as well, they're identical on both machines.
I assume that it might be a corrupted registry entry. Is there any way to quickly check the assumption?
It has to be said that, ABCpdf comes as third-party tool within another software, so I cannot contact support directly, but through the main vendor.
I had a similar problem with different behavior on w7 and ws2008, which was solved by using the Gecko engine
doc.HtmlOptions.Engine = EngineType.Gecko;
Note that websupergoo recommends using Gecko rather than IE9 as parts of the IE API it uses have been deprecated. (item 6.29)
When you 'cleaned' your system you may have erased the license key from the registry. Try re-installing your 'other software'.