Setting an application on start-up not working - c#

I'm developing an windows application and i want to set this application as windows start-up application for that i use this code:-
Code
public static void SetStartup(string AppName,
bool enable)
{
try
{
string runKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
Microsoft.Win32.RegistryKey startupKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(runKey);
if (enable)
{
if (startupKey.GetValue(AppName) == null)
{
startupKey.Close();
startupKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(runKey, true);
startupKey.SetValue(AppName, Assembly.GetExecutingAssembly().Location + " /StartMinimized");
startupKey.Close();
}
}
else
{
startupKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(runKey, true);
startupKey.DeleteValue(AppName, false);
startupKey.Close();
}
}
catch
{
}
}
Calling code on application load
SetStartup(Application.ExecutablePath, true);
And this code works fine.It sets application as a start-up application.
I check that executing msconfig command in run window.It shows this application checked in start-up tab.But when i restarts the system it doesn't start application.
Can any one tell me what is the problem and how can i solve that problem.

If everything points to it being in startup then I can only assume that that part of it is correct, but the application is failing to start for some reason.
When you start an application on run, it's working directory is set to C:\Windows\System32
I have had issues with applications that may be looking for files in its home directory such as config files but are unable to find them.
Normally files referenced the normal way will be found anyway, but if you are manually specifying a path in your code you can use:
string pathToDLL = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LibraryFile.dll");
Using AppDomain.CurrentDomain.BaseDirectory should give the path of the your application exe, rather than the working directory.
Could this be the cause of the problem?
Also, I'm going to assume Vista upwards is the OS, and if that's the case then your application would have to be running as elevated to write to that registry. So, if UAC is off and the machine is restarted then your application, if it's set in the manifest to run as requireAdministrator, would fail silently.
Martyn

Finally i got a answer for this problem.Use StreamWriter for creating a URL link of application instead of creating a LNK into start-up folder.
Create shortcut
private void appShortcutToStartup()
{
string linkName ="MytestLink";
string startDir = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
if (!System.IO.File.Exists(startDir + "\\" + linkName + ".url"))
{
using (StreamWriter writer = new StreamWriter(startDir + "\\" + linkName + ".url"))
{
string app = System.Reflection.Assembly.GetExecutingAssembly().Location;
writer.WriteLine("[InternetShortcut]");
writer.WriteLine("URL=file:///" + app);
writer.WriteLine("IconIndex=0");
string icon = Application.StartupPath + "\\backup (3).ico";
writer.WriteLine("IconFile=" + icon);
writer.Flush();
}
}
}
Delete Shortcut
private void delappShortcutFromStartup()
{
string linkName ="MytestLink";
string startDir = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
if (System.IO.File.Exists(startDir + "\\" + linkName + ".url"))
{
System.IO.File.Delete(startDir + "\\" + linkName + ".url");
}
}
This code works very fine.

I believe the most simplest way would be by following the below steps
1.) Build your application
2.) Navigate to your debug folder
3) Copy the exe and place it at your Startup location
**C:\Documents and Settings\user\Start Menu\Programs\Startup**
OR
Simply drag your exe over start menu--> Program-->Startup and Paste it there (i.e
releasing the mouse button)
I guess that would do your work
Hope it helps

Related

C# File.copy and Directory.CreateDirectory working on Win10 but in Win7 it appends folder to parent folder

The same code, one on windows 10, the other on windows 7.
The idea is to have a directory from a network drive replicate over to a local drive.
On windows 10, the machine I am writing it on, it works perfectly fine as intended.
On windows 7, the target machine, it 'works' but the sub folder structure is messed up.
Example,
C:\target -> the target location
C:\targetNewFolderName1 -> What its being copied to
C:\targetNewFolderName2
C:\targetNewFolderNameN
When it should be doing this below,(which it is, on windows 10, not on windows 7)
C:\target -> the target location
C:\target\NewFolderName1 -> What its being copied to
C:\target\NewFolderName2
C:\target\NewFolderNameN
Master is a network directory, #"\\server\fu\bar\target"
Slave is a local directory, #"C:\target"
These are passed to the function.
Function header, private void CheckMasterToSlave(string MasterPath, string SlavePath, string BackupPath, string[] MasterFilesList, string[] SlaveFilesList)
The below code snipit is within a foreach; foreach (string master in MasterFilesList).
log.Info(master + " doesnt exist, copying");
string directoryCheck = (SlavePath + master.Substring(MasterPath.Length)).Substring(0,
(SlavePath + master.Substring(MasterPath.Length)).LastIndexOf("\\"));
if (!Directory.Exists(directoryCheck))
{
log.Debug(directoryCheck + " Directory not present, touching.");
try
{
Directory.CreateDirectory((SlavePath +
master.Substring(MasterPath.Length)).Substring(0, (SlavePath +
master.Substring(MasterPath.Length)).LastIndexOf("\\")));
}
catch
{
log.Error(master + " directory failed to be created in slave environment.");
}
}
try
{
File.Copy(master, SlavePath + master.Substring(MasterPath.Length));
log.Info(SlavePath + master.Substring(MasterPath.Length) + " Successfully created.");
BackupFile(master.Replace(MasterPath, SlavePath), BackupPath, SlavePath);
}
catch
{
log.Error(master + " failed to copy, backup has been halted for this file.");
}
I do not understand why this works as intended on windows 10 but moving it to windows 7 causes this issue.
What would be causing this and how can I stop the new folder from appending to the parent folder in windows 7?
Use Path.Combine to build a path name from different path components instead of just using string concatenation.
Alright, I am stupid and forgot to change to release. When changes that NineBerry mentioned were made. It did work.
I still do not understand why the original did work on windows 10 but not on windows 7. Especially since the BackupFile portion does the same thing as the old 'wrong' way. But both work now.
Regardless, here is the updated bit.
log.Info(master + " doesnt exist, copying");
string[] EndDirectoryFile = master.Substring(MasterPath.Length).Split('\\');
string[] EndDirectory = new string[EndDirectoryFile.Length-1];
for (int i = 0; i < EndDirectoryFile.Length - 1; i++)
{
EndDirectory[i] = EndDirectoryFile[i];
}
string directoryCheck = Path.Combine(SlavePath, Path.Combine(EndDirectory));
if (!Directory.Exists(directoryCheck))
{
log.Debug(directoryCheck + " Directory not present, touching.");
try
{
Directory.CreateDirectory(directoryCheck);
}
catch
{
log.Error(master + " directory failed to be created in slave environment.");
}
}
try
{
File.Copy(master, SlavePath + master.Substring(MasterPath.Length));
log.Info(SlavePath + master.Substring(MasterPath.Length) + " Successfully created.");
BackupFile(master.Replace(MasterPath, SlavePath), BackupPath, SlavePath);
}
catch
{
log.Error(master + " failed to copy, backup has been halted for this file.");
}

Unity project can't find the right path of database in Android device

I have a Unity project which work without problems in unity editor, but when I run the app on an Android device the problem is shown.
The problem is that the app can't find the database in datapath which in the code
So, it makes a file with same name in this destination and this file is empty.
So in any method need data from database there is an error that (not find the table)
I put database in assets Folder
Here is the code to detect the path.
I tried first only this part:
testconnectionString = Application.dataPath + "/ARMaze.sqlite";
Then the hall code.
Then the code without the comment part.
And the I have the problem each time.
void Start()
{
if (Application.platform != RuntimePlatform.Android)
{
testconnectionString = Application.dataPath + "/ARMaze.sqlite";
}
else
{
testconnectionString = Application.persistentDataPath + "/ARMaze.sqlite";
//if (!File.Exists(testconnectionString))
//{
// WWW load = new WWW("jar:file://" + Application.dataPath + "!/assets" + "/ARMaze.sqlite");
// while (!load.isDone) { }
// File.WriteAllBytes(testconnectionString, load.bytes);
//}
}
connectionString = "URI=file:" + testconnectionString ;
Debug.Log("Connection String is "+connectionString);
}
In general for system paths you not concatenate the string directly but rather use Path.Combine
if (Application.platform != RuntimePlatform.Android)
{
testconnectionString = Path.Combine(Application.dataPath, "ARMaze.sqlite");
}
else
{
testconnectionString = Path.Combine(Application.persistentDataPath, "ARMaze.sqlite");
...
It automatically uses the correct path separator (\ or /) for the target platform.
I might be wrong but I think also the ! in a system path might make trouble. Why even adding a !/assets here? Shouldn't it be the same path as before testconnectionString?

Ghostscript.NET - no output file when run as Windows service

I'm writing a Windows Service to scan a set of directories for new PDF files and convert them to TIFF with Ghostscript.NET. When I'd compiled and ran the code as a normal program it functioned perfectly, but when I used the same code as a Service the output TIFF never appears. I've set the destination directory to allow writing for Everyone, and the original PDF is being removed as it's supposed to, so it shouldn't be a permissions issue for the "Local System" user. Auditing the directory for access Failures and Successes just shows a list of Successes.
There is a function that reads the color population of the PDF to determine if it's a color document, or B&W scanned as color. That part works, so there isn't an issue accessing and reading the PDF.
I've also tried removing '-q' from the Ghostscript switches and I don't have any errors reported, and "-dDEBUG" outputs so much garbage I don't know what it's saying - but nothing is tagged as an error.
public static void ConvertPDF(string file, GSvalues gsVals)
{
gsProc = new Ghostscript.NET.Processor.GhostscriptProcessor();
System.Collections.Generic.List<string> switches = new System.Collections.Generic.List<string>();
switches.Add("-empty"); // GS.NET ignores the first switch
switches.Add("-r" + gsVals.Resolution); // dpi
switches.Add("-dDownScaleFactor=" + gsVals.ScaleFactor); // Scale the image back down
switches.Add("-sCompression=lzw"); // Compression
switches.Add("-dNumRenderingThreads=" + Environment.ProcessorCount);
switches.Add("-c \"30000000 setvmthreshold\"");
switches.Add("-dNOGC");
string device;
if (_checkPdf(file, gsVals.InkColorLevels, gsVals))
{
gsVals.WriteLog("Color PDF");
device = "-sDEVICE=tiffscaled24"; // 24bit Color TIFF
}
else
{
gsVals.WriteLog("Grayscale PDF");
device = "-sDEVICE=tiffgray"; // grayscale TIFF
}
switches.Add(device);
// Strip the filename out of the full path to the file
string filename = System.IO.Path.GetFileNameWithoutExtension(file);
// Set the output file tag
string oFileName = _setFileName(oPath + "\\" + filename.Trim(), GSvalues.Extension);
string oFileTag = "-sOutputFile=" + oFileName;
switches.Add(oFileTag);
switches.Add(file);
// Process the PDF file
try
{
string s = string.Empty;
foreach (string sw in switches) s += sw + ' ';
gsVals.DebugLog("Switches:\n\t" + s);
gsProc.StartProcessing(switches.ToArray(), new GsStdio());
while (gsProc.IsRunning) System.Threading.Thread.Sleep(1000);
}
catch (Exception e)
{
gsVals.WriteLog("Exception caught: " + e.Message);
Console.Read();
}
gsVals.DebugLog("Archiving PDF");
try
{
System.IO.File.Move(file, _setFileName(gsVals.ArchiveDir + "\\" + filename, ".pdf"));
}
catch (Exception e)
{
gsVals.WriteLog("Error moving PDF: " + e.Message);
}
}
private static string _setFileName(string path, string tifExt)
{
if (System.IO.File.Exists(path + tifExt)) return _setFileName(path, 1, tifExt);
else return path + tifExt;
}
private static string _setFileName(string path, int ctr, string tifExt)
{
// Test the proposed altered filename. It it exists, move to the next iteration
if(System.IO.File.Exists(path + '(' + ctr.ToString() + ')' + tifExt)) return _setFileName(path, ++ctr, tifExt);
else return path + '(' + ctr.ToString() + ')' + tifExt;
}
This is a sample output of the generated switches (pulled from the output log):
Switches: -empty -r220 -dDownScaleFactor=1 -sCompression=lzw -dNumRenderingThreads=4 -c "30000000 setvmthreshold" -dNOGC -sDEVICE=tiffscaled24 -sOutputFile=\\[servername]\amb_ops_scanning$\Test.tiff \\[servername]\amb_ops_scanning$\Test.pdf
Settings are read in an XML file and stored in a class, GSVals. The class also handles writing to the System log for output, or to a text file in the normal Program version. GSSTDIO is a class for handling GS input and output, which just redirects all the output to the same logs as GSVals. The only code changes between the Program version and the Service version is the Service handling code, and the output is changed from a text file to the system logs. Nothing about the Ghostscript processing was changed.
This is being compiled as x86 for portability, but is being run on x64. GS 9.15 is installed, both x86 and x64 versions. GS.NET is version 4.0.30319 installed via NuGet into VS 2012. ILMerge 2.13.0307 is being used to package the GS.NET dll into the exe, also for portability. None of these things changed between the normal EXE and the Windows Service versions, and as I said the normal EXE works without any issues.
I got it working by using CreateProcessAsUser() from advapi32.dll, using code from this article.
I also had to restructure the order of the switches:
switches.Add("-c 30000000 setvmthreshold -f\"" + file + "\"")
The original source I'd used for speeding up the conversion left out the '-f' part, and the fact that the -f was the tag marking the file. I don't know why this worked in GS.NET, but with normal gswin32c.exe I got an error saying that it was an invalid file, until I set the switch this way.
Oddly, the processes this method creates are still Session 0, but it actually works. I'll keep tinkering, but for now it's working.

Make a custom file extension in C# (Windows 7)

I am trying to make a file extension associated to my application like make any file with .ztr work directly with my app when user double clicks that file.
I am using VS2012 , C# , Windows 7
I did simulate this example here.
Sure with some modification like fix Import Dll put also failed.
public static void Register (string Ext,string Program,string Ico)
{
string prog = Path.GetFileName(Program);
RegistryKey file = Registry.CurrentUser.CreateSubKey("Software\\Classes\\"+Ext);//.osa
RegistryKey App = Registry.CurrentUser.CreateSubKey("Software\\Classes\\Applications\\" + prog);//osama.exe
RegistryKey Link = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + Ext);//.osa
file.CreateSubKey("DefultIcon").SetValue("", Ico);
file.CreateSubKey("PerceivedType").SetValue("","Text");
App.CreateSubKey("shell\\open\\command").SetValue("", "\"" + Application.ExecutablePath + "\"%1");
App.CreateSubKey("shell\\edit\\command").SetValue("", "\"" + Application.ExecutablePath + "\"%1");
App.CreateSubKey("DefultIcon").SetValue("", Ico);
//There is Change here you
Link.CreateSubKey("UserChoice").SetValue("Progid", Program);
Invoke.SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);
}

Changing a programs process name in task manager?

Okay so I've been looking around and I can't find an answer anywhere.
What I want my program to do is every time I run it, the name that shows up in the task manager is randomized.
There is a program called 'Liberation' that when you run it, it will change the process name to some random characters like AeB4B3wf52.tmp or something. I'm not sure what it is coded in though, so that might be the issue.
Is this possible in C#?
Edit:
I made a sloppy work around, I created a separate program that will check if there is a file named 'pb.dat', it will copy it to the temp folder, rename it to a 'randomchars.tmp' and run it.
Code if anyone was interested:
private void Form1_Load(object sender, EventArgs e)
{
try
{
if (!Directory.Exists(Environment.CurrentDirectory + #"\temp")) // Create a temp directory.
Directory.CreateDirectory(Environment.CurrentDirectory + #"\temp");
DirectoryInfo di = new DirectoryInfo(Environment.CurrentDirectory + #"\temp");
foreach (FileInfo f in di.GetFiles()) // Cleaning old .tmp files
{
if (f.Name.EndsWith(".tmp"))
f.Delete();
}
string charList = "abcdefghijklmnopqrstuvwxyz1234567890";
char[] trueList = charList.ToCharArray();
string newProcName = "";
for (int i = 0; i < 8; i++) // Build the random name
newProcName += trueList[r.Next(0, charList.Length)];
newProcName += ".tmp";
if (File.Exists(Environment.CurrentDirectory + #"\pb.dat")) // Just renaming and running.
{
File.Copy(Environment.CurrentDirectory + #"\pb.dat", Environment.CurrentDirectory + #"\temp\" + newProcName);
ProcessStartInfo p = new ProcessStartInfo();
p.FileName = Environment.CurrentDirectory + #"\temp\" + newProcName;
p.UseShellExecute = false;
Process.Start(p);
}
}
catch (Exception ex)
{
MessageBox.Show("I caught an exception! This is a bad thing...\n\n" + ex.ToString(), "Exception caught!");
}
Environment.Exit(-1); // Close this program anyway.
}
The process name in the task manager bases on the executable name without the extension, which you can not change while it is running.
Read the documentation:
The ProcessName property holds an executable file name, such as
Outlook, that does not include the .exe extension or the path. It is
helpful for getting and manipulating all the processes that are
associated with the same executable file.
in visual studio go to Project - Properties - Application - Assembly information and change Title
I would implement a host application to do this that simply runs and monitors a sub process (other executable). You may rename a file as such:
System.IO.File.Move("oldfilename", "newfilename");
and start the process like this:
Process.Start("newfilename");
This would mean that instead of one process you would have two, but the owner process only needs to be alive under startup - in order to change the name.

Categories

Resources