I have a BHO which captures webpages as images and I run another process to pngcrush the images thus created. The problem that I face in UAC enabled systems is that every time IE runs, I get a warning for the pngcrushing process that I spawn from the BHO. I read here
Understanding and Working in Protected Mode Internet Explorer archive
Starting Processes from Protected Mode
In general, extensions should operate as low integrity processes whenever possible. This provides the best protection against malicious attacks. However, there are times when an extension may need to access medium or even high integrity objects.
To do this, create a broker process to access higher integrity objects and then launch the broker process with a higher integrity level. By default, Internet Explorer will prompt the user to confirm the medium integrity elevated process, as shown in the following screen shot.
You can silently elevate your broker process to medium integrity level by creating an elevation policy, which is a series of registry keys and values that tell Protected Mode how to handle elevation for a specific broker. Elevation policies must have a globally unique identifier (GUID) associated with them. Use CreateGuid to create a new GUID for your policy. Next, add a key to the following location.
It then proceeds to describe the registry entries requires to silently elevate the help process:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Low Rights\ElevationPolicy\{8e884ace-bee4-11e4-8dfc-aa07a5b093db}
AppName: REG_SZ = "Contoso.exe"
AppPath: REG_SZ = "C:\%USERPROFILE%\Application Data\Contoso"
Policy: REG_DWORD = 0x00000003
When I did the same reg entries manually to see if I go past these warnings, figured out that it was not working. Can someone tell me how to run the process silently from the BHO without any UAC warnings?
Kapil
In response to #blueraja's comment above, here is the code I use tp spawn the process:
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = binPath + "\\pngnqi.exe";
info.WindowStyle = ProcessWindowStyle.Hidden;
info.WindowStyle = ProcessWindowStyle.Hidden;
info.Arguments = " -e .jpg " + " \"" + filePath + "thumb_" + count + "\" " + " \"" + filePath + "temp\\" + count + "\" ";
Process pngnqi_process = Process.Start(info);
Related
I use a very simple version control whereby I use the "tag" property on the Switchboard to record the version of the database.
On a linked "mastertable" I have a master record that shows the current version. If this is out of sync, then there is code in the switchboard to initiate a simple file copy of the new client version to the user's desktop.
I can't use any EXE type auto-installers to do this, so had to come up with an all Access solution, but having some issues with shell commands and timing that is causing the "auto" part of the installer to be inconsistent.
Below are my codes for the Client and my standalone "Installer" database (which only has one form that opens on startup and initiates the copy code). I use lookup tables for all file locations, but will use strings in my example.
Client.mdb:
strInstaller = "c:\Installer\Installer.mdb"
set obj = CreateObject("access.application") 'previously tried SHELL command
with obj
.visible = true
.userControl = true
.openCurrentDatabase (strInstaller)
end with
application.quit
Simple enough. So the above code just opens my Installer mdb which opens a form and executes the following on open.
Installer.mdb:
strFileName = "ClientDB"
strMaster = "D:\" & strFileName
strClient= dlookup("DBPath", "UserTbl", "LanID = '" & MyID & "'") & "\" & strFileName
if len(dir(strClient)) <> 0 then
kill strClient
end if
filecopy strMaster, strClient
The dlookup in the strClient simply looks up the path where the user opened up the instance of the client mdb. (I record this on every instance).
My issues is that I am not getting consistent results. Sometimes it will copy the file, and sometimes it won't. I've changed it to run from a button on the Installer Form, and it works every time, so I'm guessing it has something to do with timing.
I've tried putting a pause function before the kill command, and that seems to help if I set the pause to 3 or 4 seconds. I originally used Shell to open the Installer, but got rid of it as I heard that it was running concurrently with the installer.mdb code.
I'm thinking it's something obvious, but I've been staring at this for about an hour and can't figure it out. Ideally, I don't want the user to interact with this form using an "Install" button, but would like it to happen in the background. i.e. I want to set the .visible = false at some point.
Can anyone see an issue with this method, or suggest a better method to push out new copies of the client - and I can't use any EXE install programs.
You likely want to use the shell() command. You can use CreateObject, but that feature is NOT available in the runtime. (and worse, it will not work).
The simple trick is ONCE you shell out to the upgrade program, you want to QUIT the main program (since you can’t copy over it while it is running).
The code I use is thus:
strCurrentDir = CurrentProject.Path & "\"
' path to msaccess.exe is determined here
strShellProg = q & SysCmd(acSysCmdAccessDir) & "msaccess.exe" & q & " "
' path to current dir...assume upgrade program in same folder
strShellProg = strShellProg & q & strCurrentDir & "UpGrade.accDE" & q
If Shell(strShellProg, vbNormalFocus) > 0 Then
Application.Quit
Else
MsgBox "Un able to run upgrade", vbCritical, AppName
Application.Quit
End If
In above “q” is = """" (a single double quote).
So you shell out, and then immediate do a application.Quit. The upgrade program should have a “prompt” like “about to upgrade – ok”. That “prompt the user has to hit gives the main application time to quit. I also useally write out the locations to a text file in the above code - but the above steps to shell() is the main takeaway solution here.
As noted, you can use create object, but THEN if you quit the main application, then that variable holding the upgrade program will also go out of scope (or worse, the main application cannot shut down because it is “hosting” an automated copy of the upgrade application by CreateObject.
So you in practical terms don’t want to use createObject, since this means the main program is “hosting” or “holding” a copy of the upgrade program and the main program really can’t quit.
I want my .bat file to run after I rename a file in the Sources folder that is located here:
C:\Users\UserName\Videos\Gameplays\HeroesOfTheStorm\Sources\
The .bat file is located in the same Sources folder.
How can I do that without double-clicking on the .bat file manually? I want it to run automatically after I rename a file in the Sources folder.
Set WshShell = WScript.CreateObject("WScript.Shell")
Set WMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set MonitoredEvents = WMI.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE Targetinstance ISA 'CIM_DirectoryContainsFile' and TargetInstance.GroupComponent= 'Win32_Directory.Name=""C:\\\\Users\\\\David Candy""'")
Do
Wscript.Echo MonitoredEvents.NextEvent.TargetInstance.PartComponent
WshShell.Run "cmd /c ""C:\folder\batchfile.bat""", 1, false
Loop
Note the use of 4 \ for 1 in directory name but nowhere else.
It a vbs file. It monitors a directory and will run commands if you rename or create files in that directory. WITHIN 10 means it tests every 10 secs.
Set WshShell = WScript.CreateObject("WScript.Shell")
Set WMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set MonitoredEvents = WMI.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE Targetinstance ISA 'CIM_DirectoryContainsFile' and TargetInstance.GroupComponent= 'Win32_Directory.Name=""C:\\\\Users\\\\David Candy""'")
Do
WMIPath = Split(MonitoredEvents.NextEvent.TargetInstance.PartComponent, "=")(1)
FilePath = Replace(WMIPath, "\\", "\")
WshShell.Run "cmd /k echo File Renamed is " & FilePath & "&" & Filepath
Loop
Ok, you can do this in a rather complicated way with windows tools.
First, you need to enable Auditing.
run GPEDIT and then go to: Computer Configuration --> Windows Settings --> Security Settings --> Local Policies --> Audit Policy --> Audit object Access
enable i guess both success and failures.
Now go to the folder you want to monitor, double-click and go to: security tab --> Advanced --> Auditing Tab
add a rule with your user (or a groups or something like that) that will make a log for the rename (the is no rename event, but you can try different combination, like file creation, file delete or read/write attributes you can find)
after that, now if you got to Event Viewer, Security log, a couple of events with Ids 4565/4663 will appear when the operation you selected is perfomed.
last thing, open the Task Scheduler and create a new task, with the activation set to the trigger of the event and an action that will run the bat.
Some of the term may differ, my Windows is not in English so i might have translated something wrong. Also, you might do some tests to see if you have everything set up correctly.
Another option might be setting up a small application that monitors the folder and run the bat accordingly. You can do such a thing in Java or in other languages.
This can be achieve easily with AutoHotkey using WatchDirectory()
https://stackoverflow.com/a/30582696/883015
I've been trying to get a Jenkins deploy job to work by running a batch script to do the install of an msi from the Jenkins build machine itself. I've given the appropriate access rights, but still am not able to run the following command remotely, using WMIC
wmic /node:myServerIp /user:"clientpc\my-user" /password:"my-password" process call create "D:\someDir\someOtherDir\test.bat"
The follow response from the above command:
Executing (Win32_Process)->Create()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
ReturnValue = 9;
};
After some research, it looks like return value of '9' is 'Path not found' according to https://msdn.microsoft.com/en-us/library/aa389388(v=vs.85).aspx, but I've verified that the path exists on the remote server.
The test.bat file that I'm trying to run is very simple, and should just write to a text file.
#echo This is a test.> test.txt
I've verified that both files exist on the server, and have granted 'EVERYONE' to the shared folder 'someDir'.
I have tried prefixing 'cmd.exe /c' to the path called:
wmic /node:myServerIp /user:"clientpc\my-user" /password:"my-password" process call create "cmd.exe /c D:\someDir\someOtherDir\test.bat"
...for which I receive:
Invalid Verb Switch.
I've verified that the user access is correct by providing a bad password, in which case permission is denied.
EDIT:
Changed the path from D:\someDir\someOtherDir\test.bat to D:\\someDir\\someOtherDir\\test.bat but now receive the following error:
ERROR:
Description = The RPC server is unavailable.
EDIT 2:
Looks like the RPC user I was using was the cause for the error. Still troubleshooting, but when I use my AD user, as opposed to the administrator I created to run this, I get the following AGAIN...
Executing (Win32_Process)->Create()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
ReturnValue = 9;
};
I was able to get the following to work on an Active Directory domain.
Wmic /node:"ComputerName" process call create "cmd.exe /c (net use o: /delete /y & net use o: \\Server\share /user:Domain\Administrator Password & o:\Dir\Subdir\test.cmd) >> c:\users\MyUser\testout2.txt"
The very simple contents of test.cmd:
echo Just a test >> c:\users\MyUser\testout.txt
date /t >> c:\users\MyUser\testout.txt
time /t >> c:\users\MyUser\testout.txt
The "job" is being sent to "ComputerName" on the domain. The batch/script file the job runs is on a network share. The job running on "ComputerName" will not see any mapped drives, so I delete and map a drive. I don't believe it is ever necessary to delete the drive, but I added that for completeness sake.
After execution, testout2.txt shows the batch file executing the commands and
testout.txt contains the results of the batch file commands as expected.
Things to watch out for:
As mentioned, mapped drives are not visible from the remote job
You are executing in the target machine's environment - drive letters need to make sense to that machine
Internal commands such as 'echo' require the job starts with 'CMD.EXE /c'
Group multiple commands inside parentheses and separate with ampersands (&)
Don't collide file access. I use testout.txt and testout2.txt files. If I had given them the same name, one set of outputs would have been lost.
Nothing you do this way will ever be visible to the user; the job is run in such a way that it can not display on the user's screen.
Sending a password in clear text as I show in the example is a security hazard and should be avoided. I'm not sure of a better way to map drives in this context however.
I'm writing a repository in ASP classic (using JScript) running on IIS 7.0 and I'm having some trouble with permission when moving files around. I have to following generic function that always gives me a permission denied error.
function moveFile(source, target){
fs = new ActiveXObject("Scripting.FileSystemObject");
newloc = target + "\\" + source.name;
debug("Copying file: " + source.path + " to " + newloc);
fs.copyFile(source.path, Server.MapPath( "repository/" ), true);
}
When I call the function with with source source.path being D:\Inetpub_EXT\wwwroot\builder\repo\dump\alicia.docx and target being D:\Inetpub_EXT\wwwroot\builder\repo\repository I get the following output:
Treating dumpfile: alicia
Copying file: D:\Inetpub_EXT\builder\repo\dump\alicia.docx to
D:\Inetpub_EXT\wwwroot\builder\repo\repository
Microsoft JScript runtime error '800a0046'
Permission denied
I've verified that both the folder and file exist and I gave full control to IIS_WPG, IUSR, Authenticated User, System and Administrators in builder.
Thanks for your help.
Double check your permissions. Be careful of assumptions.
For example you may be assuming that if the IIS user has permissions on the builder directory, then it has permissions on all subdirectories. This is not a good assumption.
If you set the ACL on the builder directory to give IIS permissions, after having created the subdirectories, then those subdirectories won't automatically inherit the permissions that you later applied to builder.
You can use icacls.exe from the command line to view the permissions:
%windir\system32\icacls.exe d:\inetpub\wwwroot\builder\foo\bar
I want to create a test setup which should have a 4tb of High density filesystem.
I've tried some tools(wst) but they are crashing after sometime. After struggling for two days im able to fill not even 20% of disk space. I need this tool on windows. Any suggestions?
You can use Disk Tools. I used it once for stress testing a hard disk which presumably had bad sectors.
You can:
create a small file in a directory,
copy-paste the directory itself,
put the duplicate directory into the original one,
and repeat steps 2 and 3 until you reach your need (about thirty times, depending on the size of the initial file).
If all you want is simply to create many many files, you can use this batch script that copies a given file for as many times as possible. There is no stop condition, but I suppose the counter variable will overflow after about 2^31.
Use the script like extreme_copy my_test_file.txt where the test file can have any size you want.
This is the script:
#ECHO OFF
IF "%1"=="" GOTO END
IF NOT EXIST "%1" GOTO END
REM copy loop
SET FILE_NUMBER=1
:COPY
copy "%1" "%~dpn1_%FILE_NUMBER%%~x1" > nul
REM show some progress
SET /A SHOW_ITERATIONS="%FILE_NUMBER% %% 1000"
IF /I %SHOW_ITERATIONS%==0 ECHO %FILE_NUMBER% files created...
SET /A FILE_NUMBER=%FILE_NUMBER% + 1
GOTO COPY
:END
I made a C# console app do create random files, with random content from 2kb to 10kb.
Compile it ( this is .net 2, but im sure it will compile with any .NET version )
Run like this:
YourExe d:
YourExe d:\temp2
Semi disclaimer, if you run the app long enough it might get a stackoverflow, just start it again if that happens. File names are random, so it will not create any issues
class Program
{
static void Main(string[] args)
{
if (args.Length != 1 || !Directory.Exists(args[0]))
{
Console.WriteLine("Arg should be: C:\\ (or your drive letter)");
return;
}
const int RandomFilesToCreate = int.MaxValue;
for (int i = 0; i < RandomFilesToCreate; i++)
{
string FileName = CreateRandomFile(args[0]);
Console.WriteLine(i + ") Wrote file " + FileName);
}
}
static Random gRan = new Random();
static string CreateRandomFile(string Path)
{
byte[] FileContent = new byte[gRan.Next(2,10) * 1024] ;
// generate a random filename
string FileName = Path + "\\TempF_" + gRan.Next(0, int.MaxValue) + "_" + gRan.Next(0, int.MaxValue) + "_" + gRan.Next(0, int.MaxValue) + ".tmp";
while(File.Exists(FileName))
FileName = Path + "\\TempF_" + gRan.Next(0, int.MaxValue) + "_" + gRan.Next(0, int.MaxValue) + "_" + gRan.Next(0, int.MaxValue) + ".tmp";
// fill with random bytes.
gRan.NextBytes(FileContent);
// Write to disk
File.WriteAllBytes(FileName, FileContent);
return FileName;
}
}
I can't really make the two terms "Windows" and "4TB of data" match in my head. Windows is a desktop OS written for the average user who does a bit of Word and browsing with IE. If you have special needs, use a server OS like Linux. It comes with all the tools you need to handle large amounts of data. You also get FS benchmark tools like bonnie.
You can also choose from a large set of filesystems where some (like ZFS) are designed for huge sizes (Exabytes). NTFS can theoretically handle this amount of data but I'm not aware that anyone has actually tried this. See this Wikipedia article for some pointers.
[EDIT] Since you use a "server" edition of Windows (which translates to "Desktop OS with a couple of nice wizards to set up the network"), you must have a professional support contract with Microsoft. This means you can just call them, explain your problem and let them tell you how to solve it.
Sorry, I'm being unnecessarily sarcastic here but I find all this really amusing ;) Just because the marketing department slaps a "Server" label on something doesn't mean that a professional administrator would buy it. I'd be surprised if someone would post an answer to the effect "we did the same thing and we could get it working reliably and to our satisfaction".