I'm writing an application that will run on the Okuma control and have application settings.
Since one of the conditions is that application's settings must be easily backed up, I'm keeping them in the application directory. It works on the control because applications go to the D: but if someone installs the application on a PC on the C drive, the application can't access it's own application directory and it gets errors.
Conditions:
Windows 7
P300 control
Application being installed to D-drive
Has to work if someone installs to the C-drive on a PC
Is there a standard spot to put all application settings?
Continue to keep your application settings and other data in the application's install directory. There is no need to change the directory locations just for a "PC only" install.
The solution to file access issues is to change file permissions during install.
For example, this answer someone posted using WIX installer.
A similar question is answered here.
You could use code similar to this to change permissions during install (when the user has admin privileges)
using System.Security.Principal;
public static void SetPermissions()
{
String path = GetPath();
try
{
// Create security idenifier for all users (WorldSid)
SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
DirectoryInfo di = new DirectoryInfo(path);
DirectorySecurity ds = di.GetAccessControl();
// add a new file access rule w/ write/modify for all users to the directory security object
ds.AddAccessRule(new FileSystemAccessRule(sid,
FileSystemRights.Write | FileSystemRights.Modify,
InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, // all sub-dirs to inherit
PropagationFlags.None,
AccessControlType.Allow)); // Turn write and modify on
// Apply the directory security to the directory
di.SetAccessControl(ds);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Related
When finding random apk's online through urls, I can successfully download and install them, the user is prompted to ask if they want to install comes up. But when I upload the same apk's to Google drive, and then run the download url from Google drive, the apk's doesn't work. I get a "There was a problem while parsing the package" on the device screen. I put a log to see how much data is being downloaded. And it appears that the apk's being downloaded from google drive are barely the size of what the apk's should be. Around 50k instead of 4MB. I see a lot of questions online about this, but none have talked about Google play not sending the full file. Is there something I'm missing in order to get the full apk downloaded from Google drive? here is the code,
private void downloadApk(){
// checkVersion();
String extStorageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();
File folder = new File(extStorageDirectory);
folder.mkdirs();
File file = new File(folder, "app-debug.apk");
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
DownloadApkTask downloadApkTask = new DownloadApkTask(APKURL,file);
downloadApkTask.execute();
}
public class DownloadApkTask extends AsyncTask<String, Void, Void> {
String fileURL;
File directory;
public DownloadApkTask(String fileURL,File directory) {
this.fileURL = fileURL;
this.directory = directory;
}
#Override
protected Void doInBackground(String... params) {
Log.v("DO in Back started","Started");
try {
FileOutputStream f = new FileOutputStream(directory);
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.connect();
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
Log.v("PROGREsS", String.valueOf(len1));
f.write(buffer, 0, len1);
}
f.close();
directory.setReadable(true,false);
} catch (Exception e) {
System.out.println("exception in DownloadFile: --------"+e.toString());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void stringReturn) {
super.onPostExecute(stringReturn);
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+"/app-debug.apk");
Log.v("STARTING INSTALLATION","-----");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);
}
}
Based from this page, parsing error occurs on app installment.
When you try to install an application suddenly a window pop-ups saying "there is a problem parsing the package" which means the application cannot be installed due to apk parser i.e. parsing issue.
There are several reasons why this parsing error occurs & definitely one of them is responsible for your parsing error:
File may be downloaded incompletely.
Application might be not suitable for your hardware or OS version.
Due to security issue settings
Corrupted APK file.
Follow the steps shown below for fixing the android parse error on your mobile devices:
Check Manifested app apk file.
Change the Andriomanifest.xml file to its default setting & also check the name of that file. If the original name of the file is “aap.apk” & if you renamed it as "app1.apk" then also it might cause an error. If you have some knowledge of coding, look into the app code if there is some problem with coding.
Security settings.
For the security purpose, the phone has an inbuilt setting that doesn't allow installing applications from a 3rd party provider other than mobile apps provided by play store. Don’t install an app from the non-trusted website. That might really risk your mobile.
Enable USB debugging.
Go to the settings >> Scroll down then, at last, you will see option “About device” select it.
Look for option “build number.”
Tap on “Build number” for 7 times.
You will see a message “you are now a developer.”
Once you enable to go back to settings
Choose “Developer options.”
Tick mark "USB debugging."
Corrupted App file.
The parse error may cause due to corrupted file too. In this case, download a new but complete APK file, & try again to install it again. This might help you.
Disable Antivirus.
If you have installed applications like antivirus & cleaner apps, then this can also prevent some apps installation. This prevention is due to the safety purpose of the handset. They block suspicious downloads from non-trusted sites. If you really want to install that app then disable the antivirus temporarily.
Clear cache cookies of play store.
Open google play store
Select sidebar & choose option “settings.”
In general settings, you will find out to “clear local search history.”
I'm trying to download a file and I'm getting System.UnauthorizedAccessException: Access to the path "/storage/emulated/0/Download/test.pdf" is denied. I have set required permission in Android Manifest file.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Download Path:
Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads)
If i use the below path as my download path i can able to download the file. But i cant able to share the PDF file to google drive, drop box or any other System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
I am using Xamarin.Forms v2.4.0.282 and Xamarin.Android.Support packages v25.4.0.2.
Note: The code was woking fine when use Xamarin.Forms version 2.3.5.256-pre2 and Xamarin.Android.Support packages v23.3.0
Please suggest your ideas to resolve the issue.
Thanks in Advance.
Depending on the version of Android you are using even with the permissions added in the manifest in 6.0 or up the user has to explicitly enable the permission when the app runs and on lower versions permission is asked during install. For example, on startup of the app I created a method to check if it is enabled and request permission if it's not.
private void CheckAppPermissions()
{
if ((int)Build.VERSION.SdkInt < 23)
{
return;
}
else
{
if (PackageManager.CheckPermission(Manifest.Permission.ReadExternalStorage, PackageName) != Permission.Granted
&& PackageManager.CheckPermission(Manifest.Permission.WriteExternalStorage, PackageName) != Permission.Granted)
{
var permissions = new string[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage };
RequestPermissions(permissions, 1);
}
}
}
You can also use the support library to do this, which is simpler and allows you to not have to check the Android version. For more info check out google's documentation.
If targeting API 29+, you will get the error even if you request the permission and user grants it, because they changed how storage works.
The correct solution is to look how it should be done on API 29+ and do it.
But if you are like me, tired of Android making things more complicated every day, just add android:requestLegacyExternalStorage="true" to your manifest <application> tag and you are saved until you start targeting API 30.
Those of you who are facing this issue after your app is Targeting API29 or higher, please go to this link and check LandLu's Answer:
https://forums.xamarin.com/discussion/171039/saving-files-to-external-storage
Earlier I was accessing Folder path using
return Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
But using this line solved my problem:
return Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;
You need user's permission on run time even you have mentioned them in your manifest file if you are running Android api level 23 or greater. Check and if user has not yet granted granted READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE, use the bellow code;
var permissions = new string[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage };
RequestPermissions(permissions, 77);
If i use the below path as my download path i can able to download the
file. But i cant able to share the PDF file to google drive, drop box
or any other
System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
You are storing files on app's private storage. All files saved to the internal storage are private to your application and other applications ( google drive, drop box or any other ) cannot access them (nor can the user). You can use any public folder for that purpose;
var finalPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
replace
Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
with
Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;
Is it possible to activate Xposed-modules automatically rather than checking them to be active in the Xposed GUI? Is the enabled status of the modules stored somewhere easily accessible (on a rooted device)...?
You can achieve this by modifying the conf/modules.list file in the Xposed Installer data directory, simply add the path of your APK file to the list.
You should also modify the shared_prefs/enabled_modules.xml file, so that your change is reflected within Xposed Installer (otherwise, the module will be enabled but will show as disabled within Xposed Installer).
The device needs to be rebooted after the change.
Note that this requires root access, since the file is located in the internal data directory of another app. I strongly recommend just going the normal way and opening the Xposed Installer app, and let the user enable the module themselves:
public static boolean startXposedActivity(Context context) {
Intent intent = new Intent("de.robv.android.xposed.installer.OPEN_SECTION");
intent.putExtra("section", "modules");
try {
context.startActivity(intent);
return true;
} catch (ActivityNotFoundException e) {
return false;
}
}
I am running a console application with no UI and generate thumbmail images from pdf files. The compile file for this application works fine. However I have to call this compile file from windows service application that implement the the FileSystemWatcher class to detect when new pdf files are uploaded into the directory.
and I am using the suggestion from this link
How to run console application from Windows Service?
ProcessStartInfo info = new ProcessStartInfo(appName);
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.CreateNoWindow = true;
info.ErrorDialog = false;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process process = Process.Start(info);
if (!process.HasExited)
{
LogEvent(process.ProcessName + "has started and called Thumbnail application");
}
else
{ LogEvent(process.ProcessName + "has been terminated"); }
I can see the process involking the "pdfThumbnail.exe" but I am getting this error when the application try to execute.
"System.Exception: Cannot create ActiveX component.
at Microsoft.VisualBasic.Interaction.CreateObject(String ProgId, String ServerName)
at PDFThumbnailCsharp.Main(String[] args)
"
As I have said above the pdfThumbnail.exe execute fine when i run the exe file.
Updates
This is the error from the SysInternals' Process Monitor
The machine-default permission settings do not grant Local Activation permission for the COM Server application with CLSID {FF76CB60-2E68-101B-B02E-04021C009402} and APPID
Unavailable to the user NT AUTHORITY\LOCAL SERVICE SID (S-1-5-19) from address LocalHost (Using LRPC). This security permission can be modified using the Component Services administrative tool.
I have changed the ownership of this CLSID to Administrator with Full control as described on this link
http://social.technet.microsoft.com/Forums/en-US/windowsserver2008r2general/thread/e303c7e1-16de-42fd-a1a4-7512c1261957
However I am still getting the same error.
Any help will be appreciated.
Thanks
This CLSID {FF76CB60-2E68-101B-B02E-04021C009402} is for Acrobat.Excha.PDDoc on my computer registry. Further investigation with Acrobat on this link https://forums.adobe.com/thread/1467460 revealed that Acrobat cannot be run from service.
What I have done for now until I have a better approach is to create a windows Task Scheduler that listen to an event raised by the windows service when new pdf are created and then trigger the console app that create the thumbnails.
I've been tasked with converting a legacy application to mvc. The app used pgp.exe to pgp sign user input and send it as an email. The application works locally and on a test server but won't run on a live server. I've had to jump though hoops such as running a specified user in the application pool so that we can set the keys in the users profile BUT it worked.
For some reason on the live server which is windows 2003 IIS 6 and identical to the testing server it fails. The problem is pgp.exe just wont seem to sign and create files the message I get from the console out put is. "Signature Error"?? When I put the command into a shell window logged in as the app pool user it runs no problem (after a fight with some permissions) but when running through the mvc application/IIS server it fails. The code used to call the process is below.
var startInfo = new ProcessStartInfo();
startInfo.FileName = _pgpexeLocation;
//startInfo.FileName = "pgp.exe";
startInfo.Arguments = string.Format("-sta \"{0}\" -u keyuser-z keypass +COMPATIBLE +FORCE", _tempFilePath);
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.LoadUserProfile = true;
using (Process exeProcess = Process.Start(startInfo))
{
// TODO: set limit to wait for and deal with exit
exeProcess.WaitForExit();
//var stringItem = exeProcess.StandardOutput.ReadToEnd();
//Logger.Info(stringItem);
}
I'm clutching at straws here hoping somebody has done something similar before and can help. I'm guessing it's key location or file location not being picked up somewhere but not sure what else to try?
Turns out that even though the app pool was using a specific user and I'd set the keys up in that users appdata folder when I checked the underlying process call it was actually trying to pick the keys up from the Default User profile. Not sure if this was an IIS config or something similar but moving the keys and pgp folder to this appdata instead worked?